Maximize Page
Tech & DevOps HubEspace Tech & DevOps: Explorez le monde du Dev, du Cloud et des outils DevOps à travers nos articles et discussions Explore the world of development, the cloud and DevOps tools

Sécuriser les images et automatiser leurs mises à jour avec Renovate

Date de l'article:02-08-2026
CI/CD Gitlab automate refactoring
Renforçement de la sécurité de la chaîne d'approvisionnement logicielle en verrouillant les images Docker par leur digest SHA-256. Nous automatiserons leurs mises à jours avec Renovate.

Voici les 4 étapes principales de cet article.
Elles se suivent dans l'ordre logique de mise en place, mais vous pouvez y accéder directement depuis cette liste.

Pourquoi pinner les images Docker avec un digest?
Une image Docker identifiée uniquement par son tag, par exemple maven:3.9.11, n'est pas immuable. Deux pipelines exécutés à plusieurs semaines d'intervalle peuvent donc récupérer des contenus différents malgré l'utilisation du même tag.
C'est pourquoi nous pouvons associer le tag à un digest SHA-256 afin de référencer précisément le contenu de l'image utilisé par le pipeline.

Fonctionnement du téléchargement des images
Lorsqu'aucun registre n'est explicitement indiqué dans le nom de l'image, le Docker executor de GitLab Runner récupère les images depuis Docker Hub
Comme on ne le précise pas dans les jobs, GitLab interprète automatiquement cela comme venant, par exemple de:
docker.io/library/maven:3.9.11-eclipse-temurin-17
Autrement dit: registre: Docker Hub, namespace: library,
image: maven, tag: 3.9.11-eclipse-temurin-17
Son fonctionnement est similaire à la commande:
docker pull docker.io/library/maven:3.9.11-eclipse-temurin-17
Puis il démarre le conteneur avec cette image.
On conseille de garder la syntaxe courte. C'est la convention la plus répandue, c'est une bonne pratique qui rend la configuration claire.

Conversion des images
Dans l'article précédent, nous avions commencé à travailler sur le fichier "variables/global.yml" pour rassembler les images et leurs versions dans des variables et les utiliser dans nos pipelines. À présent, nous allons modifier ce fichier de versions afin de les préparer à recevoir leurs mises à jour.
1. Modifications dans le fichier de variables
Nous allons travailler sur le fichier .gitlab/variables/global.yml
Rappel du contenu du fichier où l'on avait rassemblé les images
variables:
  JAVA_VERSION: "17"
  MAVEN_USER_HOME: "$CI_PROJECT_DIR/.m2"
  MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"

  MAVEN_IMAGE: "maven:3.9.11-eclipse-temurin-17"
  MAVEN_IMAGE_JAVA21: "maven:3.9.11-eclipse-temurin-21"

  ALPINE_IMAGE: "alpine:3.24"
  POSTGRES_IMAGE: "postgres:16.14-alpine3.23"
  TRIVY_IMAGE: "aquasec/trivy:0.72.0"

  DOCKER_IMAGE: "docker:29.6.1"
  DOCKER_DIND_IMAGE: "docker:29.6.1-dind"

  K6_IMAGE: "grafana/k6:2.1.0"
Je repars de mon fichier contenant la liste des images et de leurs URL. Je suis le lien, je regarde l'environnement et je copie l'Index digest correspondant.

maven:3.9.11-eclipse-temurin-17
https://hub.docker.com/layers/library/maven/3.9.11-eclipse-temurin-17
prod-sonarQube: maven:3.9.11-eclipse-temurin-21
https://hub.docker.com/layers/library/maven/3.9.11-eclipse-temurin-21
alpine:3.22
https://hub.docker.com/layers/library/alpine/3.22
postgres:16.14-alpine3.23
https://hub.docker.com/_/postgres?tag=16.14-alpine3.23
docker:29.6.1 + services: docker:29.6.1-dind :: on le meme digest
/docker/29.6.1 29.6.1-dind

aquasec/trivy:0.72.0
https://hub.docker.com/r/aquasec/trivy/?tag=0.72.0
grafana/k6:2.1.0
https://hub.docker.com/r/grafana/k6?tag=2.1.0
2. Récupération des index digest par image
Puisque le registre est public, on ne va pas consommer inutilement des ressources Docker, on va récupérer les images directement depuis le registre Docker Hub.
Docker Hub peut afficher deux digests différents
  • Manifest digest: digest d'une architecture précise (amd64, arm64...)
  • Index digest: digest du manifeste multi-architecture
