La Integración continua: Netscape, la NASA, XP y dos mayordomos

En el artículo “La Integración Continua reduce el riesgo en proyectos software” comentábamos un poco el contenido del artículo de Martin Fowler que sacó en el 2005 sobre este mismo tema. En este artículo Fowler explicaba que la CI tenía un beneficio directo en los proyectos software reduciendo el riesgo, y  tuvo el efecto  añadido de  ayudar a que se difundiera con aún más fuerza.  Haciendo un guiño nostálgico a un anuncio del 2001 que decía “Si no sabes programar no sabes informática”, hoy en día “si no practicas la integración continua, no desarrollas software”. Volviéndome a ponerme nostálgico, ya lo decían en un anuncio de los 80: “la informática es mucho más que unas palabras”. Porque desarrollar software es mucho más que sentarse durante horas a escribir líneas de código.

programador3

Los que conozcan Extreme programming me dirán, “integración continua es una de las prácticas de XP”. Sí que lo es, es una de las 12 prácticas de XP, pero ¿cómo fue su evolución? y ¿a quién se le ocurrió por primera vez que debían hacerse integraciones automáticas lo más a menudo posible para reducir el riesgo en los proyectos? ¿Un día se levantó Kent Beck de la cama y dijo: “¡¡¡Eureka!!!”? y uno de los doce mandamientos será: integración continua. Nada más lejos de la realidad.

Os Dez Mandamentos 1

La CI fue propuesta y nombrada por primera vez en 1991 por Grady Booch en su método (Método Booch). En este caso Booch no hablaba en ningún caso de integrar varias veces al día. Grady Booch es conocido por desarrollar UML junto con James Rumbaugh. En 1991/94 desarrolló el método Booch. Se trataba de una técnica usada en ingeniería software para el diseño de objetos (predecesor de UML y RUP). Este método hablaba de uso de objetos, métricas, QA, patrones de diseño, formalismo, madurez de procesos y una notación robusta. Habla de sacar releases de arquitectura hasta llegar al sistema final (evolutivos)…si, es el precursor de RUP también, evidentemente.

image-83472-full

En los años 90 del siglo XX se producían dos temas importantes para el surgimiento de la integración continua. Uno fue que contrataron a Kent Beck (uno de los creadores de XP) en Chrysler con el objetivo de llevar un proyecto (El C3) de gestión de nominas, en el cual los requisitos eran un gran problema (¡¡¡no me lo esperaba!!!…). Parece ser que el sistema legacy de nóminas era bastante infumable (más de lo habitual supongo), se trataban de varias aplicaciones, cada uno de su padre y de su madre, que hacían lo mismo en algunos casos pero de forma diferente y donde los requisitos, como no, brillaban por su ausencia. El primer año que sacaron la primera release fue muy duro. Tan duro,  que  cliente, punto de contacto de Chrysler con el proyecto, tuvo que pedir la baja por estrés.

liberar-estress

Por otro lado, mientras se cocía la historia de Chrysler y XP, ocurre una historia paralela. Los ingenieros de calidad de Netscape, tuvieron una gran ocurrencia. Estos llegaron a la conclusión de que sería bueno poder realizar construcciones del código automáticamente de forma periódica. Tenían bastantes problemas con CVS (que acaba de surgir en los 90), ya que cada vez que iban a sacar una release, el código no compilaba correctamente: “en mi máquina funciona” decían los desarrolladores.

fz1t19.jpg

Se pusieron manos a la obra y crearon una herramienta muy sencilla llamada Tinderbox que les permitía realizar una construcción diaria de su software de forma que sabían en el mismo día si había habido un problema con la construcción del mismo (la build). En poco menos de un año, se dieron cuenta que bajando la cadencia de los builds, eran capaces de saber cuál había sido el problema de integración que había roto la build (a menos tiempo, menos commits realizados y más fácil detectar el problema de fallo). Progresivamente bajaron la cadencia hasta  realizar builds automáticos cada hora. Cuando en 1998 el código de Netscape es liberado, también es difundida su forma de trabajo a la comunidad de open-source. De esta manera la construcción frecuente de tu código de forma automática pronto se convirtió en una buena práctica en el mundillo del desarrollo software.

best-practices.jpg

