Partie 14 : Le chaînon manquant — Déploiement automatique de bout en bout

Partie 14 : Le chaînon manquant — Déploiement automatique de bout en bout

30 décembre 2025

Le problème

Dans les parties précédentes, on a mis en place les tests automatiques (Partie 8) et le build Docker multi-architecture (Partie 9). ArgoCD surveille déjà le repo GitOps et déploie automatiquement dès qu'il détecte un changement.

Mais il reste une étape manuelle qui casse tout le flux :

git push → Tests ✅ → Docker Build ✅ → Push Docker Hub ✅
                                              ↓
                                  ❌ Modifier values.yaml à la main
                                              ↓
                              ArgoCD détecte → Deploy K3s ✅

À chaque changement de code, je dois encore aller chercher le SHA du commit, éditer helm-charts/homefonta/values.yaml pour mettre à jour le tag, commit et push vers ansible-k3s. C'est 2-3 minutes de travail manuel avec un risque de typo à chaque fois.

L'objectif : un seul git push et tout le reste se fait automatiquement, jusqu'au déploiement sur K3s.

La solution : chaîner les workflows avec workflow_run

GitHub Actions propose un trigger workflow_run qui déclenche un workflow après qu'un autre se termine. L'idée : créer un troisième workflow qui, une fois le build Docker réussi, va automatiquement mettre à jour le values.yaml dans le repo GitOps.

Le workflow update-helm.yml

Fichier : .github/workflows/update-helm.yml (dans le repo home-fonta)

name: Update Helm Chart

on:
  workflow_run:
    workflows: ["Docker Build & Push"]
    types: [completed]
    branches: [main, master]

jobs:
  update-helm:
    runs-on: ubuntu-latest
    if: ${{ github.event.workflow_run.conclusion == 'success' }}

    steps:
      - name: Checkout home-fonta repo
        uses: actions/checkout@v4
        with:
          ref: ${{ github.event.workflow_run.head_branch }}

      - name: Get image tag
        id: image_tag
        run: |
          SHORT_SHA=$(echo ${{ github.event.workflow_run.head_sha }} | cut -c1-7)
          echo "tag=sha-${SHORT_SHA}" >> $GITHUB_OUTPUT

      - name: Checkout ansible-k3s repo
        uses: actions/checkout@v4
        with:
          repository: Nikob2o/ansible-k3s
          token: ${{ secrets.PAT_TOKEN }}
          path: ansible-k3s

      - name: Update values.yaml
        run: |
          cd ansible-k3s
          sed -i "s|tag: .*|tag: ${{ steps.image_tag.outputs.tag }}|" \
            helm-charts/homefonta/values.yaml

      - name: Commit and push to ansible-k3s
        run: |
          cd ansible-k3s
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add helm-charts/homefonta/values.yaml
          if git diff --staged --quiet; then
            echo "No changes to commit"
          else
            git commit -m "Update home-fonta image to ${{ steps.image_tag.outputs.tag }}" \
                       -m "Triggered by workflow"
            git push
          fi

Les points importants :

  • workflow_run + condition success : le workflow ne se lance que si le build Docker a réussi. Pas de déploiement d'images cassées.
  • Personal Access Token (PAT) : nécessaire pour que le workflow puisse pusher vers un autre repo (ansible-k3s). Créé dans GitHub Settings → Developer settings → Personal access tokens, puis ajouté comme secret PAT_TOKEN dans le repo home-fonta.
  • sed sur values.yaml : remplace le tag de l'image par le SHA court du commit. Simple et efficace.

Configurer le PAT

  1. GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
  2. Permissions : repo (accès complet aux repos)
  3. Dans le repo home-fonta → Settings → Secrets → PAT_TOKEN

Note sécurité : Le PAT donne accès à tous vos repos. Pour un environnement production, préférer une GitHub App avec permissions limitées.

Premier test : un bug YAML

Pour tester, j'ai ajouté un lien vers Ghost dans templates/services.html et poussé. Le workflow a échoué :

Invalid workflow file: .github/workflows/update-helm.yml#L64
You have an error in your yaml syntax on line 64

Le problème : un message de commit multi-lignes avec des emojis et des variables GitHub Actions qui cassait le YAML. La solution : utiliser l'option -m multiple de Git au lieu d'une chaîne multi-lignes.

Leçon : en YAML GitHub Actions, les chaînes multi-lignes avec variables sont piégeuses. Rester simple.

Deuxième test : ça marche !

Après correction, la cascade complète s'est exécutée :

  1. CI - Tests et Linting — 28 secondes, 6 tests passés
  2. Docker Build & Push — 3 min 42s, image sha-2e13437 créée et poussée
  3. Update Helm Chart — 12 secondes, values.yaml mis à jour et poussé

Vérification dans le repo GitOps :

git pull && grep "tag:" helm-charts/homefonta/values.yaml
# tag: sha-2e13437

ArgoCD a détecté le changement, synchronisé, et le nouveau code était en production en moins de 3 minutes. Le lien "Blog (Ghost)" était visible sur https://home-fonta.fr/services.

Le pipeline complet

┌──────────────────────────────────────────────────────────────┐
│  Developer : git push                                         │
└─────────────────────────┬────────────────────────────────────┘
                          ▼
┌──────────────────────────────────────────────────────────────┐
│  GitHub Actions (repo home-fonta)                             │
│                                                               │
│  1. CI Tests + Linting                            ~30s       │
│  2. Docker Build multi-arch + Push + Trivy        ~3m 42s    │
│  3. Update values.yaml dans ansible-k3s           ~12s       │
└─────────────────────────┬────────────────────────────────────┘
                          ▼
┌──────────────────────────────────────────────────────────────┐
│  ArgoCD (polling 3 min max)                                   │
│  Détecte le changement → Sync → Rolling Update → Healthy     │
└─────────────────────────┬────────────────────────────────────┘
                          ▼
┌──────────────────────────────────────────────────────────────┐
│  Cluster K3s — nouveau pod en production                      │
│  Temps total : ~7-8 minutes | Intervention manuelle : ZÉRO   │
└──────────────────────────────────────────────────────────────┘

Avant / Après

Avant Après
Temps 10-15 min de travail manuel 5 secondes (git push)
Tests Souvent oubliés Systématiques
Mise à jour values.yaml Manuelle (risque typo) Automatique
Traçabilité Aucune Commit SHA → image → déploiement
Rollback Refaire tout à la main git revert HEAD && git push

Ce que j'ai appris

  • workflow_run permet de créer des cascades de workflows propres. Toujours ajouter la condition conclusion == 'success'.
  • Cross-repo push nécessite un PAT. Le workflow clone le repo cible, modifie, commit et push.
  • YAML + variables GitHub Actions : rester simple, éviter les chaînes multi-lignes avec emojis et variables.
  • ArgoCD polling : 3 minutes par défaut, suffisant pour un homelab. Pour du temps réel, utiliser des webhooks.

Conclusion

Avec ce troisième workflow, le pipeline CI/CD est complet. Un git push suffit pour que le code soit testé, buildé en image Docker, et déployé sur K3s via ArgoCD — sans aucune intervention manuelle.

vim app.py
git add . && git commit -m "feat: nouvelle fonctionnalité" && git push
# Café. Quand je reviens, c'est en production.

C'est exactement ce que font les équipes DevOps en entreprise. Et maintenant, c'est sur mon homelab Raspberry Pi.


Session du 30 décembre 2025