El placer de trabajar con quien uno gusta

Varios son los beneficios de trabajar de manera independiente, pero dudo que alguno sea más gratificante que el hecho de poder elegir con quien trabajar.

En este sentido ayer tuve  el gusto de compartir una mañana de trabajo con Pablito Tortorella (@pablitux). Pablo y yo estamos trabajando en un cliente, Pablo enfocado en cuestiones de adopción de Scrum y mejora organizacional y yo en cuestiones de integración continua y pruebas automatizadas. Si bien son temas distintos, tienen puntos de contacto y complementación. Ayer en particular estuvimos trabajando armando la infraestructura de prueba con un equipo que está físicamente distribuído.

Fue una mañana intensa, trabajamos todos juntos sentados frente a dos pantallas: una con el Hangout (teníamos miembros del equipo conectados en forma remota) y otra con el código del proyecto.

Logramos el objetivo que nos habíamos propuesto (tener una prueba corriendo sobre la nueva arquitectura), aprendimos, la pasamos bien y acordamos repetirlo la semana próxima.

¡Gracias Pablitux!

Integración continua, principio #3: el principio del tio Ben

Cuando el tío Ben está apunto de morir en los brazos de su sobrino Peter Parker (spiderman) le dice una frase que lo marcará para siempre:

Grandes poderes conllevan grandes responsabilidades

Amo esta frase, creo que aplica a todos los ámbitos de la vida y también al desarrollo de software. En este sentido Tobias Meyer en su libro People Scrum la utiliza para describir la situación de un equipo autoorganizado: el equipo tiene el poder de autoorganizarse y eso automáticamente aumenta su responsabilidad. Analicemos esta situación por el contrario: si a un equipo se le imponen compromisos ¿cuán responsable será ese equipo por esos compromisos impuestos?. Si en lugar de eso fuera el propio equipo el que asumiera los compromisos ¿no se sentiría ese equipo automáticamente más responsable por el cumplimiento de esos compromisos que el propio equipo eligió? Mi experiencia me ha demostrado que efectivamente es de esta forma, lo cual confirma la frase del tío Ben.

Llevando esto al contexto de integración continua creo que la frase puede incluso aplicarse a la inversa, grandes responsabilidades requieren grandes poderes. O sea, si se pretende que un equipo asuma la responsabilidad de mantener un build sano, debe entonces darse a ese equipo las herramientas (poderes) para poder tomar esa responsabilidad. En concreto ello implica, entre otras cosas, que el equipo debe tener acceso total al ambiente de integración continua. Sin excepción puedo decir que todas las implementaciones fallidas que he visto de esta práctica tenían en común que el equipo no tenía acceso completo al ambiente de integración continua.

Integración continua, principio #2: build everywhere

Particularmente la tarea de Build debe poder ejecutarse tanto en el servidor de integración continua como en la máquina del programador. Esto es fundamental para que en caso de falla del build, los programadores sean capaces de reproducir la falla en sus ambientes locales ejecutando la misma tarea que ejecutó el servidor.

Al mismo tiempo esto reduce la dependencia con el servidor de integración continua, ya que el mismo solo agrega un paso previo y uno posterior al build. En concreto:

  • El servidor de IC monitorea al repositorio de código y dispara nuevas ejecuciones en caso de detectar cambios
  • Una vez disparado el build y descargado el código fuente, el servidor de IC ejecutará la tarea de build que es justamente la que debe poder ejecutarse en la máquina de los programadores
  • Finalmente el paso adicional que ejecuta el servidor de IC es la notificación del resultado del build

Integración continua, principio #1: Independencia de IDE

