Aller au contenu

Introduction a gitlabci slides

Introduction

GitLab CI/CD est le moteur d'automatisation intégré à GitLab

Il permet d'exécuter automatiquement des vérifications, des builds et des déploiements à chaque événement du cycle de vie du code


Vue d'ensemble

Cycle minimal d'un pipeline :

  • Un développeur pousse du code
  • GitLab crée un pipeline
  • Le pipeline exécute un ou plusieurs stages
  • Chaque stage contient un ou plusieurs jobs
  • Les jobs sont exécutés par des runners

Pipeline

Un pipeline est une suite de jobs déclenchés par un événement, par exemple :

  • Un push
  • Une merge request
  • Un tag
  • Un déclenchement manuel
  • Un schedule

Stages

Les stages servent à organiser l'ordre global d'exécution

Exemple classique :

  • build : construire l'application
  • test : lancer les tests
  • deploy : déployer

Tous les jobs d'un même stage peuvent s'exécuter en parallèle


Fichier .gitlab-ci.yml

La configuration du pipeline se fait dans le fichier .gitlab-ci.yml à la racine du dépôt

stages:
  - build
  - test
  - deploy

build_job:
  stage: build
  script:
    - echo "Building the project"

test_job:
  stage: test
  script:
    - echo "Running tests"

deploy_job:
  stage: deploy
  script:
    - echo "Deploying the project"

Jobs

Un job est une unité d'exécution

Chaque job définit en général :

  • Un stage
  • Une image ou un environnement d'exécution
  • Un script
  • Éventuellement des règles, variables, artifacts ou caches

Exécution d'un pipeline

GitLab orchestre le pipeline

Le runner récupère le job, prépare l'environnement d'exécution puis lance les commandes du script

Selon la configuration, le job peut s'exécuter dans :

  • Un conteneur Docker
  • Un shell local
  • Un cluster Kubernetes

GitLab Runners

Un GitLab Runner est l'agent qui exécute les jobs

Il peut être :

  • shared : mutualisé entre plusieurs projets
  • specific : dédié à un projet ou un groupe

Le runner détermine concrètement où et comment les commandes s'exécutent


Variables CI/CD

Les variables CI/CD servent à passer de la configuration et des secrets au pipeline

Exemples :

  • URL d'API
  • Nom d'environnement
  • Token d'accès
deploy_job:
  stage: deploy
  script:
    - echo "Deploying on $ENVIRONMENT"
  variables:
    ENVIRONMENT: production

À retenir : on peut définir des variables à plusieurs niveaux, par exemple groupe, projet ou job


Variables prédéfinies

GitLab expose aussi des variables déjà disponibles pendant l'exécution

Exemples utiles :

  • CI_JOB_NAME
  • CI_COMMIT_SHA
  • CI_PROJECT_NAME
  • CI_PIPELINE_ID
  • CI_COMMIT_BRANCH
job1:
  script:
    - echo "Job: $CI_JOB_NAME"
    - echo "Commit: $CI_COMMIT_SHA"
    - echo "Projet: $CI_PROJECT_NAME"

Artifacts

Un artifact conserve les fichiers produits par un job pour les rendre disponibles ensuite

Cas d'usage :

  • Rapport de tests
  • Binaire compilé
  • Logs
build:
  stage: build
  script:
    - make build
  artifacts:
    paths:
      - build/
    expire_in: 1 week

Cache

Le cache sert à accélérer les jobs en réutilisant des fichiers entre exécutions

Cas d'usage :

  • Dépendances téléchargées
  • Répertoires de cache des outils
test:
  stage: test
  script:
    - npm ci --cache .npm
    - npm test
  cache:
    paths:
      - .npm/

Cache vs Artifacts

Artifacts

  • Conservent un résultat produit par un job
  • Servent surtout à transmettre ou télécharger un livrable
  • Ont une durée de vie explicite

Cache

  • Réutilise des fichiers utiles aux futures exécutions
  • Sert surtout à gagner du temps
  • N'est pas un mécanisme de livraison

Rules

rules permet de décider quand un job doit être créé

On peut baser la décision sur :

  • La branche
  • Le type d'événement
  • Des variables
  • Des fichiers modifiés
deploy_job:
  stage: deploy
  script:
    - echo "Deploying to production"
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: manual
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: never

Ici, le job apparaît en manuel sur la branche par défaut et n'apparaît pas dans les pipelines de merge request


rules vs only/except

only et except existent encore, mais rules est plus souple et plus lisible

rules permet de combiner :

  • if
  • changes
  • exists
  • when

Exemple d'idée :

  • Exécuter un job seulement sur la branche par défaut si le dossier src/ a changé

needs

Par défaut, GitLab suit l'ordre des stages

needs permet de dire qu'un job dépend explicitement d'un autre et peut démarrer dès que cette dépendance est prête

build_app:
  stage: build
  script:
    - echo "Build step"

test_app:
  stage: test
  needs: ["build_app"]
  script:
    - echo "Test step"

extends

extends sert à réutiliser une configuration commune entre plusieurs jobs

.base_job:
  tags:
    - docker
  script:
    - echo "Base job script"

job1:
  extends: .base_job
  script:
    - echo "Job1 doing extra work"

job2:
  extends: .base_job
  script:
    - echo "Job2 doing extra work"

needs vs extends

needs parle d'ordre d'exécution et de dépendances