XP lleva las mejores prácticas a niveles extremos. Por ejemplo la práctica de hacer test antes de desarrollar fue usada por la NASA en el programa Mercury Space por primera vez para tarjetas perforadas en 1960. XP la llevo al extremo con TDD. Aunque Kent beck no se considera a sí mismo el creador de Test Driven Development, fue el que implemento SUnit, un framework de tests unitarios para Smalltalk que fueron las bases de la familia xUnit (conjunto de frameworks basados en sus premisas como nUnit, phpUnit, junit, MsUnit, etc). Este framework se pensó para realizar TDD basándose en ideas de Gerard Weinberg y Leeds, Herbert D. en su libro (Computer Programming Fundamentals – 1960). Sí, he de afirmar que es curioso que en la portada original Weingberg no aparezca. Pero eso es otra historia.

51+GmuMoPYL._SX331_BO1,204,203,200_

Otra de las prácticas que se lleva al extremo es la integración continua. Kent Beck tomó la idea de Booch, las nuevas buenas prácticas de los build automáticos con las ideas de los servidores de builds automáticos emergentes y la inclusión del framework de test automáticos que había creado para dar forma a una de las prácticas de XP: Si aquellos tipos de Netscape podrían hacer construcciones del código cada hora, ¿por qué no íbamos a poder hacerlos en cada commit y además pasar automáticamente baterías de test automáticamente con sUnit? En 1999 Kent beck publica el primer libro sobre XP donde incluye el concepto como una de sus 12 prácticas.

circles.jpg

La integración continua ha ido evolucionando a medida de que han ido apareciendo nuevas tecnologías y herramientas. Si tenemos que pensar en cual fue la primera herramienta construida para este propósito, podemos pensar que fue Cruise Control que surgió en el 2001 como servidor de builds extensible. Esta herramienta estaba pensada para realizar builds automáticos usando Ant o Maven. Funcionaba (y funciona) a través de plugins que extendían su funcionalidad. Se trata de una herramienta gratuita y open-source.  Existe una herramienta para .NET similar denominada Cruisecontrol.NET que aparece en el 2003 con su versión 0.3.1 pero no es hasta 2005 que aparece la primera versión 1.0 estable. Es decir, que la integración continua basada en herramientas específicas (no el concepto como tal), tampoco es tan lejano. Fue cuando se estrenó “Batman begins”.

Batman-Begins-batman-555782_1024_768.jpg

Hudson es otra herramienta de integración continua escrita en Java que se ejecuta en un Apache Tomcat o en el servidor de aplicaciones GlassFish. Trabaja con CVS, Svn, Git y clearcase, y puede ejecutar Apache Ant y Maven así como procesos Windows. Hudson surgió en 2008 y se convirtió en una alternativa a Cruise control y otros servidores de builds de código abierto.  El desarrollador principal de Hudson fue Kohsuke Kawaguchi que actualmente es empleado de Sun Microsystems. Si dejas a un montón de desarrolladores software el código de una herramienta como esta, pasa lo que pasa: crean una comunidad y la llevan “hasta el infinito y más allá”.

kohsuke.jpg

Cuando más adelante Oracle compró Sun, este declaró que quería registrar el nombre de Hudson y desarrollar una versión comercial. Esto enfadó mucho a la comunidad de desarrollo de Hudson, la cual decidió, junto con Kawaguchi hacer un fork del código de Hudson y llamarlo Jenkins en 2011 (ambos son nombres típicos de mayordomos). Al final Oracle se da por vencido y en 2012 dona Hudson a la fundación Eclipse. En 2013 llevan muchos commits de Jenkins a Hudson. Lo que decía yo… “hasta el infinito y más allá”.

jenkins vs Hudson java

El caso es que los conceptos han cambiado poco desde final del siglo XX, ya que siguen siendo prácticamente los mismos. Si han aparecido nuevos, es porque han aparecido herramientas que ahora lo permiten y anteriormente no, o no con la misma facilidad. De la integración continúa se pasa a la entrega continua y de ahí al despliegue automático en producción. Hoy en día existen muchas herramientas y plugins desarrollados que están trayendo nuevos conceptos y capacidades de automatización, o quizá ya no tan nuevos en el momento de publicación de este post. Algunas organizaciones, hoy en día, son lo suficientemente maduras para automatizar tanto el desarrollo software y las pruebas, que con cada commit despliegan directamente en los servidores de producción  con seguridad (pocas son) (continuous deployment). Pero eso amigos, eso, es otra historia.

continuos deployment vs delivery.jpg

PDFicono EXTENDIDO

REFERENCIAS:

[1] Continuous Integration – Martin Fowler
[2] Continuous delivery  – Martin Fowler
[3] Extreme Programing Explanined:Embrace change – Kent Beck

