GitHub Actions : CI/CD fiable et maintenable
Publié le · Mis à jour le
GitHub actions permet d’automatiser validations, tests, builds, packaging, tâches planifiées et déploiements depuis les événements du dépôt. Ce guide explique comment concevoir un CI/CD fiable, protéger les secrets, séparer les environnements, optimiser l’exécution, déployer des artifacts testés et maintenir le workflow dans le temps.
Concevoir le workflow avant le YAML
Avant d’écrire le YAML, décrivez le chemin du code depuis un changement développeur jusqu’à une version testée puis déployée. Listez branches, checks de pull request, installation, lint, type checking, tests, build, packaging, cibles de déploiement et éventuelles validations manuelles. Cette carte révèle les hypothèses avant qu’elles ne deviennent une suite de jobs difficile à comprendre. Définissez ce qui doit tourner sur chaque PR, ce qui appartient seulement à la branche principale et ce qui doit rester manuel ou planifié.
Séparez conceptuellement CI et CD. Le CI vérifie si le changement peut être fusionné : dépendances, qualité, tests et build. Le CD décide quoi faire après acceptation : empaqueter, déployer, migrer, vérifier la santé et promouvoir entre environnements. Cette séparation rend les erreurs plus faciles à interpréter et évite qu’un échec de test ressemble à un échec de production.
Définissez les entrées et sorties de chaque job. Un job de build reçoit le code et un lockfile et produit un artifact ; un job de déploiement consomme cet artifact et des credentials spécifiques à l’environnement. Ces contrats facilitent cache, réutilisation et diagnostic.
- Map release flow
- Separate CI and CD
- Define job inputs
- Document assumptions
Choisir des déclencheurs adaptés
Utilisez les événements qui correspondent au processus réel. pull_request est utile avant merge, push après merge, schedule pour la maintenance périodique et workflow_dispatch pour un lancement manuel contrôlé. Les path filters peuvent économiser du temps, mais ils doivent être assez prudents pour ne pas sauter des tests importants.
Protégez les branches et tags qui déclenchent le déploiement. Production ne devrait pas partir d’une feature branch arbitraire. Définissez clairement les branches de release, la signification des tags et les règles de création des versions. Une stratégie floue produit facilement des exécutions doublées ou des déploiements du mauvais commit.
Utilisez concurrency selon le besoin. Pour le CI, des commits plus récents peuvent rendre les runs précédents inutiles et ceux-ci peuvent être annulés. Pour un environnement de déploiement, vous pouvez au contraire imposer une seule exécution à la fois afin d’éviter deux releases concurrentes.
- Use focused triggers
- Protect release refs
- Manage concurrency
- Avoid duplicate runs
Construire un CI reproductible
Un CI fiable utilise un environnement reproductible. Fixez la version du runtime, installez depuis le lockfile et évitez les outils implicites non garantis par le runner. Les commandes du CI devraient rester proches des commandes locales pour permettre de reproduire un problème sans recréer l’infrastructure GitHub.
Faites échouer rapidement. Lint, format et analyse statique sont souvent plus rapides que les tests d’intégration ou un gros build. Les exécuter tôt réduit coût et attente. Séparez les tests indépendants lorsque le parallélisme apporte une vraie amélioration, sans transformer le workflow en dizaines de jobs incompréhensibles.
Rendez les critères de succès explicites. Un build vert qui a ignoré une partie des tests n’est pas une preuve. Les commandes doivent échouer lorsqu’un check important échoue, et les artifacts produits doivent être vérifiés avant le déploiement. Testez migrations et changements de schéma hors production avant la phase de release.
- Pin runtime
- Fail fast
- Parallelize carefully
- Validate outputs
Protéger secrets et environnements
Ne stockez jamais les secrets directement dans le YAML, le code ou les logs. Utilisez les secrets chiffrés du repository, de l’organisation ou de l’environnement selon le périmètre nécessaire. Un credential uniquement destiné à production ne doit pas être accessible à tous les jobs de pull request.
Les environments permettent de séparer staging et production avec credentials, approvals et règles de protection distincts. Cela évite qu’un job exécuté dans un contexte de test reçoive automatiquement les droits de production. Nommez clairement endpoints, régions et project IDs afin de limiter les erreurs de cible.
Considérez les logs comme un possible canal de fuite. Un mode debug, un echo ou une action tierce peut exposer une valeur sensible. Vérifiez ce qui est imprimé, évitez de passer des secrets en arguments visibles et faites une rotation après toute suspicion d’exposition.
- Scope secrets
- Separate environments
- Protect logs
- Rotate credentials
Optimiser cache, artifacts et matrices
Le cache accélère l’installation mais ne doit jamais devenir une source de vérité. Les clés doivent dépendre des fichiers qui décrivent réellement les dépendances. En cas de comportement étrange, il doit être simple de désactiver le cache pour vérifier si celui-ci est la cause.
Les artifacts servent à transmettre les sorties entre jobs et à conserver des preuves : package compilé, rapports de tests, coverage, screenshots ou logs utiles. Définissez une durée de rétention et n’y placez pas de secrets ou de données de production sensibles. Le déploiement devrait utiliser exactement l’artifact validé par le CI.
Les matrix jobs permettent de tester versions de runtime, systèmes ou configurations. Ils sont utiles lorsque la compatibilité compte réellement, mais chaque dimension multiplie le nombre de jobs. Commencez par les combinaisons supportées et séparez les scénarios expérimentaux des checks obligatoires.
- Cache safely
- Use artifacts
- Control retention
- Keep matrices intentional
Automatiser le déploiement avec contrôle
Le déploiement automatisé devrait promouvoir un artifact connu plutôt que reconstruire différemment à chaque étape. Conservez commit SHA, version, environnement et heure du déploiement. En cas d’incident, ces données permettent d’identifier immédiatement la release concernée.
Ajoutez des garde-fous proportionnés au risque. Staging peut être automatique alors que production exige une approbation ou un tag. Les migrations de base demandent une attention particulière car revenir en arrière sur les données est plus difficile que sur le code. Préférez des changements compatibles et préparez des sauvegardes lorsque nécessaire.
Après le déploiement, lancez smoke tests ou health checks sur l’environnement réel. Définissez à l’avance la stratégie en cas d’échec : rollback vers l’artifact précédent, arrêt pour décision humaine ou correction vers l’avant. Une bonne chaîne CD rend aussi la récupération prévisible.
- Promote tested artifacts
- Use approvals
- Run health checks
- Plan recovery
Rendre les échecs observables
Donnez aux jobs et steps des noms utiles. Une étape nommée Test API explique mieux le contexte qu’un simple Run command. Publiez rapports, annotations ou artifacts qui permettent d’agir sans parcourir des centaines de lignes. Pour un problème intermittent, capturez runtime, dépendances et service externe impliqué.
Distinguez erreurs de code et erreurs d’infrastructure. Une assertion, un registry indisponible, un credential expiré, un runner saturé ou un rate limit demandent des réponses différentes. Utilisez retry seulement pour les erreurs réellement transitoires. Relancer automatiquement toute erreur peut masquer un défaut déterministe.
Suivez durée, queue time, taux d’échec et jobs les plus coûteux. Ces indicateurs montrent où les développeurs attendent et quelles dépendances sont instables. Pour le CD, conservez l’historique des déploiements et reliez les incidents aux releases.
- Name steps clearly
- Classify failures
- Use targeted retries
- Track metrics
Maintenir et faire évoluer le pipeline
Gardez les fichiers workflow lisibles. Déplacez la logique répétée dans reusable workflows, composite actions ou scripts lorsque cela réduit la duplication sans cacher le comportement. Épinglez les actions tierces sur des versions de confiance et considérez-les comme des dépendances de sécurité.
Revoyez le pipeline lorsque l’architecture change. Monorepo, nouveaux services, environnements ou cibles peuvent nécessiter une autre organisation des jobs. Supprimez les jobs et secrets obsolètes seulement après avoir confirmé qu’aucun chemin actif n’en dépend.
Testez périodiquement le chemin de récupération. Vérifiez qu’un déploiement échoué peut être diagnostiqué, qu’un artifact précédent peut être restauré lorsque c’est approprié et que les credentials peuvent être renouvelés sans casser tout le système. Un pipeline mature reste compréhensible, reproductible et observable.
Vérifiez aussi les permissions du token utilisé par le workflow. Un job qui n’a pas besoin d’écrire des releases, packages ou contenus du dépôt ne devrait pas recevoir ces droits. Des permissions explicites réduisent l’impact potentiel d’une action tierce compromise. Les pull requests de forks demandent une attention particulière car les secrets y sont souvent restreints volontairement.
Dans un monorepo, évitez d’exécuter toute la chaîne si un package indépendant est le seul à changer, mais gardez une détection prudente. Une modification du lockfile, de la configuration racine ou d’un composant partagé peut nécessiter des tests plus larges.
Conservez des métadonnées de release utiles : version, digest de l’artifact, commit, environnement et identifiant de migration. Elles rendent l’analyse d’incident beaucoup plus précise qu’une simple date.
Vérifiez aussi les permissions du token utilisé par le workflow. Un job qui n’a pas besoin d’écrire des releases, packages ou contenus du dépôt ne devrait pas recevoir ces droits. Des permissions explicites réduisent l’impact potentiel d’une action tierce compromise. Les pull requests de forks demandent une attention particulière car les secrets y sont souvent restreints volontairement.
Dans un monorepo, évitez d’exécuter toute la chaîne si un package indépendant est le seul à changer, mais gardez une détection prudente. Une modification du lockfile, de la configuration racine ou d’un composant partagé peut nécessiter des tests plus larges.
- Keep workflows readable
- Review third-party actions
- Remove obsolete logic carefully
- Test recovery
Questions
À quoi sert github actions ?
À automatiser validations, tests, builds, tâches planifiées et déploiements à partir des événements du dépôt.
Déployer production à chaque push ?
Généralement non. Utilisez une branche, un tag, un environnement ou une approbation correspondant au processus de release.
Où stocker les secrets ?
Dans les secrets chiffrés ou mécanismes d’identité courts, avec le périmètre le plus restreint possible.
Que doit préserver un bon pipeline ?
Le commit ou artifact validé, des logs clairs, l’historique de déploiement, la séparation des environnements et un chemin de récupération.