Salta el contingut
 

Fluxos de treball automatitzats en CI/CD

Joan Puigcerver Ibáñez

Llicència: CC BY-NC-SA 4.0

(Reconeixement - NoComercial - CompartirIgual) 🅭

Automatització en CI/CD

La integració contínua (Continuous Integration o CI) i el desplegament continu (Continuous Deployment o CD) són pràctiques que permeten als equips de desenvolupament integrar els canvis en el codi de manera regular i distribuir-los automàticament.

Aquestes pràctiques són essencials en el desenvolupament de programari actual, ja que acceleren el lliurament de funcionalitats noves, redueixen el temps d'aturada i milloren la qualitat del projecte mitjançant l'automatització de tasques repetitives, sense necessitat d'intervenció manual. Les tasques que s'automatitzen més habitualment són:

  • Compilació: compilació i empaquetatge de l'aplicació.
  • Proves: execució de proves i validacions.
  • Qualitat del codi: anàlisi amb linters, anàlisi estàtica, etc.
  • Desplegament: desplegament de l'aplicació i gestió de llançaments.
  • Documentació: generació i publicació de la documentació.

Què és la integració contínua (CI)?

La integració contínua (Continuous Integration o CI) consisteix a integrar de manera contínua i freqüent els canvis en la branca principal del projecte i a provar automàticament cada canvi quan s'integra en el repositori.

Això permet detectar i solucionar errors o vulnerabilitats de manera més senzilla i ràpida, ja que els canvis són més xicotets i fàcils de revisar. A més, la integració contínua facilita la col·laboració de l'equip, ja que redueix la possibilitat de conflictes entre branques encara que es treballe en paral·lel.

Un flux de treball típic de CI inclou els passos següents:

  • Anàlisi estàtica del codi: verifica la qualitat del codi font i assegura que compleix els estàndards establerts.
  • Compilació i proves automatitzades: asseguren que el projecte es compila correctament i que les funcionalitats implementades funcionen com s'espera.

Què és el desplegament continu (CD)?

El desplegament continu (Continuous Deployment o CD) és el procés d'automatitzar les tasques necessàries per a desplegar una aplicació. Pot incloure des de la preparació de la infraestructura fins al desplegament de l'aplicació en un entorn de proves o de producció.

Un flux de treball típic de CD inclou els passos següents:

  • Desplegament automàtic en un entorn de proves: permet fer proves i validacions addicionals.
  • Desplegament automàtic en l'entorn de producció: permet lliurar funcionalitats noves a les persones usuàries de manera ràpida i segura.

Fluxos de treball

Els fluxos de treball de CI/CD, també coneguts com a CI/CD pipelines, són processos automatitzats que s'encarreguen de la compilació, les proves i el desplegament de les aplicacions. Es componen de diferents tasques que s'executen automàticament, sense intervenció humana.

Exemple d'un flux de treball

https://katalon.com/

Figura 1. Exemple d'un flux de treball.

Cadascuna d'aquestes tasques pot incloure diverses accions, que es configuren en l'entorn de CI/CD que s'utilitze.

Entorns i ferramentes de CI/CD

Hi ha diferents entorns i ferramentes de CI/CD que permeten configurar i gestionar fluxos de treball automatitzats. Alguns dels més habituals són:

  • GitHub Actions: fluxos de treball automatitzats sobre repositoris de Git allotjats a GitHub.
  • GitLab CI/CD: fluxos de treball automatitzats sobre repositoris de Git allotjats a GitLab.
  • Forgejo Actions: fluxos de treball automatitzats sobre repositoris de Git allotjats a Codeberg (o en qualsevol altra instància de Forgejo). La seua sintaxi és pràcticament compatible amb la de GitHub Actions.
  • Jenkins: servidor d'automatització de codi obert, que cal instal·lar i configurar.
  • Travis CI: servei d'automatització allotjat en el núvol. És programari privatiu i requereix un compte de pagament.
  • Azure Pipelines: servei d'automatització de Microsoft Azure.
  • AWS CodePipeline: servei d'automatització d'Amazon Web Services.

GitHub Actions

