Entrega continua principio #1: 3 repositorios por aplicación

Creo que en la actualidad está ya claro que debemos tener un repositorio para versionar el código de nuestra aplicación. Algunos también versionan  en ese mismo repositorio la configuración de la aplicación. Para algunos casos esto puede ser suficiente, pero en contextos de entrega continua no me parece apropiado.

En primer lugar la configuración y el código tienen un tasa de cambio distinta, el código cambia mucho más rápido que la configuración. Al mismo tiempo la configuración suele variar dependiendo del ambiente en que se despliegue la aplicación. Finalmente, dependendiendo de la organización puede que la configuración del ambiente productivo sea reservada y sólo algunos miembros de la organización puedan accederla. La propuesta entonces es tener un repositorio exclusivo para almacenar la configuración de la aplicación. En particular, yo suelo crear en ese repositorio un branch por cada ambiente. Adicionalmente para facilitar el trabajo del equipo de desarrollo suelo almacenar junto al código, la configuración del ambiente desarrollo.

Finalmente necesitamos un tercer repositorio para almacenar los scripts de despliegue. La idea de poner estos scripts en un repositorio exclusivo tiene que ver otra vez con su tasa de cambio esporádica y también con el hecho de que es posible que estos scripts sean creados/manipulados por personas distintas a las que escriben el código, típicamente sysadmins.

En algunos casos particulares puede que sea necesario un cuarto repositorio, por ejemplo si uno quisiera generar modulos Puppet para automatizar el provisioning de la aplicación.

Pensándolo bien, creo que el título del artículo no es preciso, el principio es versionar todo,  el hecho de usar 3 repositorios es más bien una forma de implementarlo, que puede no aplicar siempre.

Emoción: avance de ingeniería en el CBC

Hoy desayuné con una noticia que me emocionó: la última inscripción del Ciclo Básico Común (curso de ingreso) de Universidad de Buenos Aires indica que habrá más ingresantes 2015 en carreras de ingeniería que en carreras de ciencias sociales, una situación casi inédita.

Claro está que la UBA no es la única casa de altos estudios en el país, pero sin duda es una institución de referencia y es posible que esta tendencia sea un reflejo general de la sociedad. Parece que los esfuerzos de promoción de las carreras técnicas hechos por las diversas organizaciones relacionadas a la industria han dado frutos.

La noticia me llegó por medio de este artículo del diario Clarín, lo que me resulta curioso es que la información provista en el mismo artículo indica que el título de la nota es incorrecto, ¡ja!

 

DevOps, una nueva idea no tan nueva

El término DevOps fue acuñado por Patrick Debois quien allá por 2009 organizó una serie de conferencias bajo el título DevOpsDays. El objetivo de estos eventos era incentivar una visión holística de la entrega de software derribando las barreras de la visión tradicional que separaban el desarrollo del software de su operación. A pesar que el término fue acuñando hace ya más de 5 años, creo que fue en los último 3 que tuvo un salto de popularidad potenciado entre otras cosas por herramientas como Chef, Puppet, Docker, y Vagrant y por prácticas como Infraestructura as Code, Test-Driven Infraestructure y Self-Service Provisioning.

Si bien la idea de DevOps aún hoy puede parecer novedosa para algunas organizaciones, para algunas otras siempre ha sido moneda corriente. Hablando más en concreto creo que DevOps suele resultar novedoso o incluso revolucionario para grandes organizaciones de tipo «tradicional» como bancos, telcos e incluso organismos gubernamentales. Al mismo tiempo me parece que es moneda común en organizaciones surgidas en la era de internet como .coms y startups.

Personalmente desde 2012 soy parte del equipo de Tipit, una empresa dedicada a brindar soluciones web y que adicionalmente cuenta con un conjunto de aplicaciones ofrecidas como servicio.
Tipit es una empresa chica pero que tiene bien claro que sus clientes pagan por el valor aportado al negocio y que en este contexto se traduce en software funcionando en manos del usuario. Dicho de otra forma, en términos de valor no existe la diferencia entre desarrollo y operación, la cuestión es blanco o negro: ¿está la funcionalidad lista para ser usada en un ambiente productivo o no?

