Este codelab está planeado para mostrar la forma de agregar una configuración básica de integración continua por medio de los pipelines Gitlab.

En caso de requerir agrega una configuración que incluya también despliegue continuo, es necesario usar el DroneCI de CONACyT.

El proceso se dividirá en etapas pasos:

  1. Agregar una configuración mínima
  2. Agregar una configuración contemplar compilación y pruebas
  3. Agregar una configuración que contemple el caché de Gitlab.

Antes de iniciar, se requiere:

  1. Un proyecto que compile y tenga sus pruebas unitarias activadas.
  2. El proyecto debe estar dentro de un Gitlab con la configuración de Gitlab runner
  3. En caso de que el proyecto esté en el Gitlab de la CRIP, no deberá tener una configuración previa de CI/CD.

Para que Gitlab ejecute el ciclo de CI/CD, se requiere crear un archivo de configuración llamado .gitlab-ci.yml (este archivo debe localizarse en la raíz del proyecto).

El contenido del archivo será el siguiente:

image: maven:3.6-jdk-11

compile:
  stage: build
  script:
    - mvn clean package

En el archivo se tiene dos partes importantes:

  1. image: Define la imagen Docker a usar por default en los diferentes stages (si un stage requiere una imagen diferente se pude indicar en el propio stage).
  2. compile: Este es el nombre que se le dio al stage, como se puede ver, también se indica el tipo de stage (en este caso es build) y la lista de scripts que se ejecutarán en el stage.

Una vez que se ha creado y guardado la configuración, se debe subir el archivo al repositorio central:

git add .gitlab-ci.yml
git commit -m "Primera versión de CI"
git push

Una vez realizado el push, Gitlab detectará el archivo de configuración nuevo e iniciará el proceso de CI/CD. Para verificar que el archivo recién creado fue detectado por Gitlab, es necesario acceder al sitio del proyecto dentro de Gitlab y buscar la sección CI/CD

img01

Dentro de esta sección se podrá observar que se está ejecutando un primer pipeline

img02

Una vez que termine de ejecutarse el pipeline, debería mostrarse el pipeline con íconos en verde

img03

Una vez que se halla verificado que la integración continua está funcionando, se puede agregar un nuevo stage que se encargue de realizar la fase de pruebas.

Para esto es necesario editar el archivo de configuración (.gitlab-ci.yml) y modificarlo para que quede de la siguiente forma:

image: maven:3.6-jdk-11

compile:
  stage: build
  script:
    - mvn clean package -DskipTests

integration-test:
  stage: test
  script:
    - mvn clean verify -Pprod

En este caso se tienen dos stages:

  1. build: En este stage se omiten las pruebas, esto debido a que en el siguiente stage se realizarán de forma completa.
  2. integration-test: En este stage se vuelve a compilar y se realizan las pruebas unitarias y de integración.

El primer stage es tipo build y el segundo de tipo test.

Una vez que se han guardado los cambios en la configuración, se debe subir el archivo al repositorio central:

git add .gitlab-ci.yml
git commit -m "Pruebas unitarias en CI"
git push

Al momento de revisar el listado de pipelines se puede observar que esta vez hay dos stages

img04

Si entramos al pipeline (dando clic sobre el estado del pipeline), es posible observar los nombres de los stages definidos

img05

Debido a que Gitlab limpia el espacio de trabajo entre cada stage, los archivos que no pertenecen al proyecto son borrados antes de cambiar de stage. Esto incluye tanto a los archivos que se descargan (como los artefactos de Maven o los módulos de Node) como los archivos generados.

Para evitar esto, es posible usar el caché de los runners de Gitlab. En el caso del ejemplo, se usará para guardar los artefactos de Maven y, así, no tenerlos que descargar una segunda vez (una por cada stage).

Para esto es necesario editar el archivo de configuración (.gitlab-ci.yml) y modificarlo para que quede de la siguiente forma:

image: maven:3.6-jdk-11

cache:
  paths:
    - .m2/repository
  key: '$CI_BUILD_REF_NAME'

variables:
  MAVEN_OPTS: '-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository'

build:
  stage: build
  script:
    - mvn clean package -DskipTests

integration-test:
  stage: test
  script:
    - mvn clean verify -Pprod

En el ejemplo, se tiene dos configuraciones extras:

  1. cache: Indica las rutas que van a guardarse en el caché y la llave de reemplazo (en este caso se está guardando el caché por branch)
  2. variables: Agrega una variable de ambiente para indicarle a Maven sobre el directorio a usar para los archivos del repositorio local (esto es una configuración exclusiva para Maven, para Node solo es necesario guardar node_modules); sin embargo, por medio de las variables podemos modificar el comportamiento del runner o git.

Una vez que se han guardado los cambios en la configuración, se debe subir el archivo al repositorio central:

git add .gitlab-ci.yml
git commit -m "Uso de caché en CI"
git push

Pipeline para guardar el target

En este ejemplo se declara el directorio target en las rutas del caché para poderlo usar en el stage del SonarQube.

image: maven:3.6-jdk-11

cache:
  paths:
    - .m2/repository
    - target
  key: '$CI_PIPELINE_ID'

variables:
  MAVEN_OPTS: '-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository'

build:
  stage: build
  script:
    - mvn clean package

code-review:
  stage: test
  script:
    - mvn sonar:sonar -Dsonar.login=${SONAR_TOKEN} -Dsonar.host.url=${SONAR_URL}

Pipeline con node

En este ejemplo se guarda el directorio node_modules en el caché y, adicionalmente, se usa el tipo de stage .pre para realizar la instalación de las dependencias de Node previo a la compilación.

image: node:14

cache:
  paths:
    - node_modules
  key: '$CI_PIPELINE_ID'

install:
  stage: .pre
  script:
    - npm install

build:
  stage: build
  script:
    - npm run build --prod

Pipeline con múltiples imágenes

En este ejemplo se utiliza una imagen Docker diferente para el stage de tipo deploy.

image: node:14

cache:
  paths:
    - node_modules
    - dist
  key: '$CI_PIPELINE_ID'

install:
  stage: .pre
  script:
    - npm install

build:
  stage: build
  script:
    - npm run build --prod

publish-docker:
  stage: deploy
  image: docker:19
  script:
    - docker login $REGISTRY_NAME -u $HARBOR_USER -p $HARBOR_PASS
    - docker build -t $REGISTRY_NAME/library/codelabs .
    - docker push $REGISTRY_NAME/library/codelabs

Para mayor información, revisar el sitio cd/ci de Gitlab.