Desde el punto de vista conceptual esta práctica está muy bien descripta en el artículo de Martin Fowler (#lecturaObligatoria), pero a la hora de intentar implementar la práctica, no suele alcanzar con la teoría. En este sentido un libro que me parece muy útil es Jenkins: The definitive guide de John Ferguson.

Luego de la lectura de los mencionados recursos y de haber recorrido un largo camino con esta práctica he identificado algunos principios fundamentales para la efectiva implementación de esta práctica. A partir de hoy y durante los próximos días voy a compartir una serie de post explicando cada uno de dichos principios. Si bien los principios los voy a ir numerando, su numeración no tiene correlación alguna con su importancia. Aquí va el primero.

Independencia del IDE

La generación del build no puede depender de un IDE. Es sorprendente la cantidad de programadores que no son capaces siquiera de compilar su aplicación sin usar un IDE. Esta es una situación que veo en muchos ambiente Java (alta dependencia de Eclipse) y .Net (alta dependencia de Visual Studio). En la actualidad todos los lenguaje de programación cuentan con alguna herramienta de build e incluso si no existe una herramienta específica para algún lenguaje, siempre es posible utilizar alguna herramienta genérica como el noble make.

El evento del Año: AOC 2015

aoc2015

Definitivamente este evento está en el top 3 de los eventos que más expectativas me han generado.

Mi gran expectativa no es por el contenido, pues dada la propia dinámica del evento el contenido surgirá de los asistentes y será sin duda excelente. Lo que realmente me genera gran expectativa es el “formato inmersivo”: hay una invitación explícita a compartir plenamente 3 días realizando diversos tipos de actividades, sesiones de debate, caminatas, almuerzos, meriendas, cenas, visitas turísticas, actividades deportivas, etc, etc.

Y como si con una experiencia así no fuera ya suficiente, debemos sumarle el hecho de que el evento se llevará a cabo es uno de los paisajes naturales más hermosos de Argentina.

Me imagino…

….charlas después de la cena alrededor de una fogata.

…rondas de mate al aire libre con un cerro nevado de fondo.

… actividades recreativas a la orilla del lago.

…asado, chocolates y cerveza!!!!

La cita es 17, 18 y 19 de Abril en San Carlos de Bariloche, info completa en http://www.agileopencamp.com.ar/ ¿Te lo vas a perder?

 

 

 

Elegir un sistema de control de versiones

En más de una ocasión he sido consultado por organizaciones sobre la elección de sistemas de control de versión. Actualmente estoy trabajando con una organización que usa CVS y que está evaluando distintas herramientas para reemplazarlo.

Si bien basta con googlear un poco para encontrar miles de post sobre las diferencias, beneficios y problemas de los distintos sistemas de control de versiones, cambiar el sistema de control de versiones implica varias cuestiones no triviales.

Desde mi perspectiva estamos hablando de una herramienta que nos ayudará a resolver ciertas cuestiones de trabajo colaborativo y recalco esto: nos ayudará, la herramienta por sí sola no resolverá nada. Más aún, una herramienta mal utilizada puede traer más problemas que soluciones. Para que la herramienta nos permita resolver algún problema, debemos establecer ciertas reglas/convenciones para su uso (y luego respetarlas).

Dicho esto, deberíamos comenzar por identificar el/los problemas a resolver y luego analizar cómo es que cada alternativa de herramienta nos permitiría resolver esas cuestiones.

Desde mi óptica, hay 3 dimensiones de considerar en la evaluación.

Sistema de control de versiones: Git, Subversion, CVS, Mercurial, Darcs, son algunos sistemas de control de versiones. Para elegir uno posiblemente debamos comenzar por preguntarnos si queremos un sistema distribuido o centralizado y con ese punto de partida podremos ir acotando nuestras opciones. No voy a profundizar sobre este punto pues considero que es el que más desarrollado está y basta googlear un poco para encontrar pros y contras de cada uno.

Producto/Servicio: una vez elegido el sistema debemos elegir un producto o servicio que lo implemente. En este caso la discusión podría comenzar por: ¿queremos tener el sistema en nuestra infraestructura o preferimos contratarlo como servicio?. Una vez definido esto deberemos elegir un opción concreta. Ejemplo: supongamos que decidimos ir un sistema distribuido y concreto nos inclinamos por Git, entonces podríamos utilizar un servicio en la nube como el ofrecido por GitHub o Bitbucket o bien podríamos decidir adquirir un producto e instalarlo en nuestro entorno como podria ser GitLab o Stash.

Forma de uso: por más que hayamos elegido una producto/servicio concreto (supongamos GitLab), aún no basta para resolver nuestro problema, deberíamos definir ciertas cuestiones respecto de cómo usarlo. Esto implica responder preguntas tales como: ¿Cuál es el criterio para la creación de repositorios: creamos un único repo por equipo o creamos un repo por componente de nuestra solución? ¿usamos branches o forks? ¿cómo debería ser la estructura de cada repositorio?¿trabajamos todos sobre master o usamos feature branches?. Sin duda varias de estas cuestiones estarán influenciadas por la herramienta elegida pero más allá de eso, hay otra cuestiones que dependerán de problemática concreta de cada organización/proyecto.

En los últimos 2 años, he trabajado con al menos 5 organizaciones y en todos los casos la herramienta elegida ha sido Git. Si bien no siempre participé directamente en la elección de la herramienta, en varios casos estuve fuertemente involucrado en la definición de la forma de uso y la capacitación de los equipos.

Continuous: Integration vs Delivery vs Deployment

En los últimos dos años he repetido incontables veces la diferencia entre estas tres prácticas y dado que no encontré ninguna explicación online que me satisfaciera, he decidido escribir mi propia explicación.

Continuous Integration: el software suele desarrollarse en equipo, donde cada miembro trabaja en su máquina en una porción del software. En ese contexto, la práctica de Continuous Integration propone integrar de forma continua el trabajo realizado por cada miembro del equipo. Esto implica una serie de cuestiones como ser el uso de controlador de versiones y contar con un ambiente de integración donde puedan ejecutarse verificaciones sobre software integrado.

Continuous Delivery: en términos organizacionales esta práctica es poner en manos del negocio la decisión de cuándo ir a producción. Más concretamente eso implica que cada build exitoso pueda (si el negocio así lo decide) ir a producción. entiéndasee build como el artefacto resultante del proceso de integración)