extends parle de réutilisation de configuration YAML


!reference

!reference permet de réutiliser un fragment déjà défini dans la configuration

.default:
  script:
    - echo "Commande par défaut"

job1:
  script:
    - !reference [.default, script]
    - echo "Commande spécifique à job1"

Utile pour éviter la duplication sur de petits blocs YAML


Scheduled pipelines

Un pipeline planifié est déclenché à intervalle régulier avec une syntaxe de type cron

Cas d'usage :

  • Scan de sécurité
  • Tests E2E de nuit
  • Nettoyage technique
  • Vérifications périodiques

Scheduled pipelines

Configuration dans GitLab :

  1. Aller sur le projet
  2. Ouvrir CI/CD puis Schedules
  3. Créer un nouveau schedule

Champs importants :

  • Description
  • Intervalle cron
  • Fuseau horaire
  • Branche cible
  • Variables optionnelles

Downstream pipelines

Il existe deux grandes familles :

  • Child pipeline : pipeline enfant dans le même projet
  • Multi-project pipeline : pipeline déclenché dans un autre projet

Exemple multi-projet :

trigger_deploy:
  stage: deploy
  trigger:
    project: project-group/my-downstream-project

Environments

Un environment relie un job de déploiement à une cible nommée comme :

  • production
  • staging
  • review/...

Cela permet à GitLab d'afficher :

  • L'historique de déploiement
  • L'URL associée
  • Les informations de rollback selon l'outillage utilisé

Environments

deploy_prod:
  stage: deploy
  script:
    - ./deploy.sh
  environment:
    name: production
    url: https://app.bastien.com
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

On retrouve ensuite les déploiements dans l'interface GitLab


Review Apps

Une Review App déploie une version éphémère de l'application pour une merge request

Intérêt :

  • Tester avant le merge
  • Partager une URL de preview
  • Valider plus vite un changement visuel ou fonctionnel

Review Apps

deploy_review:
  stage: deploy
  script:
    - ./deploy_preview.sh
  environment:
    name: review/$CI_COMMIT_REF_SLUG
    url: https://$CI_ENVIRONMENT_SLUG.preview.bastien.com
    on_stop: stop_review_app
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

stop_review_app:
  stage: deploy
  script:
    - ./delete_preview.sh
  environment:
    name: review/$CI_COMMIT_REF_SLUG
    action: stop
  when: manual
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

Parallélisation avec matrix

La matrice permet d'exécuter le même job sur plusieurs combinaisons de variables

test_compatibility:
  parallel:
    matrix:
      - PHP_VERSION: ["8.1", "8.2", "8.3"]
        OS: ["alpine", "ubuntu"]
  script:
    - echo "Testing PHP $PHP_VERSION on $OS"

Tags de runners

Les tags permettent d'envoyer un job vers un runner compatible avec ses besoins

Exemples :

  • Runner avec GPU
  • Runner Windows
  • Runner privé pour les déploiements sensibles
test_windows:
  stage: test
  tags:
    - windows-11
  script:
    - echo "Execution sur un runner Windows"

Templates distants

On peut centraliser des définitions communes dans un autre dépôt puis les inclure

Dépôt ci-templates

# templates/test-template.yml
.test_template:
  script:
    - echo "Run test"

Dépôt mon-repo

include:
  - project: 'mon-org/ci-templates'
    ref: 'main'
    file: '/templates/test-template.yml'

my_test_job:
  extends: .test_template
  stage: test

Components GitLab

Les CI/CD components sont une forme de réutilisation plus modulaire

Idée générale :

  • Un composant expose des inputs
  • Un projet peut inclure ce composant avec include:component
  • Cela aide à standardiser des blocs réutilisables

Components GitLab

Exemple simplifié :

spec:
  inputs:
    stage:
      default: test
---

"scan-job":
  stage: $[[ inputs.stage ]]
  script:
    - echo "Running scan"
include:
  - component: $CI_SERVER_FQDN/mon-org/security-components/scan@1.0
    inputs:
      stage: test

Templates vs Components

Templates

  • Très bien pour mutualiser des jobs YAML
  • Simples à comprendre
  • Souvent suffisants pour un besoin interne

Components

  • Plus modulaires
  • Plus adaptés à la réutilisation standardisée
  • Plus récents et un peu plus avancés à prendre en main

Services GitLab

Un service est un conteneur auxiliaire lancé à côté du job principal

Il sert surtout à fournir un service accessible par le réseau pendant le job, par exemple :

  • Une base PostgreSQL
  • Un Redis
  • Un Docker-in-Docker

Le service ne copie pas ses binaires dans le conteneur principal


Services GitLab

integration_test:
  image: node:18
  services:
    - name: mongo:6
      alias: mongo
  script:
    - npm ci
    - npm test

Le job contacte alors le service via le réseau, par exemple avec l'hôte mongo


Services GitLab

Points d'attention :

  • Les services sont recréés à chaque job
  • Un service peut prendre du temps à démarrer
  • Il faut parfois attendre qu'il soit réellement prêt avant de lancer les tests
script:
  - until nc -z mongo 27017; do sleep 1; done
  - npm test

Récap

Pour bien démarrer avec GitLab CI, il faut retenir :

  • La structure pipeline -> stage -> job
  • Le rôle des runners
  • La différence entre cache et artifacts
  • L'intérêt de rules, needs et extends
  • Les bases du déploiement avec environments et review apps