El por qué de que algunos proyectos fracasen VI: RUP y un caso de éxito

Uno de los puntos positivos de Rational Unified Process (RUP) es que partimos de la idea de que “los requisitos van a cambiar”. Reconocer esto tiene gran mérito ya que en la cultura de desarrollo software  predominante en su nacimiento (años 90) lo que se hacía era negociar los requisitos con cliente y rezar compulsivamente para que no cambiasen. Creo que muchos jefes de proyecto se debían y deben sentir muchas veces como Jeff Murray en el día de la Marmota.

Atrapado en el tiempo

RUP dice que puesto que ya sabemos que los requisitos pueden cambiar, vamos a hacer una aproximación en 4 fases: Iniciación, Elaboración, Construcción y transición. Dentro de cada fase se producen una serie de hitos en los cuales debemos sacar un entregable, es decir, una baseline de mis requisitos, código  o lo que tengamos que entregar en esa fase. La idea es obtener feedback (interno) de lo que hemos realizado. Esos hitos por fase son de 4-6 semanas. En cada hito vamos a tratar de ir refinando la solución del problema, mejorando iterativamente nuestro conocimiento y necesidades del negocio a través del feedback aportado normalmente por los ingenieros de V&V(lo llaman feedback interno en RUP)…aunque la verdad es que nada impide que se tenga feedback externo de cliente, aunque esto no es obligatorio. Se trata en de un modelo de desarrollo en espiral de convergencia a la mejor solución  a través de inspección de sus artefactos (casos de uso, en general otros diagramas UML y distintas vistas de arquitectura) y adaptación en cada iteración.

rup_fundamentals_slide05

Cuando apliqué RUP años atrás en uno de los  proyectos en los que trabajé, cada fase era básicamente un proyecto completo y distinto donde cada hito final era de cobro, pudiendo haber sobre todo en la fase de construcción un par de hitos de cobro intermedios. No debe confundirse estas fases con las típicas de inicialización, planificación, ejecución y cierre de proyecto, ya que estas fases son exclusivamente para converger a la solución de una manera óptima en cuanto a recursos, minimización de coste y riesgo donde el alcance varía a lo largo de estas iteraciones. Supongo que como todo podría aplicarse de otros modos de acuerdo a lo que se estipule en el contrato con cliente, al fin y al cabo RUP es un marco de trabajo y no una metodología como tal. En las cuatro fases nosotros realizamos las siguientes actividades:

  • Iniciación: Aquí no participé, pero fue la toma de contacto con cliente. Donde se obtuvieron os requisitos de muy alto nivel y se estableció un poco como iban a realizarse los trabajos, es decir, preparamos un poco el terreno. De acuerdo a RUP, en esta fase se modela a alto nivel el negocio, el entorno donde va a ser desarrollado y desplegado, como se va a hacer la gestión de configuración y poco más.

como-redactar-una-carta-comercial-de-oferta-de-productos

  • Elaboración: Durante la fase de elaboración se le pregunta a cliente y se establece una idea de que es lo que vamos a desarrollar partiendo del output obtenido en la fase anterior. En nuestro caso hicimos un prototipo para apoyar los casos de uso y  obtuvimos los requisitos en varias entregas con cliente donde obtuvimos un feedback muy valioso. Tuvimos suerte de que en este caso el producto estaba basado en otro producto que habíamos desarrollado años antes donde además del software se documentaron requisitos, casos de usos y se trabajó en la gestión de la configuración, división en componentes, etc. La entrega fueron unos cuantos CDs con mucha documentación + un prototipo ejecutable.

Payme

  • Construcción: Después de pelearnos unos meses llevando el prototipo y algunos videos de su funcionamiento a algunas ferias, esperando que nos dieran el visto bueno para desarrollar el sistema que habíamos “elaborado”. Nos dieron el OK y formamos un equipo de unas 10 personas. Recuerdo que trabajamos sobre un software con un Core muy desarrollado y bien definido, por lo que a final de cuentas sólo hubo que desarrollar nuevas funcionalidades, específicas del problema, documentar mediante UML, pruebas, trazabilidad, etc.
    Se hicieron varias entregas intermedias y en alguna hubo algún susto que otro, pero al final se entregó todo con la calidad esperada y cubriendo todos los requisitos. La facilidad para lograr hitos fue sin duda de un equipo de desarrollo altamente cualificado donde no había diferenciación entre programadores y analistas, ya que se trataba de un equipo multifuncional donde todos éramos simplemente ingenieros de proyecto. Había alguno que estaba especializado en algún área de negocio o en alguna parte técnica como verificación y validación, pero a final de cuentas, no había más título que el de ingeniero de proyecto.