GitHub Actions és una funcionalitat de GitHub que permet crear fluxos de treball sobre un repositori. Es gestionen des de l'apartat Actions, on es poden consultar les tasques d'automatització configurades i les seues execucions.

Cada projecte té característiques i necessitats pròpies; per tant, cal adaptar els processos a la naturalesa del projecte.

Consulta els Exemples de fluxos de treball per a trobar exemples de fluxos de treball més complexos i adaptats a diferents tipus de projectes.

Configuració d'un flux de treball

Les tasques d'automatització es defineixen en fitxers de configuració YAML, que s'han de situar dins del directori .github/workflows/.

Documentació oficial: Quickstart for GitHub Actions – GitHub

Repositori d'exemple: exemple-actions

.github/workflows/demo.yml
name: GitHub Actions Demo
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀
on:
  push:
  workflow_dispatch:
jobs:
  Explore-GitHub-Actions:
    runs-on: ubuntu-latest
    steps:
      - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
      - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
      - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
      - name: Check out repository code
        uses: actions/checkout@v5
      - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
      - run: echo "🖥️ The workflow is now ready to test your code on the runner."
      - name: List files in the repository
        run: |
          ls ${{ github.workspace }}
      - run: echo "🍏 This job's status is ${{ job.status }}."

GitHub Docs

La configuració bàsica d'un flux de treball es fa amb els camps següents:

  • name: nom del flux de treball.
  • on: esdeveniments que fan que s'execute.
  • jobs: llista de tasques que cal executar.

Cada tasca té les seccions següents:

  • runs-on: tipus de màquina on s'executa la tasca.
  • if: (opcional) condició que s'ha de complir per a executar la tasca.
  • steps: llista de passos que cal executar. Cada pas és una ordre de la terminal (run) o una acció de GitHub predefinida (uses):

    • name: nom del pas.
    • run: ordre de la terminal que s'executa.
    • uses: acció de GitHub predefinida que s'executa. Cada acció pot tindre els seus propis paràmetres de configuració, que s'estableixen dins de la secció with.

Execució d'una automatització

Les tasques d'automatització s'executen automàticament quan es compleixen les condicions definides en la secció on de la configuració.

on:
  push:
    branches:
      - main

Documentació oficial: Events that trigger workflows – GitHub

En la secció Actions es poden consultar les execucions de les tasques d'automatització definides en el repositori.

A més, una tasca es pot configurar perquè també es puga executar manualment, especificant workflow_dispatch en la secció on de la configuració:

on:
  workflow_dispatch:

Així, l'automatització es pot llançar manualment des de la secció Actions.

Execució manual d'una automatització

Figura 1. Execució manual d'una automatització des de Actions.

Per a provar una tasca d'automatització localment sense haver de publicar canvis en el repositori, es poden utilitzar ferramentes com act. Aquesta ferramenta utilitza Docker per a simular un entorn d'execució semblant al de GitHub Actions.

Per exemple, aquesta és l'eixida d'act en executar el flux de treball del repositori d'exemple:

jpuigcerver@fp:~/exemple-actions (main) $ act
INFO[0000] Using docker host 'unix:///var/run/docker.sock', and daemon socket 'unix:///var/run/docker.sock' 
[GitHub Actions Demo/Explore-GitHub-Actions] ⭐ Run Set up job
[GitHub Actions Demo/Explore-GitHub-Actions] 🚀  Start image=catthehacker/ubuntu:act-latest
[GitHub Actions Demo/Explore-GitHub-Actions]   🐳  docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true
[GitHub Actions Demo/Explore-GitHub-Actions]   🐳  docker create image=catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[GitHub Actions Demo/Explore-GitHub-Actions]   🐳  docker run image=catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[GitHub Actions Demo/Explore-GitHub-Actions]   🐳  docker exec cmd=[node --no-warnings -e console.log(process.execPath)] user= workdir=
[GitHub Actions Demo/Explore-GitHub-Actions]   ✅  Success - Set up job
[GitHub Actions Demo/Explore-GitHub-Actions] ⭐ Run Main echo "🎉 The job was automatically triggered by a push event."
[GitHub Actions Demo/Explore-GitHub-Actions]   🐳  docker exec cmd=[bash -e /var/run/act/workflow/0] user= workdir=
| 🎉 The job was automatically triggered by a push event.
[GitHub Actions Demo/Explore-GitHub-Actions]   ✅  Success - Main echo "🎉 The job was automatically triggered by a push event." [68.068069ms]
[GitHub Actions Demo/Explore-GitHub-Actions] ⭐ Run Main echo "🐧 This job is now running on a Linux server hosted by GitHub!"
[GitHub Actions Demo/Explore-GitHub-Actions]   🐳  docker exec cmd=[bash -e /var/run/act/workflow/1] user= workdir=
| 🐧 This job is now running on a Linux server hosted by GitHub!
[GitHub Actions Demo/Explore-GitHub-Actions]   ✅  Success - Main echo "🐧 This job is now running on a Linux server hosted by GitHub!" [66.309582ms]
[GitHub Actions Demo/Explore-GitHub-Actions] ⭐ Run Main echo "🔎 The name of your branch is refs/heads/main and your repository is cursgit/exemple-actions."
[GitHub Actions Demo/Explore-GitHub-Actions]   🐳  docker exec cmd=[bash -e /var/run/act/workflow/2] user= workdir=
| 🔎 The name of your branch is refs/heads/main and your repository is cursgit/exemple-actions.
[GitHub Actions Demo/Explore-GitHub-Actions]   ✅  Success - Main echo "🔎 The name of your branch is refs/heads/main and your repository is cursgit/exemple-actions." [65.540094ms]
[GitHub Actions Demo/Explore-GitHub-Actions] ⭐ Run Main Check out repository code
[GitHub Actions Demo/Explore-GitHub-Actions]   🐳  docker cp src=/home/jpuigcerver/exemple-actions/. dst=/home/jpuigcerver/exemple-actions
[GitHub Actions Demo/Explore-GitHub-Actions]   ✅  Success - Main Check out repository code [15.128121ms]
[GitHub Actions Demo/Explore-GitHub-Actions] ⭐ Run Main echo "💡 The cursgit/exemple-actions repository has been cloned to the runner."
[GitHub Actions Demo/Explore-GitHub-Actions]   🐳  docker exec cmd=[bash -e /var/run/act/workflow/4] user= workdir=
| 💡 The cursgit/exemple-actions repository has been cloned to the runner.
[GitHub Actions Demo/Explore-GitHub-Actions]   ✅  Success - Main echo "💡 The cursgit/exemple-actions repository has been cloned to the runner." [65.674574ms]
[GitHub Actions Demo/Explore-GitHub-Actions] ⭐ Run Main echo "🖥 The workflow is now ready to test your code on the runner."
[GitHub Actions Demo/Explore-GitHub-Actions]   🐳  docker exec cmd=[bash -e /var/run/act/workflow/5] user= workdir=
| 🖥 The workflow is now ready to test your code on the runner.
[GitHub Actions Demo/Explore-GitHub-Actions]   ✅  Success - Main echo "🖥 The workflow is now ready to test your code on the runner." [75.593933ms]
[GitHub Actions Demo/Explore-GitHub-Actions] ⭐ Run Main List files in the repository
[GitHub Actions Demo/Explore-GitHub-Actions]   🐳  docker exec cmd=[bash -e /var/run/act/workflow/6] user= workdir=
| README.md
[GitHub Actions Demo/Explore-GitHub-Actions]   ✅  Success - Main List files in the repository [85.435409ms]
[GitHub Actions Demo/Explore-GitHub-Actions] ⭐ Run Main echo "🍏 This job's status is success."
[GitHub Actions Demo/Explore-GitHub-Actions]   🐳  docker exec cmd=[bash -e /var/run/act/workflow/7] user= workdir=
| 🍏 This job's status is success.
[GitHub Actions Demo/Explore-GitHub-Actions]   ✅  Success - Main echo "🍏 This job's status is success." [67.346446ms]
[GitHub Actions Demo/Explore-GitHub-Actions] ⭐ Run Complete job
[GitHub Actions Demo/Explore-GitHub-Actions] Cleaning up container for job Explore-GitHub-Actions
[GitHub Actions Demo/Explore-GitHub-Actions]   ✅  Success - Complete job
[GitHub Actions Demo/Explore-GitHub-Actions] 🏁  Job succeeded