Al igual que la mayoría de mis colegas en Tipit, yo trabajo tanto en tareas de desarrollo como en tareas de operaciones. Esto no implica que todos hagamos todo, todo el tiempo, sino que cada uno tiene un rol en cada proyecto pero más allá de ese rol particular que cada uno desempeña, todos somos responsables de que el software este disponible en manos del usuario cuando este lo necesite. Entre otras cosas esto requiere no dejar las cuestiones de operaciones para la última milla, sino tenerlas presentes en forma temprana, ya desde el momento del diseño de cada funcionalidad.

DevOps ¿es un realmente un rol?

Érase una época en que las organizaciones operaban como silos, con un área de desarrollo por un lado y una área de operaciones/infraestructura por otro. Estas dos áreas no sólo hablaban poco entre ellas sino que incluso en algunos casos guardaban cierto rencor entre sí. Programadores y Sysadmins enfrentados mutuamente como Vampiros y Hombres-Lobo, porque obviamente más allá de las diferencias que ellos percibían, para todo el resto de la organización eran más o menos lo mismo: gente rara del área de TI.

La adopción de métodos ágiles en las áreas de desarrollo ayudó que los desarrolladores se acercarán más al negocio y al resto de las áreas de la organización. Agile fue algo así como la sustancia que permite a Blade exponerse la luz solar y vivir más como humano que como Vampiro. Pero en la gran mayoría de los casos la fórmula de Blade no tuvo efecto en los Hombres-Lobo, quienes quedaron aún más aislados del resto de la organización.

En varias organziaciones la cuestión se puso aún más interesante cuando los equipos usando agile pretendieron salir a producción en forma frecuente. Tradicionalmente los pasajes a producción ocurrian cada un par de meses y era entonces cuando la relación entre Programadores y Sysadmins alcanzaba los picos máximos de tensión. Ahora los programadores agile pretendián ir a producción cada 2 semanas y encima contaban con el apoyo (y el entusiasmo) de la gente de negocio. Para los Hombres-Lobo esto era demasiado: ahora los Vampiros tenian el apoyo de Blade y los humanos.

Y como suele ocurrir en todas las guerras, el mayor perjudicado con todo esto era el pueblo (que en este caso era la organización). Fue en este contexto donde surgió el la iniciativa de DevOps como una propuesta para acercar a los programadores y los sysadmins y lograr que cada uno trabajé consciente de la existencia y responsabilidades del otro. Es aquí donde las implementaciones de DevOps divergen en dos estrategias.

Por un lado algunas organzaciones generan un nuevo rol al que denominan DevOp con el objetivo de mediar entre programadores y sysadmins. Si bien creo que inicialmente esta estrategia puede ayudar mejorar la situación, creo que no es más que un remiendo. Estos DevOps cuentan generalmente con habilidades técnicas mixtas, o sea son una especie de Hombre-Lobo-Vampiro y en última instancia son un bicho raro más a los ojos del resto de la organización.

Por otro lado, algunas otras organizaciones ven DevOps como una transformación en la organización mediante la cual programadores y sysadmins dejan de lado su egoísmo para trabajar colaborativamente unos con otros (al mejor estilo Saga Crepúsculo parte 3) de cara a lograr una feliz convivencia con los humanos y el resto de la organización.

Personalmente me inclino por esta segunda estrategia de DevOps aunque reconozco que en ciertos casos la primera estrategia puede resultar beneficiosa siempre y cuando quienes ocupen el rol de DevOps cuenten con habilidades blandas (gestión, facilitación, etc) más allá de las habilidades técnicas.

Nobleza obliga: la analogía con Vampiros y Hombres-Lobo está tomada de un artículo publicado por Jeff Atwood en su blog CodingHorror.com.