steve-ballmer-developers-bandwidthblog-664x534

  • Transición: Aquí ya no estuve. Se despliega el producto, se corrigen algunos errores. Se trata de la típica fase de mantenimiento donde se afinan un poco más los requisitos con el sistema ya funcionando, pero su objetivo es obtener feedback de cliente, no únicamente su mantenimiento. Aún se pueden cambiar algunas funcionalidades, aunque es esperado que tras el trabajo realizado en fases anteriores esto ocurra excepcionalmente. Aquí es donde tiene más peso el feedback de cliente según la teoría de RUP.

Rup_espanol

Mi experiencia fue buena y creo que la del equipo también. Sin embargo no creo que sea un buen ejemplo de aplicación de RUP a un proyecto complejo, si no de aplicación de RUP a un proyecto en el cual teníamos poca incertidumbre y por tanto muy poco riesgo, el cual estaba controlado. El feedback interno obtenido por el ingeniero de V&V estaba bien, pero al final lo que contaba era el feedback de cliente. Aunque como decía antes, no es un buen ejemplo de aplicación pura de RUP, quería sacar este ejemplo porque fue un caso de éxito que en teoría podría ser contado a nivel estadístico como un caso de éxito que utilizaba metodologías tradicionales (aunque tenga el ciclo de vida en espiral o incremental, no considero a RUP muy diferente de V-Model. Echar un vistazo a “Dual V Model”) .

developers

Hay que decir que a pesar de todo esto, hubo pequeños picos de trabajo  y algún que otro problema de entrega (errores humanos sin importancia). Sin embargo, no era un problema demasiado complejo. Tampoco digo que fuera fácil, pero conocíamos el camino, sólo teníamos que recorrerlo . Se trataba de un proyecto de riesgo controlado y no éramos más de 10 personas en el equipo en total, con lo que la capa de gestión estaba formada básicamente por un jefe de proyecto. Había un director técnico, pero la forma de trabajo era totalmente plana, se trataba de un equipo autoorganizado, senior y con varios años trabajando juntos.

equipo-aPara la documentación usamos Rational Rose y conseguimos cada mes alinear el diseño UML de manera semi-automática donde sólo nos consumía 1 persona 2 o 3 días. Esto no quiere decir que no hiciéramos diseños previos, si no que la documentación la hacíamos a posteriori apoyándonos de herramientas automáticas. Al fin y al cabo, eran entregables pedidos por cliente. Los casos de uso no fueron más que documentación que fue totalmente inútil tanto para ellos como para nosotros en la fase de construcción. Es cierto que en la fase de elaboración si tuvieron cierta utilidad para comunicarnos con el cliente, aunque el prototipo funcional tuvo mucho más peso. La documentación de arquitectura la hacíamos a posteriori y le encontré varias utilidades que no tienen nada que ver con los objetivos que plantea RUP (la cual se debería documentar a priori). Estas fueron:

  • Se detectaban desviaciones de la arquitectura de forma temprana en cada actualización. A veces pasa cuando hay falta de alineación, por lo que ayudó a mantener esa alineación entre los componentes del equipo en cuanto al “como hacer”. No hacíamos reuniones rápidas diarias para alinearnos y creo que uno de los miembros no estaba en la misma sala, era un fallo que teníamos.
  • El cliente prefería ver el sistema funcionando y relacionarlo con los diagramas a nivel de paquetes UML, que ver un montón de casos de uso que ya no le decían nada. Iban viendo las relaciones entre paquetes de alto nivel y podían navegar entre ellos gracias a la herramienta Rational Rose. Esta transparencia, dio mucha confianza al cliente en cuanto a la calidad interna del software y esto nos facilitó muchísimo las entregas debido a su tolerancia ante la aparición de errores.
  • Esta documentación era muy útil para que los nuevos integrantes del proyecto se “metieran en harina” sin tener que “bucear en el código”.

vueltatortilla