Execució d'una automatització en una Pull Request

Les tasques d'automatització també es poden combinar amb les Pull Requests per a comprovar que els canvis proposats compleixen els estàndards de qualitat del projecte abans d'integrar-los en la branca principal. D'aquesta manera, es facilita la integració contínua (CI). Les tasques més habituals en aquest cas són:

  • Proves: execució de proves automatitzades.
  • Estil: anàlisi de l'estil del codi.
  • Qualitat: anàlisi de la qualitat del codi.

Execució d'una automatització en una Pull Request

Figura 2. Exemple d'una tasca d'automatització que s'executa en una Pull Request.

Execució correcta d'una automatització en una Pull Request

Figura 3. Exemple d'una tasca d'automatització que s'ha executat correctament en una Pull Request.

Secrets

De vegades, les tasques d'automatització necessiten informació sensible per a executar-se, com ara credencials d'accés a serveis externs, claus d'API, etc.

En aquests casos, és important no incloure aquesta informació directament en els fitxers de configuració, ja que formen part del repositori i qualsevol persona amb accés al repositori els pot llegir.

GitHub Actions permet gestionar aquesta informació de manera segura mitjançant els secrets: variables d'entorn que es poden utilitzar en les tasques d'automatització, però que no són visibles ni accessibles des dels fitxers de configuració.

Per a configurar un secret, cal anar a la secció Settings del repositori, a l'apartat Secrets and variables > Actions.

Configuració de secrets en GitHub Actions

Figura 4. Configuració de secrets en GitHub Actions.

Els secrets es poden utilitzar com a variables en els fitxers de configuració dels fluxos de treball, i el seu valor se substitueix de manera segura durant l'execució.

steps:
  - name: Login a Docker Hub
    uses: docker/login-action@v3
    with:
      username: ${{ secrets.DOCKERHUB_USERNAME }}
      password: ${{ secrets.DOCKERHUB_TOKEN }}

Documentació oficial: Using secrets in GitHub Actions – GitHub

GitHub Pages

GitHub Pages és un servei de GitHub que permet publicar llocs web estàtics1 directament des d'un repositori de GitHub.

Amb un compte gratuït de GitHub, només es pot configurar GitHub Pages en repositoris públics.

En els repositoris privats, cal un compte de pagament. No obstant això, GitHub proporciona llicències gratuïtes per a l'alumnat i el professorat mitjançant GitHub Education.

Aquest servei és útil per a publicar:

  • Documentació: la documentació d'un projecte.
  • Portafolis: portafolis personals o de projectes.
  • Llocs web estàtics: llocs generats amb ferramentes com Jekyll o MkDocs.

Per exemple, aquest lloc web està publicat amb GitHub Pages.

Configuració de GitHub Pages

GitHub Pages s'habilita i es configura en la secció Settings del repositori, dins de l'apartat Pages.

Configuració de GitHub Pages

Figura 5. Configuració de GitHub Pages en aquest repositori.

GitHub Pages es pot configurar per a publicar el lloc web de dues maneres diferents:

  • Automatització: un flux de treball construeix, carrega i desplega els continguts del lloc web.

  • Contingut d'una branca: es publica el contingut d'una branca i d'un directori concrets del repositori. Es pot triar qualsevol branca, però només els directoris / (arrel del repositori) o /docs.

Bibliografia


  1. Un lloc web estàtic és un lloc web que no necessita un servidor que genere les pàgines HTML, sinó que les pàgines ja estan generades i se serveixen directament. ↩

📌 Aquest document pot quedar desactualitzat després d’imprimir-lo. Pots consultar la versió més recent a la pàgina web.
🌿 Abans d’imprimir aquest document, considera si és realment necessari. Redueix el consum de paper i ajuda a protegir el nostre entorn.