On utilise l'Index Digest afin que le registre fournisse automatiquement la bonne image selon l'architecture du runner

Exemple avec Maven: copy digest index from docker hub
Utilisation combinée (Tag + digest SHA-256)
Il est également possible de conserver le tag pour la lisibilité humaine tout en forçant la vérification du SHA (exemple): image: redis:7.2@sha256:XXXXX
3. Entrez les digest SHA-256 dans fichier global
Il ne reste plus qu'à mettre à jour les références des images en leur ajoutant leur digest. Derrière les versions des images, ajoutez simplement
@sha256: suivi de l'INDEX DIGEST, copié depuis le registre officiel
variables:
  JAVA_VERSION: "17"

  MAVEN_USER_HOME: "$CI_PROJECT_DIR/.m2"
  MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"

  MAVEN_IMAGE: "maven:3.9.11-eclipse-temurin-17@sha256:e4a7ace3dc0d645ed97f8d9ad0b0d3f0b14fa8d150138f27f116d7105a639b82"
  MAVEN_IMAGE_JAVA21: "maven:3.9.11-eclipse-temurin-21@sha256:6fdc855a6ed81d288ca7ca37ac6ff5e9308b612485c0801d70b25a858c83d237"

  ALPINE_IMAGE: "alpine:3.22@sha256:5291449c3df73caf6ed85e649dec1b9e818b39a5d8c871e97afc13e9cd5e8fa8"
  
  POSTGRES_IMAGE: "postgres:16.14-alpine3.23@sha256:42b8b8b29c8a4e933d88943e5b03001a78794905cf786e6e7634e9f2abd5a0d3"

  DOCKER_IMAGE: "docker:29.6.1@sha256:66d292e5c26bd33a6f6f61cacb880de2186339a524ecba1ce098dbbaceed6515"
  DOCKER_DIND_IMAGE: "docker:29.6.1-dind@#sha256:66d292e5c26bd33a6f6f61cacb880de2186339a524ecba1ce098dbbaceed6515"

  TRIVY_IMAGE: "aquasec/trivy:0.72.0@sha256:cffe3f5161a47a6823fbd23d985795b3ed72a4c806da4c4df16266c02accdd6f"

  K6_IMAGE: "grafana/k6:2.1.0@sha256:65c920dc067d5e2e00befbf982af6ad6ad0117034e8b1c65817c7975c52d4669"
Les digests, eux, restent immuables. Lorsqu'un tag Docker évolue vers un nouveau contenu, Renovate peut mettre à jour le digest tout en conservant le même tag. Lorsqu'une nouvelle version du tag est disponible, il peut également mettre à jour simultanément le tag et le digest.
Les versions et SHA cités peuvent différer de votre environnement en raison du temps écoulé entre les mises à jour et la rédaction des articles;
En cas d'écart, seul le repository est la source de vérité

Mise en place de Renovate
Une fois les images figées avec leurs digests, le contenu des images utilisées par les pipelines devient reproductible. En contrepartie, les versions n'évoluent plus automatiquement.
Renovate permet de résoudre ce problème en surveillant les images Docker, les dépendances ou les fichiers de configuration. Lorsqu'une nouvelle version est disponible, il crée automatiquement une Merge Request contenant la mise à jour proposée.

Pour Renovate, on travaillera sur ces fichiers:
.gitlab/
├── jobs/
│   └── renovate.yml
├── .gitlab-ci.yml
└── renovate.json
Processus et étapes
  1. Création d'un Personal Access Token GitLab spécialement utilisé pour Renovate
  2. Création du fichier renovate à la racine du projet et test de la regex
  3. Création d'un pipeline GitLab qui exécute Renovate
  4. Création du pipeline schedule et intégration dans la CI