Realmente, hicimos algo de trampa porque, sin querer cubrimos muchos de los principios ágiles, los cuales desconocíamos por completo su existencia:

  • La jerarquía de proyecto era prácticamente plana y el equipo al completo se podría decir que era totalmente autoorganizado.
  • No teníamos procesos que seguir, más que los estrictamente necesarios para lograr nuestros objetivos.
  • Dimos prioridad al código ejecutable y funcionando frente a la documentación exhaustiva.
  • Dimos prioridad al conocimiento tácito, es decir, aquél que forma parte del equipo y del cliente de una manera informal, frente a la documentación de casos de uso.
  • Hablábamos con el cliente, pero de una manera informal y siempre con una versión del producto delante. Había requisitos, pero nos ayudábamos del cliente para entenderlos.
  • Dimos prioridad al uso de herramientas automáticas frente a la documentación previa y exhaustiva.
  • Hubo cambios en algunas partes. No fueron muy drásticos, pero los abrazamos sin ningún tipo de problema.

El éxito de este proyecto fue utilizar el sentido común de unos grandes profesionales que llevaban más de 20 años desarrollando este tipo de sistemas. No eran agilistas, pero sin lugar a duda eran ágiles.

Sinquerer

Actualmente RUP ha evolucionado a AUP (Agile Unified Process) donde han seguido manteniendo sus 4 fases pero han orientado el desarrollo de producto a XP. Básicamente quitaron todo parecido que tuviera con V-Model, casos de usos, UML… porque al final, creo que casi ningún proyecto de éxito lo seguía a rajatabla. Quizá después de todo acertamos.

Agile_Methodologies_lightweightfuller_approaches

En la teoría, nos enseñan a definir el sistema completo antes de comenzar el desarrollo mediante casos de uso, diseños arquitectónicos documentados con UML y al final cuando está todo pensado, debemos pasar a la acción escribiendo líneas de código como si ladrillos fuesen, tratando a los desarrolladores como meros interpretadores de esos planos tan detallados e infalibles.  En la realidad, se escribe una documentación que nunca llega a tiempo, o si llega, con un detalle parcial que proporciona a los desarrolladores una idea vaga de cómo se quiere el sistema. Si han tenido suerte de que el analista orgánico ha trabajado codo con codo con desarrollo, tendrán que realizar ajustes y seguramente el trabajo de la documentación haya servido como una primera aproximación al problema y tenga cierto valor. Pero si en el proyecto existe una clara separación entre analista orgánico y desarrollador, es muy probable que el trabajo del mismo haya sido una pérdida de tiempo y dinero razonable para proyecto.

sin dinero en el bolsillo

El diseño, la documentación, lo que hace el sistema está ahí, en el código. El problema es que es un lenguaje que hay que conocer. Además si no cuidamos el código, se trata de una documentación “infumable” y por tanto como documentación es poco útil. Imaginad una novela donde cambiamos palabras por etiquetas sin ningún sentido semántico, la indentación y las fuentes no son homogéneas, existen párrafos que están obsoletos y no deberías leer y la estructura es caótica. Dan ganas de leerla ¿eh?

repetir codigo

Lógicamente, no la leerías y pedirías que te escribieran un “guía burros” para poder entenderla. El código es la novela de tu producto. Hoy en día existen técnicas de diseño basadas exclusivamente en código (específicamente en pruebas automáticas): TDD y BDD. Además el tener pruebas unitarias con una buena cobertura, también nos proporciona cierta garantía de que si escribo un párrafo de mi libro tendrá coherencia con el resto de la novela. También existen herramientas que me detectan falta de homogeneidad, párrafos repetidos, etc. Realmente ¿crees necesario, escribir un mapa de tu libro para poder leerlo y entenderlo? Puedo entender que se escriba documentación porque el proyecto lo requiera y sea un entregable, pero ¿Quién crees que va leer cada clase y atributo en “un tocho” de 10000 páginas?

Libraco

He dicho anteriormente que hicimos trampa usando RUP, quizá haya exagerado en un momento de pasión. Simplemente no seguimos RUP. La documentación la tratamos como un entregable más que debía cumplir una serie de estándares y la obtuvimos automáticamente con el beneplácito del propio cliente. Le encontramos un valor a esos entregables que eran dar transparencia a cliente acerca de nuestra arquitectura y revisiones semi-automáticas de la evolución del código, el cual estaba debidamente comentado y cuidado. Fuimos ágiles, eficientes y utilizamos la documentación en nuestro favor de camino hacia la victoria. En resumen fuimos Culpables.

culpable

PDFicono EXTENDIDO

REFERENCIAS:

[1] RUP en wikipedia
[2] Rational Unified Process – Best Practices for software development teams
[3] Managing the development of large systems
[4] Manifiesto Ágil