Continuous Delivery como una cinta transportadora

Hace un par de semanas en un reunión de trabajo mi colega Mariano explicó la práctica de Continuous Delivery como una analogía con una cinta transportadora y me pareció simplemente excelente.

Siendo estrictos con las definiciones Continuous Delivery implica Continuous Integration y Trunk-Based Development. Entonces:

  • El equipo hace commits pequeños, si hace TDD, posiblemente un commit por cada nueva prueba en verde.
  • Un funcionalidad/story requiere de varios commits.
  • Si el equipo trabaja simultáneamente en más de una funcionalidad es común que una funcionalidad se complete mientras otra está aún en desarrollo.
  • Si efectivamente hacen continuous delivery es posible que a penas se complete una funcionalidad se la quiera poner producción. Esto a su vez implicaría llevar a producción también las funcionalidades aún no completas.

De esta forma el proceso de continuous delivery es una cinta transportadora donde cada commit es como un paquete que uno pone en la cinta y la cinta lo lleva a producción.

Esto tiene un impacto muy grande en la forma del trabajo del equipo que obliga a tomar precauciones adicionales como puede ser el uso de feature toggles, de manera que si una funcionalidad no completa llega a producción, la misma pueda ser “toggleada/apagada”.

Todos contra master: Trunk-Based Development

Más de una vez me he encontrado con gente sorprendida cuando le comento de esta práctica, por ello quiero compartir algunas reflexiones y explicaciones.

La idea es bastante simple, todo el equipo trabaja sobre un mismo branch todo el tiempo. Siendo un poco más laxos con la definición es posible trabajar sobre distintos branches en la medida que dichos branches no vivan más de 1 o 2 días.

La práctica de Trunk-Based Development va muy en línea con la practica de integración continua la cual, como su nombre lo indica, propone integrar el producto en forma continua mínimamente 1 vez al día. Desde la perspectiva de integración continua uno podría trabajar en distintos branches pero al fin del día uno debería integrar todos esos branches. Esto no es opinable ni discutible, es una definición. Puede gustar o no, pero es así como la práctica fue definida hace ya ~20 años. El punto es, no podemos decir que hacemos integración continua si estamos escribiendo código en distintos branches por varios días. En todo caso podemos decir que hacemos integración frecuente o esporádica, pero no continua, lo cual no tiene nada de malo.

Ahora bien, cuando uno piensa en hacer Trunk-Based Development surgen una serie de preguntas sobre cómo manejar diversas situaciones. No voy a entrar en detalle sobre esas diversas cuestiones, simplemente les voy a recomendar este excelente libro de Paul Hammant: https://trunkbaseddevelopment.com/book/.

Adicionalmente a los consejos de Hammant voy a compartir un conjunto de prácticas/premisas que yo suelo utilizar en conjunto con Trunk-Based Development.

  1. En primer lugar hablamos de un equipo chico, no más de 6 o 7 personas commiteando.
  2. Al mismo tiempo ese equipo chico trabaja en un pieza chica, un bounded context o un microservicio. Eventualmente puede trabajar en varios bounded context pero cada uno en un repositorio separado.
  3. Todo el código se escribe en pairing o mobbing, lo cual reduce la cantidad de cantidad de commits.
  4. Todo el código se escribe haciendo TDD, lo cual colateralmente genera una alta cobertura que funciona como una red de seguridad cuando están entrando varios commits sobre el mismo branch.
  5. Las funcionalidades están cortadas en “pequeñas fetas”, esto permite trabajar en pequeños incrementos que pueden completarse rápidamente (1, 2 o 3 días máximo).
  6. Ante cada commit, se integra el código, se buildea y se corren pruebas unitarias, se despliega a un ambiente compartido y se corren pruebras de aceptación. Si todo esto va bien, estamos en condiciones de ir a producción.

Se que algunos de estos puntos pueden resultar polémicos, incluso más polémicos que Trunk-based Development, pero esto es lo que a mi me suele funcionar. No digo que estoy vaya a funcionar en todos los contextos, pero creo que para descubrirlo hay que probarlo.