Para hablar de CI/CD, consideramos necesario introducir un concepto más amplio que, por razones obvias de espacio y coherencia, no podemos profundizar más allá de un breve párrafo. El concepto que debemos mencionar es DevOps. Veamos qué se entiende por DevOps.
DevOps: conceptos básicos
El término «DevOps» combina «Desarrollo» y «Operaciones». DevOps engloba muchos aspectos y prácticas para gestionar los procesos de producción de software. Técnicamente, DevOps indica un conjunto de enfoques y valores, más que una lista de prácticas concretas a utilizar. DevOps debe declinarse en un contexto concreto, en los distintos equipos de producción y gestión de software. Como informa aquí RedHat: DevOps describe los enfoques que deben adoptarse para acelerar los procesos que permiten que una idea (como una nueva función de software, una solicitud de mejora o una corrección de errores) pase del desarrollo al despliegue en un entorno de producción, donde puede aportar valor al usuario. Estos enfoques requieren una comunicación frecuente entre los equipos de desarrollo y los operativos. En este contexto, CI/CD es un enfoque que forma parte de DevOps.
Traducción realizada con la versión gratuita del traductor www.DeepL.com/Translator
Qué significa CI/CD
CI/CD (Integración Continua/Entrega Continua – Despliegue) es un enfoque de desarrollo de software que consiste en construir, probar y entregar de forma continua y automática el código desarrollado. CI/CD permite la integración automática de los cambios incorporados al código fuente mediante el uso de pipelines, es decir, la automatización de las operaciones de construcción, prueba y despliegue del software. Como afirma RedHat aquí: El enfoque CI/CD es un componente fundamental de la metodología DevOps, cuyo propósito es aumentar la colaboración entre los equipos de desarrollo y operaciones. Ambos métodos se centran en la automatización de los procesos de integración del código, acelerando así el paso de una idea (como una nueva función, una corrección de errores o una solicitud de mejora) de la fase de desarrollo a la de despliegue, en un entorno de producción donde pueda ofrecer un valor añadido al usuario. El CI/CD incluye pasos que integran las operaciones a realizar para probar, compilar e integrar nuevos desarrollos en un software; el flujo de trabajo del equipo se adapta al uso de pipelines para optimizar su productividad y minimizar el tiempo y los errores en la fase de lanzamiento del software. Veamos algunos de los pasos clásicos que se integran en un pipeline de CI/CD, teniendo en cuenta que no son los únicos posibles y que el pipeline debe adaptarse a las necesidades del software que se está desarrollando y del equipo que trabaja en él.
Compilación
La compilación es el paso que crea algún tipo de ejecutable a partir del código fuente de la aplicación. Un tipo de software muy utilizado hoy en día se denomina «dockerizado». Docker se basa en ciertas características del kernel de Linux para permitir que el mismo software y sus dependencias se ejecuten en diferentes entornos. La compilación del software suele generar imágenes Docker, que son el software que posteriormente ejecutará Docker; tienen la ventaja de ser portátiles, autocontenidas y fáciles de replicar.
Pruebas
La fase de prueba en el proceso CI/CD es fundamental: garantiza que el código integrado en la aplicación no contenga regresiones o errores fácilmente detectables. Normalmente, la fase de pruebas se lleva a cabo sobre el código fuente creado por la fase de compilación, o la fase de pruebas se basa en la propia compilación, dependiendo de las características del software. El proceso suele prever que, si las pruebas fallan, se detenga la publicación; de lo contrario, el proceso continúa con la siguiente fase.
Versionado
El versionado de software implica guardar un historial de los cambios realizados en el software. Normalmente, se utiliza algún sistema tipo Git para versionar el código fuente; dado que Git es distribuido, a menudo se depende de algún sistema centralizado como GitHub o GitLab para mantener una versión oficial del proyecto. Además, el versionado implica asignar una versión, normalmente representada de alguna forma alfanumérica, al código fuente y a los ejecutables generados a partir de él. Es posible integrar la fase de versionado automáticamente en un pipeline. La versión del software suele asignarse mediante el versionado semántico, que tiene la forma M.m.p, donde M es la versión mayor, m es la versión menor y p es el parche.
Pipeline
Un pipeline, como ya se ha mencionado, es un procedimiento que automatiza el proceso CI/CD y con él la liberación de software a partir de nuevo código fuente. El objetivo del pipeline es permitir a los desarrolladores realizar liberaciones de forma automática, aliviando así la carga de trabajo de los equipos de Operaciones y Sistemas.
Pipeline en GitLab
GitLab es una plataforma DevOps que permite integrar fácilmente pipelines en los proyectos. GitLab integra el versionado del código fuente a través de Git, guardándolo en servidores centralizados que garantizan versiones compartidas y oficiales, herramientas y pipelines de CI/CD, y prácticas de control y seguridad del software. Incluir un pipeline en un proyecto GitLab es muy sencillo: basta con crear un archivo llamado .gitlab-ci-yml y colocarlo en el directorio raíz del proyecto. El archivo .gitlab-ci.yml describe el pipeline en términos de fases, trabajos y los distintos scripts correspondientes. La etapa es la implementación de las fases presentadas anteriormente: compilación, generación de versiones, pruebas u otras; un trabajo es una tarea concreta que ejecuta una parte de la etapa. Una etapa puede constar de varios trabajos, que se ejecutan en paralelo; las distintas etapas, en cambio, se realizan secuencialmente. Por último, el script implementa los comandos específicos relacionados con cada trabajo; además del script, éste incluye indicaciones sobre el entorno y el modo de ejecución. Las etapas del pipeline y sus scripts son ejecutados por defecto por los GitLab runners (procesos que proporcionan un entorno en el que ejecutar los comandos del script). Por supuesto, es posible configurar ejecutores locales. Para ello, consulta la documentación de GitLab. Un ejemplo de pipeline cuyo único propósito es introducir la sintaxis del archivo es: stages:
- build
- test
- deploy
build_job:
stage: build
script:
- echo "Building"
version_job:
stage: build
script:
- echo "Versioning"
test_job:
stage: test
script:
- echo "Testing"
deploy_job:
stage: deploy
script:
- echo "Deploying" El archivo pipeline indica tres etapas, en nuestro caso: build, test y deploy. Se puede introducir un número arbitrario de etapas con el nombre deseado. A continuación, cada sección describe trabajos. El deploy_job, por ejemplo, se ejecuta en la etapa deploy y consiste en el script echo ‘Deploying’ (que imprime la cadena Deploying como salida estándar). Es posible decidir ejecutar el trabajo de despliegue sólo para una determinada rama del código versionado. Para ello, la configuración debe ser:
deploy:
only:
- master
stage: deploy
script:
- echo "Deploying"
Un ejemplo
Un ejemplo de código de versionado de un pipeline al realizar una petición de fusión en el siguiente archivo .gitlab-ci.yml. stages: build: only: – master stage: build script: – echo “Building” version: stage: build before_script: – git config user.email “${GITLAB_USER_EMAIL}” – git config user.name “${GITLAB_USER_NAME}” – git remote add versioning-origin https://oauth2:${GITLAB_ACCESS_TOKEN}@gitlab.com/${CI_PROJECT_PATH} script: – echo «Versioning» – git fetch –tags – OLD_VERSION=`git describe –abbrev=0 –tags` – NEW_VERSION=`bash change_version.sh $OLD_VERSION` – git tag -a $NEW_VERSION -m «Auto-tagged» – git push versioning-origin $NEW_VERSION rules: – if: $CI_MERGE_REQUEST_ID test: only: – etapa maestra: script de prueba: – echo «Probando» deploy: only: – master stage: deploy script: – echo «Deploying» Como puede verse, los comandos siguen la sintaxis de Bash. La sección
- build
- test
- deployindica a GitLab que compruebe la variable de entorno por defecto CI_MERGE_REQUEST_ID, que especifica si el pipeline actual fue lanzado por una Merge Request. Este pipeline llama al script change_version.sh, que debe ser guardado en el repositorio del proyecto para ser ejecutado correctamente.
rules:
- if: $CI_MERGE_REQUEST_ID


