Cómo lograr la integración continua en desarrollo de software

Desarrolladora o programadora trabajando en la computadora

Tomado de una charla interna dictada por Facundo Pascual, desarrollador de Cultura IT.

Con el objetivo de ahondar sobre la búsqueda de iterar y mejorar nuestros procesos de trabajo de forma constante, en este artículo vamos a analizar:

  • Qué es la integración continua
  • Qué necesitamos para aplicarla a nuestros proyectos
  • Por donde empezamos
  • Un punto de partida / A way to go

¿Qué es la integración continua?

Históricamente, el desarrollo de software ha dado un gran salto en los 70s/80s, comenzando con el proceso de desarrollo en cascada, del cual hemos contado sobre sus inicios en este artículo sobre metodologías ágiles.

De la mano del manifiesto agile, eventualmente salen a la luz las metodologías ágiles (como scrum), los ciclos de trabajo, los procesos iterativos, etc.

¿Cuál era el desafío del manifiesto agile? Convertirlo en un proceso sistematizado, documentado, 100% cíclico e iterativo.

La Integración Continua es parte del Delivery Continuo:

  • Code > Build > Test > Stage (casi igual que ir a producción) > Prod
  • Empezando desde la izquierda, es más común detectar errores. Sin embargo, mientras más avanzamos, el costo de corregir esos errores aumenta.
  • ¿Por qué nos enfocamos en esto? Porque producción equivale a cliente/usuario feliz, y cliente feliz equivale a facturación.
  • El objetivo del continuous delivery es desarrollar, iterar, y llegar a producción, en instancias chicas.

 

Aplicamos Continuous Delivery cuando:

  • El software puede ser deployado en cualquier momento.
  • El estado del producto (deployable) es la prioridad.
  • El feedback es automático ante cada cambio.
  • El deployment se hace con un click y puede ser de cualquier versión.
  • Se integra el código al menos una vez al día.

 

¿Cuáles son los beneficios del Continuous Delivery?

  • Reducción del riesgo.
  • Progreso constante (siempre hay algo nuevo para los usuarios por ir lanzando de a poco e ir haciendo iteraciones constantes).
  • Feedback constante y rápido (relacionado con lo anterior, como el progreso es rápido, el feedback es constante).

"La integración continua es una práctica en la que los miembros de un equipo integran su trabajo con frecuencia, por lo general al menos una vez al día, llevando a múltiples integraciones diarias."

Martin Fowler

Con esto podríamos decir que nuestro objetivo es convertir a la integración en algo “smooth” o “no-event”. Algo natural, no planificado, y liso.

¿Cómo logramos esto? El paso de build a test no tiene que sentirse.

¿Qué tratamos de resolver haciendo continuous delivery?

  • Merge hell (juntar, por ejemplo, a 4 desarrolladores codeando en un mismo código)
    • Siendo 3 o 4 personas codeando, más de una persona modifica el mismo archivo. Cuanto más días pasan sin mergear el código de las 4 personas, más complejo se hace luego resolverlo.
  • Disponibilidad de un build testable (muchas veces falla el build pero tiene que siempre haber algo disponible para testear)
  • Comunicación fracturada

"Si duele, hazlo seguido y dolerá mucho menos".

Jez Humble

¿Qué necesitamos para aplicar la integración continua a nuestros proyectos?

  • Build automatizada
  • Codigo auto-testeable
  • Convertir el proceso en continuo (al menos diario, y con la actitud que eso requiere)
  • Aplicar una buena estrategia de control de versiones
  • Priorizar la corrección de builds fallidas (con la actitud que eso requiere)
  • Hacer que la información y los resultados sean públicos y de fácil acceso para todo el equipo
  • Automatizar lo máximo posible, especialmente el deployment

¿Por dónde empezamos?

  • Generando un control de versiones
  • Convirtiendo el proceso en algo continuo (todos los días)
  • Generando código auto-testeable
  • Generando builds automáticas
  • Priorizando la corrección de las builds fallidas

Control de versiones

  • Deberíamos contar con un branch principal bien identificado
  • Todo trabajo se realizará sobre un branch de trabajo
  • Debería ser posible mergear desde nuestro branch de trabajo al branch principal
  • El estado del branch de trabajo deberá separarse lo mínimo posible del branch principal
  • Como regla general, deberá sincronizarse al menos una vez al dia

Algunas herramientas para lograrlo:

Código auto testable

  • No se consigue simplemente agregando unit testing. Si bien es algo importante, es solo una parte, ya que puede contener cosas como:
    • Validación de estilos (indentation, spacing, naming convention)
    • Pruebas de API
    • Pruebas unitarias
    • End-to-end
    • Pruebas de performance
  • Recomendación: agregar pruebas debería ser parte del proceso de desarrollo

Builds automatizadas

  • Una vez que tenemos un control de versiones acordes y suficientes tests para garantizarnos una confianza de que el producto es estable lo siguiente será:
    • Setear un ambiente de CI
    • One click building
    • One click testing
    • Nuestros resultados deberán ser públicos para cada miembro del equipo que necesite acceso a ellos
  • Opciones: Jenkins, Circle CI, Hudson, etc.

Un equipo continuo y las prioridades del equipo

  • Antes de realizar un commit todo dev debería:
    • Hacer pull desde el branch principal
    • Build
    • Correr pruebas en su ambiente local
    • Pushear al branch principal
    • Esperar el ok del proceso de integración
    • Listo!

Un punto de partida / A way to go:

  • Los temas aquí sugeridos son un punto de partida, una cuestión de organización interna de cada equipo y pueden diferir entre proyecto/equipo.
  • Una vez alcanzada la integración a nivel equipo, es posible estandarizar los demás pasos para todos los equipos.
  • El proceso de buildeo automático puede enlazarse al proceso de commit usando triggers.
  • Si una build es exitosa, el deployment puede automatizarse.
  • Tenemos que informar al equipo de cada evento en el proceso.
  • Tenemos que armar nuestros Pipelines, definiendo qué partes se automatizan y hasta qué punto.

"Continuous Integration is an attitude, not a tool."

James Shore

Lo que logramos aprender implementando estos procesos en equipo, es que no importan las herramientas que usemos, sino la actitud permanente de estar buscando la integración continua en nuestros equipos de trabajo.