Continuous Deployment: está práctica va más allá de Continuous Delivery e implica que cada build exitoso va automáticamente a producción. Tal como propone Jez Humble, un mejor nombre para esta práctica sería Continuous Release. Continuous Deployment implica Continuous Delivery pero no al reves.

Estas tres prácticas tienen un aspecto técnico relacionado a herramientas y aspecto humano relacionado a hábitos y reglas que las personas deben incorporar y que personalmente considero que es el mayor desafío a la hora de intentar implementar estas prácticas. Ejemplo: de nada sirve tener un controlador de versiones si los miembros del equipo hacen commit una vez por día.

El orden en que describí cada práctica tiene que ver con el orden natural de adopción de las misma. Cabe aclarar cada práctica puede implementarse con distintos “niveles de profundidad” los cuales dependerán del contexto de cada proyecto/organización.

Muchas veces al explicar estas prácticas la audiencia tiende a decir que quiere implementar Continuous Delivery ante lo cual suelo aclarar: “No todas las prácticas son necesarias para todo contexto” y a continuación pregunto: “¿Su negocio realmente necesita continuous delivery?” En determinados contextos tener Continuous Delivery puede ser imprescindible para que el negocio sea competitivo, mientras en otros contextos (posiblemente más estables a nivel de negocio), sea simplemente un nice-to-have.

Como comentaba un amigo que trabaja en la industria petrolera: “Nosotros tenemos 3 releases anuales planificados e inamovibles”, en un contexto así posiblemente no se justifique el esfuerzo que implica adoptar continuous delivery. Distinto es el caso de un negocio muy variable que requiere de cambios constantes en sus aplicaciones donde no tener Continuous Delivery podría implicar perder el negocio.

Por su parte la práctica de Continuous Integration tiene algunas particularidades respecto de las otras dos prácticas. En primer lugar, es una práctica higiénica, lo cual implica que en términos generales siempre debe utilizarse. En segundo lugar es una práctica “a puertas cerradas” en el sentido que su uso está complementamente en manos del equipo de desarrollo. No es necesario aprobación y/o interacción con personas de otras áreas de las organización ni con el usuario. Si bien puede ser útil tener ayuda del grupo de infraestructura para montar un servidor de integración continua, la realidad es que no es algo imprescindible, el propio equipo puede montar un servidor de integración continua en la máquina de alguno de los miembros del equipo o bien podría utilizar algún servicio online (como Travis o CloudBees).

Para quienes quieran profundizar les recomiendo es artículo de Jez Humble: Continuous Delivery vs. Continuous Deployment.

Para cerrar les comparto un par de imagenes (de mi autoría) que esquematiza la diferencia/relación entre estas prácticas.

ci_y_cd

 

cd_y_cd