La calidad no es inyectable, parte 3

Finalmente hoy sí voy a referirme a los métodos ágiles. Tal como lo contamos en el capítulo 18 de Construcción de Software, una mirada ágil, el enfoque de los métodos ágiles es construir con calidad día a día. Esto no es muy novedoso pues bajado a concreto (y en forma simplificada) lo que hacen los métodos ágiles es tomar algunas de las prácticas existentes en el desarrollo de software y llevarlas un paso más allá:

  • Si las revisiones de código agregan valor, entonces directamente escribamos el código de dos (pair programming)
  • Si el feedback del usuario es valioso, entonces trabajemos más cerca de él (on-site customer) y busquemos su validación en forma periódica (iteration review)
  • Si la integración periódica nos facilita el desarrollo, entonces integremos todo el tiempo (integración continua)
  • Si el testing y la aceptación son actividades importantes para la calidad, no las dejemos para el final, integremoslas al ciclo de desarrollo de forma temprana (Definition of Done, BDD)
  • Si creemos que podemos mejorar en la forma que trabajamos, incorporemos entonces un mecanismo explícito para la mejora continua (retrospectivas)

Y sin duda podríamos seguir enumerando casos de prácticas de desarrollo que los métodos ágiles han potenciado.

Adicionalmente hay algunas otras cuestiones, que personalmente no logro identificar con prácticas pre-existentes pero que sin duda son clave en los métodos ágiles y entre las cuales destaco:

La construcción de software es una actividad intelectual llevada a cabo por personas. Si bien puede parecer una cuestión obvia resulta que curiosamente muchos enfoques de construcción de software precedentes parecen haberla pasado por alto.

Fin.

Nuevo proyecto de CI / CD

Hacía fines de diciembre del año pasado me contactaron de una empresa para que los ayudara con una iniciativa de Integración Continua. Intercambiamos un par de mails, tuvimos una llamada telefónica de 20 minutos y acordamos una primera reunión.

Desde mi punto de vista la práctica de integración continua no es un fin en sí mismo sino que es una herramienta. Por ello, una de las primeras cosas que pregunté fue: ¿Cuál es su problema? ¿Qué esperan solucionar con esta práctica? La respuesta fue clara, había dos problemas principales: por un lado la calidad del producto y por otro el desperdicio de tiempo invertido en el despliegue de la aplicación a los distintos ambientes. Esto me permitió entender que la cuestión iba bastante más allá de la integración continua.

El desafió me pareció muy interesante, pues se trataba de una empresa grande, con equipos distribuidos geográficamente en distintos lugares de latinoamérica y cuyo negocio estaba centrado en la venta de soluciones de banca. La empresa contaba con un plataforma de productos que vendía a distintos clientes y cada venta implicaba una implementación/customización de los productos. De esta forma había equipos trabajando sobre los productos y en paralelo un equipo de implementación para cada cliente que compraba el producto.

En términos de administración de la configuración a primera vista la naturaleza del negocio llevaba a tener un trunk de producto con un branch por cada cliente. Fácil decirlo, no tan fácil de implementarlo sobre todo teniendo el código de todos los productos en un único repositorio CVS.

La plataforma tecnológica era Java, un clásico en sistemas de banca. Pero dado que la solución se vendía a distintos clientes la aplicación debía funcionar sobre distintos ecosistemas tanto a nivel base de datos, application server y service bus.

Un último condimento no menor es que gran parte del código venía arrastrándose desde hacía varios años y tenía dependencia con componentes open source ya sin soporte (por ejemplo Apache Hivemind). Adicionalmente también se estaban usando versiones viejas de algunas herramientas (por ejemplo java6  y maven2).

Cabe destacar que varias de este cuestiones no las sabia inicialmente, sino que las fui descubriendo una vez empecé a trabajar.

La situación era compleja y las expectativas del cliente eran muy grandes. Mi propuesta fue simple y concreta:

