INTEGRACIÓN Y ENTREGA CONTINUAS

Michael Jordan

Integración Continua

Michael Jordan

I've never lost a game,
I just ran out of time.

  Michael Jordan

📙 Conceptos básicos
Control de versiones git, cvs, subversion, mercurial, etc.
Repo uca-gii/construccion alojado en github
Mainline estado actual del repositorio
Working copy copia local del repositorio
Check out clonar el repositorio en local

¡Cuidado! A diferencia de otros SCV antiguos, hacer checkout en git es cambiar de rama o restaurar los ficheros de un working tree.

¿Cómo funciona CI en la práctica?

Ejemplo de CI a escala

Desarrollo de una nueva característica o feature...

Check-out

Hacer check-out de una working copy en un repositorio

$ git clone https://github.com/sistemas-sw/construccion
Clonando en 'construccion'...
remote: Enumerating objects: 688, done.
remote: Counting objects: 100% (104/104), done.
remote: Compressing objects: 100% (74/74), done.
remote: Total 688 (delta 45), reused 84 (delta 29), pack-reused 584
Recibiendo objetos: 100% (688/688), 39.75 MiB | 22.49 MiB/s, listo.
Resolviendo deltas: 100% (296/296), listo.

Cambiarse al repo con la working copy local

$ tree -d construccion 
construccion/
├── docs
├── marp
└── slides
    ├── devops
    │   ├── docker
    │   │   ├── docs
    │   │   └── img
    │   ├── img
    │   ├── jenkins
    │   │   ├── entregable
    │   │   └── img
    │   ├── scv
    │   │   └── img
    │   └── terraform
    │       └── img
    ├── implementacion
    │   └── img
    └── marp
$ cd construccion 

Entorno de construcción

Preparar el entorno de construcción:

$ cd marp
$ npm install --save @marp-team/marp-core

added 304 packages, and audited 305 packages in 3s

34 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Construcción (build)

Construir en local (debería automatizarse):

$ cd ..
$ mkdir ./html/img
$ cp -R slides/devops/img/ ./html/img/
$ marp --allow-local-files --config-file ./marp/marp-engine.js \
    --html slides/devops/cultura.md \
    -o ./html/cultura.html
[  INFO ] Converting 1 markdown...
[  INFO ] slides/devops/cultura.md => html/cultura.html
$ open ./html/cultura.html

Ignorar el build (carpeta html/) al sincronizar el repo:

$ cat .gitignore
...
# Ignorar la carpeta html/
html/*.html
html/img/*.png
html/img/*.gif
**/html
...

Desarrollo y pruebas

A partir de ahora:

  • Modificar source code (ficheros .md) para hacer una tarea.
  • Hacer tests de que el cambio funciona.
  • git add, git commit y git push para subir los cambios al repositorio.

Con git:

  • El index guarda una instantánea del contenido del working tree.
  • Hacer commit es grabar los cambios en el repositorio (local).
  • Hacer push: es subir al repo global

Colaboración con otros

Si alguien modifica algo...

$ git pull
remote: Enumerating objects: 20, done.
remote: Counting objects: 100% (20/20), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 15 (delta 9), reused 15 (delta 9), pack-reused 0
Desempaquetando objetos: 100% (15/15), 3.03 KiB | 344.00 KiB/s, listo.
Desde https://github.com/sistemas-sw/construccion
   23141b5..7cc4304  master     -> origin/master
Actualizando 23141b5..7cc4304
Fast-forward
 slides/devops/cicd.md    | 194 ++++++++++++++++++------------------------------
 slides/devops/cultura.md | 184 ++++++++++++++++++-------------------------
 2 files changed, 118 insertions(+), 260 deletions(-)

Intregración

Aún no hemos acabado... Hay que hacer un build (manual o automático) en un servidor de integración común (v.g. Jenkins, Github Actions).

  • Si hay un conflicto entre dos desarrolladores, se suele detectar cuando el segundo hace un build sobre su copia de trabajo. Hay que arreglarlo lo antes posible.
  • El repo debe quedar en todo momento con un software estable, funcional y con pocos errores.
  • No hay que alejarse mucho de esa base estable pues llevaría mucho tiempo integrarse con ella.

Martin Fowler: Building a feature with CI

Devops team

Beneficios de CI

Abordar problemas del desarrollo:

  • Software complejo
  • Cambios inesperados e incompatibles
  • Desarrollo en equipo

Ventajas:

  • Retroalimentación rápida
  • Lotes pequeños
  • Calidad y productividad

Prácticas de CI

  • Un solo repositorio de código fuente
  • Automatizar la construcción (build)
  • Hacer el build self-testing
  • Todos deben hacer commit al trunk todos los días
  • Cada commit a la mainline debe originar un build en un servidor de integración
  • Arreglar inmediatamente los builds fallidos
  • Mantener rápidos los build
  • Etc.

Martin Fowler: Practices of CI

Un solo repo