Création du token
Renovate doit pouvoir communiquer avec l'API GitLab pour analyser le projet, créer des branches et ouvrir des Merge Requests. Il lui faut donc un jeton d'accès lui permettant de s'authentifier auprès de GitLab.
GitLab propose plusieurs mécanismes pour authentifier une automatisation: notamment les Personal Access Tokens, les Project Access Tokens et les Group Access Tokens. Le choix dépend du périmètre d'accès souhaité et de l'offre GitLab utilisée.
Les Project Access Tokens et les Group Access Tokens requièrent un abonnement payant. J'utiliserai un "Personal Access Token" combiné à un compte de service (Bot) avec l'offre gratuite de GitLab.
Le "Personal Access Token" est associé à notre compte utilisateur. Il faut donc lui attribuer uniquement les droits nécessaires et le stocker comme une variable CI/CD protégée et masquée. gitlab/#setting-up-project-access
Un token d'accès doit être considéré comme un mot de passe: ne jamais le commiter dans le dépôt, l'afficher dans les logs ou l'intégrer directement dans un fichier de configuration.
1. Créer le Personal Access Token:
Depuis le projet → Avatar → Edit profile → Access Tokens
Nom : renovate
Expiration : 1 an (ou sans expiration)
Scopes :  api
Cliquer sur Create personal access token et copier sa valeur
2. Ajouter le token dans le projet
Depuis le projet: Settings → CI/CD → Variables
Ajouter la variable:
Key: RENOVATE_TOKEN
Value: le TOKEN_PAT
Options:
 Masked
 Protected
Contraintes GitLab: une variable "Masked" doit tenir sur une seule ligne, faire au moins 8 caractères et respecter un jeu de caractères restreint.
Une variable "Protected" n'est exposée que sur les branches/tags protégés: Pensez donc à protéger la branche develop, sinon le schedule n'aura pas accès au token.