Busca un equipo que esté interesado en trabajar en esta iniciativa. Yo me siento y trabajo con el equipo codo a codo 1 mes para resolver los impedimentos que el equipo considere le impiden construir software de calidad.

Al cliente, le gustó la propuesta y la bola empezó a rodar.

Continuará…

Selección de herramientas de prueba (parte 2)

En la primera entrega de esta serie presenté una arquitectura de prueba de referencia. En esta entrega voy a instanciar esa arquitectura de referencia en Ruby.

Comenzado por las pruebas del programador (unitarias y de componentes), tendremos que nuestro objeto de prueba serán clases programadas en Ruby. Para hacer este tipo de pruebas una de las herramientas más populares es RSpec la cual nos daría una arquitectura de pruebas conformada por:

  • Lenguaje de especificación: Lenguaje de Dominio Específico provisto por RSpec
  • Intérprete: es el propio RSpec
  • Driver: dado que estamos testeando clases Ruby, que estamos haciendo pruebas unitarias y de componentes y que RSpec está hecho en Ruby no requerimos de ningún driver particular. En todo caso nuestro driver es el mismo Ruby
  • Librería de aserciones: es el mismo RSpec
  • Motor de ejecución: RSpec

Un detalle a tener presente es que este tipo de pruebas son pruebas que hace el programador para sí mismo, ya sea para guiar el desarrollo (si está haciendo TDD) o bien para garantizar que sus clases se comportan acorde a lo esperado. Este tipo de pruebas no suelen interesar al usuario, pues son de índole técnica y al mismo tiempo mucho más granulares que las funcionalidades pedidas por el usuario.

arquitectura_developer_tests_ruby

 

 

Pasando ahora a las pruebas de aceptación funcionales, si bien podríamos utilizar el mismo set de herramientas, la realidad es que esperamos que el usuario esté involucrado y por ello usaremos un set distinto de herramientas de cara tener un lenguaje de especificación más «amistoso» para el usuario. Al mismo tiempo el objeto de nuestras pruebas ya no son clases sino la aplicación como un todo:

  • Lenguaje de especificación: Gherkin
  • Intérprete: Cucumber
  • Driver: dependerá de la forma en que pretendamos comunicarnos con la aplicación. Suponiendo que nos comunicamos via HTTP, podríamos utilizar Capybara en conjunto con WebDriver de Selenium.
  • Librería de aserciones: RSpec
  • Motor de ejecución: Cucumber

arquitectura_user_tests_ruby

 

Libro de experiencias

Hace un tiempo que vengo dando vueltas a la idea de escribir un libro de experiencias de desarrollo de software. Seria una especie de compendio de casos de estudio cada uno de ellos escrito en primera persona. No es una idea novedosa, de hecho el año pasado gente de una univesidad de Colombia intentó hacer algo similar, pero hasta donde supe no prosperó.

La semana pasada mientras compraba mi pasaje para el Agile Open Camp tuve una idea para para concretar este libro: proponer una sesión en el open space para escribirlo. La idea seria aprovechar que estaremos 3 dias y dedicar un tiempo fijo cada día de cara a llegar el final de evento con una primera versión del libro. Puede parecer complejo pero en realidad no lo es, básicamente quienes tengan un caso para compartir, deberan sentarse y escribirlo, sin dar muchas vueltas la idea tener el caso contado aunque sea a grandes rasgos, luego se le podremos iterear para agregar detalles y correcciones. El último dia del evento tomamos todos los casos y generamos el libro utilizando la plataforma LeanPub. A partir de ahí, el manuscrito queda en un repositorio Git para que podemos ir puliendo los capítulos, ajutando estilo, agregando imágenes, etc, etc.

Al mismo tiempo, yo como promotor de la idea tomaré la responsabilidad de revisar y unificar estilos (acepto colaboración también para estos temas).