Un solo repositorio

  • SCM, CVS, configuration management,...
    • Todo en el monorepo...
    • ...menos los productos del build
  • Instalar SO, [IDE, SGBD] y... checkout!
  • Minimizar número de ramas
Automatizar construcción

Automatizar los build

  • Build tools: make, GNU Autotools, Apache ant, mvn, gradle, dotnet msbuild, Ruby rake, etc.
  • Dependencias: Apache ivy, maven, npm, yarn, pip, conda, NuGet, cargo, etc.

No depender de los IDEs para hacer builds

Self testing

Hacer el build self-testing

  • ¿Hacer TDD o XP?
  • Suite de tests automatizados
  • XUnit, UI tests (Selenium), APIs (Appium), Mocking (mockito), etc.
  • SAST (SonarQube, ESLint, etc.)
Aizkolaris

Todos deben hacer commit al trunk todos los días

  • Encontrar problemas pronto
  • Frecuentes merge de ramas en el trunk
  • Diff debugging tras detectar fallos al ejecutar el build:
    git bisect

Búsqueda binaria de bugs en commits (inicio)

Git bisect

Búsqueda binaria de bugs en commits (repetir pasos)

Git bisect

$ git bisect reset

Elon Musk

1 commit de mainline ⇒\Rightarrow 1 build en servidor de integración

  • Update y build local... ¡no siempre se hace!
  • Pues en mi máquina me funciona...
  • Build en máquina compartida (manual vs. servidor de integración)
  • Servidores de CI: Jenkins, Gitlab CI/CD, Teamcity, Bamboo, GitHub Actions, Azure DevOps services, CircleCI, Semaphore, etc.

¿Nightly builds es hacer integración continua?

Build fallido

Arreglar inmediatamente los builds fallidos

  • Prioridad 1
  • Un par de personas basta
  • Técnica rápida: revertir el commit más reciente que ha roto el build y debug en local
  • Técnica para evitar romper la mainline: crear working copy desde head y hacer commits en una rama pending-head diferente
Sagrada Familia

Mantener rápidos los build

  • ¿1 hora es mucho? ¿10 minutos?
  • Testing: cuello de botella
  • Build pipeline o Staged build
  • Ejemplo: 2-stage pipeline
    1ª etapa rápida (compilación y pruebas unitarias sin la BD) →\rightarrow 1er. commit build
    2ª etapa lenta (pruebas de integración con la BD real) →\rightarrow build secundario →\rightarrow si falla, añadir tests al commit build

Otras prácticas de CI...

  • Testear en un clon del entorno de producción
  • Hacer que sea fácil para cualquiera obtener el ejecutable más reciente
  • Todos pueden ver lo que está pasando
  • Automatizar el despliegue
TBD timeline

Trunk-Based Development (TBD)

TBD timeline

Timeline no TBD

TBD vs no TBD

Controversia de CI

  • Prácticas de CI son controvertidas

    • Dividir features grandes en pasos pequeños
    • Lleva más tiempo completar las features grandes
  • Si los cambios son pequeños

    • Desarrollo + Entrega más rápidos y estables
    • Las ramas son de corta duración
    • Los desarrolladores reciben comentarios periódicos sobre el impacto de su trabajo en el sistema en conjunto
    • Más fácil y rápido detectar, clasificar y solucionar problemas

CI es el paso previo a la CD

Plutarco

Entrega Continua

Plutarco

Lo entregó todo al fuego,
que no hace distinción

  Plutarco

Deploy button

Entrega Continua

Se hace CD cuando:

  • Software desplegable en cualquier momento
  • Equipo prioriza mantener el software desplegable
  • Tras un cambio, cualquiera puede saber rápidamente si el sistema está listo para producción
  • Se puede desplegar con un click cualquier versión del software en cualquier entorno
Software finished

Beneficios de CD

  • Despliegues con riesgo reducido
  • Progreso creíble: ¿quién garantiza el done? ¿que esté en producción? ¿que lo digan los desarrolladores?
  • Feedback de los usuarios: reduce el riesgo de construir algo inútil

Cuanto antes te des cuenta...

User requirements

Cómo implementar CD

  • Automatizar el build, las pruebas y el despliegue
  • Trunk-based development
    • nº ramas activas < 3
    • ramas y forks con vida corta (< 1 día)
    • pocos locks del código (merge conflicts, freezes, etc.)
  • Shift-left de la seguridad
  • Arquitectura poco acoplada
  • Dejar a cada equipo elegir sus herramientas
  • Control de versiones de configuraciones y scripts de despliegue
  • Gestión de cambios en la base de datos: fixtures

Errores comunes al implementar CD

  • Creer que CD implica hacer despliegues frecuentes
  • No hacer cambios en las capacidades técnicas necesarias para hacer CD
  • Centrarse solo en herramientas y patrones (v.g. deployment pipeline)
  • No hacer CD porque no se puede hacer CDEP
J Curve

Transformación