Analyse des besoins
Faisons une petite analyse de nos besoins avant l'écriture du fichier Renovate. Cela nous permettra de savoir ce qu'il nous faut configurer exactement
Pour respecter notre stratégie Git, Renovate ne devra scanner et envoyer ses MR que depuis la branche [develop]
Dans cette plateforme, l'application Flashcards est utilisée uniquement pour la CI/CD, GitHub reste la référence en charge de la mise à jour de ces fichiers.
Renovate ne devra donc pas scanner le dossier .github, le Dockerfile, et le pom.xml
Pour GitLab, on donne accès à sa CI (.gitlab/* ) et particulièrement au fichier variables/global.yml contenant toutes les images (et versions) utilisées dans la CI/CD
On évite d'avoir plusieurs MR ouvertes simultanément et Renovate ne devra en lancer que 1 par 1 en reprenant develop comme point de départ à chaque fois.
Si plusieurs mises à jour sont détectées, elles seront regroupées en une seule MR. Les mises à jour des versions majeures et mineures peuvent être traitées séparément.

1. Création du fichier Renovate.json
Avant de se pencher sur l'écriture du fichier, voyons un peu la documentation: json-schema et comment il fonctionne: key-concepts/how-renovate-works ainsi que ses modules
Le fichier de configuration cible un cas d'usage précis: la mise à jour de l'infrastructure CI/CD sur GitLab, avec une forte restriction sur le bruit (limite de PR) et l'utilisation de regex personnalisées
Créer le fichier renovate.json à la racine du projet
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:recommended"
  ],
  "enabledManagers": [
    "gitlabci",
    "custom.regex"
  ],
  "baseBranches": [
    "develop"
  ],
  "prConcurrentLimit": 1,
  "branchConcurrentLimit": 1,
  "ignorePaths": [
    "pom.xml",
    "Dockerfile",
    ".github/**",
    "src/**"
  ],
  "customManagers": [
    {
      "customType": "regex",
      "managerFilePatterns": [
        "/^\\.gitlab\\/variables\\/global\\.yml$/"
      ],
      "matchStrings": [
        "#\\s*renovate:\\s*depName=(?[^\\s]+)\\s*\\r?\\n\\s*[A-Z][A-Z0-9_]*:\\s*[\"'](?[^:]+):(?[^@\"']+)(?:@(?sha256:[a-f0-9]+))?[\"']"
      ],
      "datasourceTemplate": "docker",
      "versioningTemplate": "docker"
    }
  ],
  "packageRules": [
    {
      "description": "Group all Docker image updates from global variables",
      "matchFileNames": [
        ".gitlab/variables/global.yml"
      ],
      "groupName": "CI global images",
      "separateMajorMinor": true
    }
  ]
}
Résumé des modules
Avec extends:["config:recommended"]: on fait hériter le pipeline des bonnes pratiques par défaut de Renovate
enabledManagers:["gitlabci","custom.regex"]
Limite les managers utilisés par Renovate à:
→ gitlab-ci, pour les dépendances dans le fichier gitlab-ci.yml
→ custom.regex, pour les dépendances à détecter dans variables/global.yml
Avec baseBranches:["develop"], Renovate utilise develop comme branche de référence et cible ses mises à jour dessus
Avec prConcurrentLimit: 1 et branchConcurrentLimit: 1, on limite le bot à une seule Merge Request ouverte à la fois.
Avec ignorePaths, on exclut les fichiers que nous ne voulons pas traiter.

customManagers permet, via une regex, de scanner le fichier global.yml
Son "customType": "regex", "managerFilePatterns": [..]
applique une expression régulière pour viser ce fichier
Son matchStrings: [ ... ] permet de cibler les paquets écrits sous un commentaire spécifique (via depName, packageName, ..) dans le fichier .yml, la regex détecte aussi les digests SHA256 (currentDigest)
Ses datasourceTemplate et versioningTemplate indiquent à Renovate que les dépendances trouvées dans ce fichier proviennent du Docker Hub (ou d'un registre Docker) et qu'il doit utiliser les règles de versioning de Docker

packageRules: {...} permet de regrouper les mises à jour des images présentes dans global.yml, sous un même groupe nommé "CI global images"
Avec separateMajorMinor: true, les mises à jour majeures et mineures sont traitées séparément afin d'éviter de mélanger des changements potentiellement plus importants avec les simples mises à jour de patch. (Il s'agit déjà du comportement par défaut de Renovate, mais l'écrire explicitement rend l'intention claire.)
En bref, ce fichier configure Renovate pour agir comme un gardien de la CI/CD GitLab.
Il ne touche pas au code source, regarde uniquement le fichier de variables globales et les fichiers GitLab CI, il recherche les images Docker définies par un commentaire # renovate: depName=..., et/ou un digest. Il met à jour toutes ces images en même temps dans une seule Merge Request, (sauf en cas de versions majeures), ciblant la branche develop.

2. Ajout des commentaires Renovate
.gitlab/variables/global.yml
variables:
  JAVA_VERSION: "17"
  MAVEN_USER_HOME: "$CI_PROJECT_DIR/.m2"
  MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"

  # renovate: depName=maven
  MAVEN_IMAGE: "maven:3.9.11-eclipse-temurin-17@sha256:e4a7ace3dc0d645ed97f8d9ad0b0d3f0b14fa8d150138f27f116d7105a639b82"
  # renovate: depName=maven
  MAVEN_IMAGE_JAVA21: "maven:3.9.11-eclipse-temurin-21@sha256:6fdc855a6ed81d288ca7ca37ac6ff5e9308b612485c0801d70b25a858c83d237"

  # renovate: depName=alpine
  ALPINE_IMAGE: "alpine:3.22@sha256:5291449c3df73caf6ed85e649dec1b9e818b39a5d8c871e97afc13e9cd5e8fa8"

  # renovate: depName=postgres
  POSTGRES_IMAGE: "postgres:16.14-alpine3.23@sha256:42b8b8b29c8a4e933d88943e5b03001a78794905cf786e6e7634e9f2abd5a0d3"

  # renovate: depName=docker
  DOCKER_IMAGE: "docker:29.6.1@sha256:66d292e5c26bd33a6f6f61cacb880de2186339a524ecba1ce098dbbaceed6515"
  # renovate: depName=docker
  DOCKER_DIND_IMAGE: "docker:29.6.1-dind@sha256:66d292e5c26bd33a6f6f61cacb880de2186339a524ecba1ce098dbbaceed6515"

  # renovate: depName=aquasec/trivy
  TRIVY_IMAGE: "aquasec/trivy:0.72.0@sha256:cffe3f5161a47a6823fbd23d985795b3ed72a4c806da4c4df16266c02accdd6f"

  # renovate: depName=grafana/k6
  K6_IMAGE: "grafana/k6:2.1.0@sha256:65c920dc067d5e2e00befbf982af6ad6ad0117034e8b1c65817c7975c52d4669"
Le commentaire # renovate: depName=... sert à indiquer explicitement à Renovate quelle dépendance doit être recherchée.
La valeur correspond au nom du repository Docker (maven, alpine, postgres, aquasec/trivy, etc.).
Il doit se trouver sur la ligne directement au-dessus de la variable: une ligne vide entre les deux casse la regex.

Tester la Regex et le fichier de variables
Tester la Regex en amont, depuis l'excellent site regex101.com
  1. Dans le menu de gauche: "Editor", sélectionner <> Flavor: JavaScript
  2. Dans le Box "Regular Expression": Cliquez dans le coin en haut à droite et sélectionner Regex Options et ensuite Regex Flag cliquez sur global
  • Il faut ensuite enlever les guillemets et les doubles back-slash de la regex renovate:
    #\s*renovate:\s*depName=(?[^\\s]+)\s*\r?\n\s*[A-Z][A-Z0-9_]*:\s*[\"'](?[^:]+):(?[^@\"']+)(?:@(?sha256:[a-f0-9]+))?[\"']
  • Collez la liste des images du fichier variables/global dans la zone "Test String"
    tests de la regex Renovate et du fichier global
  • L'outil va scanner tout le fichier et mettre en surbrillance chaque bloc qui correspond à la structure. Pour chaque correspondance, vérifiez dans le panneau de droite, que les groupes sont correctement extraits
tests de la regex Renovate et du fichier global Match found

3. Création du pipeline Renovate
flashcards
└── .gitlab/jobs/renovate.yml
renovate:
  stage: quality
  image: renovate/renovate:latest
  variables:
    RENOVATE_PLATFORM: gitlab
    RENOVATE_ENDPOINT: "https://gitlab.com/api/v4"
    RENOVATE_REPOSITORIES: "val7304/flashcards"
									 
    LOG_LEVEL: info
  script:
    - renovate
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
    - when: never
4. Création du Pipeline Schedule
Depuis le projet (menu de gauche): Build → Pipeline schedules
Description   : Renovate
Target branch :  develop
Cron:          0 3 * * *
Cron timezone : Europe/Paris
Il ne faut rien configurer comme variable dans le "Pipeline Schedule"
Le pipeline sera exécuté tous les jours à 03h (heure de Paris)
La variable prédéfinie CI_PIPELINE_SOURCE s'assure que le job ne s'exécutera que lorsqu'il sera lancé par le "Pipeline Schedule"
si on fait un "git push" : CI_PIPELINE_SOURCE != schedule   Renovate ne tourne pas
si on ouvre une MR :    CI_PIPELINE_SOURCE != schedule   Renovate ne tourne pas
si on le Schedule :        CI_PIPELINE_SOURCE = schedule    Renovate tourne
C'est exactement ce qu'on veut. Il n'a pas besoin de s'exécuter à chaque commit.

5. Inclure les fichiers dans la CI
Le stage "quality" existe déjà, ajoutez simplement le job Renovate dans le fichier .gitlab-ci.yml
include:
  - local: '.gitlab/jobs/renovate.yml'

6. Ajouter la branche Renovate aux règles
Ajouter "renovate" juste derrière la dernière valeur (chore) dans le fichier .gitlab\templates\rules.yml afin qu'il détecte les Merge Requests venant de Renovate vers la branche develop
nouvelle règle:
.develop_rules:
  rules:
    - if: '$CI_COMMIT_BRANCH == "develop"'
    - if: '$CI_COMMIT_BRANCH =~ /^(feature|fix|refactor|chore|renovate)\/.+$/'
    - when: never

7. Mise à jour du composant sast/semgrep
Dans ce même fichier, nous avions mis en place, depuis la branche develop, le composant sast de Semgrep.
Nous pouvons lui ajouter son digest afin que Renovate puisse également le mettre à jour
Renovate sur gitlab.com/sast/-/tags?
Depuis code / tags:
Cliquez sur le short-sha du commit de la dernière version:
https://gitlab.com/components/sast/-/commit/0a29..
Remplacez la version:
- component: gitlab.com/components/sast/sast@3.4.0
Par le SHA long du commit:
- component: gitlab.com/components/sast/sast@0a29cf13041d2693472a2ce536c126df209b1cd4   #3.4.0
Laisser la version #3.4.0 en commentaire permet de suivre les versions mises à jour par Renovate

8. Vérification du job et de la version
Avant de laisser Renovate tourner tous les jours, on fait un premier test manuel
Depuis Build → Pipeline schedules
Ouvrir "Schedule Renovate" et cliquer sur Run ()
Ainsi on constate:
  • que le token fonctionne et Renovate trouve bien le dépôt
  • qu'il détecte les dépendances du fichier GitLab-ci (via le manager gitlabci)
  • qu'il détecte les images du fichier global.yml (via la custom.regex)
  • qu'il peut éventuellement créer une première MR
D'après les logs:
$ renovate
 INFO: Renovate started
       "renovateVersion": "44.57.2"
 INFO: Dependency extraction complete
       (repository=val7304/flashcards, baseBranch=develop)
       "stats": {
         "managers": {
           "gitlabci": {"fileCount": 9, "depCount": 12},
           "regex": {"fileCount": 1, "depCount": 9}
         },
         "total": {"fileCount": 10, "depCount": 21}
       }

9. Mise à jour de la version de l'image Renovate dans global
Maintenant que nous avons la version de l'image de Renovate, on peut rechercher son digest sur Docker Hub, l'ajouter dans le fichier "global.yml" et lui ajouter son commentaire Renovate, afin de lui faire bénéficier de ses propres mises à jour:
 # renovate: depName=renovate/renovate
  RENOVATE_IMAGE: "renovate/renovate:44.57.2@sha256:94230bf485d9f3b469eb3f63e05e960e7709084101acf159b132f2a3e2a225c7"
Dans le pipeline renovate.yml, remplacer:
image: renovate/renovate:latest
par:
image: $RENOVATE_IMAGE

9. Première Merge Request reçue
La branche est lancée depuis une branche Renovate vers develop, la stratégie Git est donc respectée

Renovate sur GitHub
Compatibilité multi-plateforme
Dependabot: intégré à l'écosystème GitHub
Renovate: compatible avec GitHub, GitLab, Bitbucket, Azure DevOps, Gitea, etc.
Renovate est particulièrement adapté si l'on souhaite utiliser le même outil sur plusieurs plateformes Git.
Je pourrais donc faire exactement la même chose sur GitHub, les faire cohabiter et ensuite supprimer Dependabot. Cela me permettra de n'avoir qu'un système à gérer.

Responsabilités entre plateformes
GitLab Renovate
.gitlab-ci.yml .gitlab/**/* renovate.json
GitHub Renovate
pom.xml Dockerfile .github/*
Cette répartition n'empêche pas certaines modifications d'être effectuées directement depuis une plateforme CI/CD lorsqu'une vulnérabilité est détectée.
Mise à jour des dépendances ou de l'image Docker
Le fichier pom.xml peut être modifié dans les plateformes CI/CD utilisant des scans de vulnérabilités (Trivy):
  • Si celles-ci concernent les dépendances: voir comment fixer-les-vulnerabilites-trivy-d-un-application-java
  • Si la vulnérabilité concerne l'image Docker: seul GitHub prend en charge la mise à jour de l'image Distroless et possède son script et son pipeline de mise à jour.
    Dans ce cas, il faut comparer les digests et, en cas de changement, mettre à jour le Dockerfile dans la plateforme concernée (GitLab).
En général, la mise à jour du digest de l'image résout la vulnérabilité sur l'image Docker.
Dans la majorité des cas, je retrouve les mêmes vulnérabilités sur les deux plateformes, celles-ci sont alors rapidement mises à jour.
Pour l'instant, j'ai encore Dependabot sur GitHub et rien ne presse pour l'installer progressivement ; la configuration de Renovate pourrait alors être partagée et harmonisée entre GitLab et GitHub afin de partager des paramètres communs, tout en conservant un périmètre de fichiers propre à chaque plateforme.

Conclusion
Avec ce refactoring, l'ensemble des pipelines devient entièrement reproductible grâce aux digests SHA, tout en restant simple à maintenir grâce à Renovate.
Cette combinaison permet de concilier le besoin de reproductibilité des pipelines avec la nécessité de maintenir régulièrement les images utilisées par la CI/CD.
Dans l'article suivant, nous poursuivrons le refactoring de la CI en externalisant les scripts CI. Chacun deviendra autonome, réutilisable et partageable entre plusieurs pipelines ou plateformes.

Laissez-moi un commentaire

En postant un commentaire anonyme, vous adhérez automatiquement aux conditions d'utilisation du site.