Más aún, podría ser interesante llevar al evento con algunos casos ya escritos y aprovechar alguna sesión del open space para trabajar en cuestiones de revisión y unificación de estilo. ¿Que tal si escribes tu caso durante el viaje? (salvo los patagónicos, el resto de los asistentes tendrá al menos 2 horas de viaje, tiempo más que suficiente para volcar la idea en un mail).

Imagino todos los casos siguiendo una misma estructura:

  • Título
  • Tags
  • Contexto
  • Desafío
  • Solución
  • Conclusión

Para tener una idea más concreta de mi idea de caso, pueden ver este que escribí el año pasado.

Para mi es clave es llegar el final del evento con una primera versión del libro, pues ya he participado en proyectos de escritura/traducción con varios involucrados y resulta verdaderamente complejo lograr compromiso y dedicación cuando uno tiene otras responsabilidades.

Bien, la invitación está hecha,  espero que contar con el apoyo suficiente para terminar el evento con la primera versión del libro.

 

La calidad no es inyectable, parte 2

Hablando sobre calidad no inyectable es inevitable recordar el aporte de Joseph Juran con su idea de Quality by Design. Esta idea hace referencia a que la calidad puede ser planificada y que muchos de los problemas de calidad se deben a la forma en que la calidad es planificada. En el post anterior comenté sobre el enfoque de planificar la calidad en una etapa tardía del proyecto, posterior a la finalización de la etapa de construcción. Quisiera ahora compartir otro enfoque más integral que planifica la calidad como actividades llevadas a cabo a lo largo de todo el proceso de construcción.

Y no, no voy a hablar de métodos ágiles, no todavía. Quiero referirme ahora a un enfoque duro y puro de ingeniería de software. No puedo dejar de asombrarme cuando escucho profesionales del software hablar como si antes de los métodos ágiles hubiera sido todo desorganización. No es cierto, entre la era de la desorganización y la aparición de los método ágiles ha habido muchas ideas, técnicas y prácticas muy valiosas, entre las que destaco:

  • Desarrollo iterativo e incremental
  • Revisiones de código
  • Arquitectura basada en componentes
  • Automatización de pruebas
  • Gestión de la configuración

Si bien estas prácticas estan descritas en diversos libros de ingeniería de software, personalmente me gusta el libro de Calidad en el desarrollo de Software de Guillermo Pantaleo, el cual está escrito en castellano, está enfocado específicamente en cuestiones de calidad, fue publicado en 2011 y esta escrito con la visión mixta de alguien con mucha experiencia académica e industrial como es el caso de Guillermo.

Continuará…

 

 

La calidad no es inyectable

No puedes construir un producto y luego inyectarle calidad, por una simple razón: la calidad no es inyectable.

Si quieres un producto de calidad, debes construirlo con calidad desde el vamos. Esto implica que la calidad de tu producto está directamente relacionada al proceso de construcción del mismo. Por ello tu proceso de construcción debe incluir actividades y prácticas de calidad. Y nada de esto es particular de la construcción de software.

Curiosa y contrariamente a esto, durante mucho tiempo muchas organizaciones de la industria del software han insistido (y algunas lo siguen haciendo)  en separar las actividades de construcción de las actividades de calidad, delegándolas incluso en distintos equipos que trabajan sobre el producto en distintos momentos, generalmente en forma secuencial. Un equipo de técnicos construye el producto y una vez terminado lo entrega al equipo de calidad, como si este pudiera inyectarle calidad, pero realidad ese equipo en el mejor de los casos solo mide la calidad del producto haciendo pruebas. Dependiendo del resultado de esas pruebas, el equipo de construcción vuelve a tomar el producto para «mejorar» su calidad. Esta dinámica de ida y vuelta se repite hasta que el producto alcanza el nivel de calidad deseado (o hasta que se acaba el presupuesto o hasta que se llega a una fecha límite).

¿Es posible generar un producto de calidad de esta forma ? Si, es posible. Pero no es la única forma y posiblemente tampoco sea la mejor para todos los casos. Entonces, ¿cómo seria una mejor forma de hacer esto? ja!, eso es tema del próximo post 😉