[Factory](../../../README.md) > [Doc](../../README.md) > [Runbooks](../README.md) > [Nouvelle application web](README.md) > **6. Workflows CI** # 6. Les workflows CI (`.gitea/workflows/`) > **Status:** ✅ Active > **Upstream:** [1. Dépôt Gitea](01-gitea-repo.md) (secrets d'org), [3. Vault plateforme](03-vault-platform.md) (`gitea_cicd_`) > **Related:** [4. Chart Helm](04-helm-chart.md) · [5. Terraform de l'app](05-app-terraform.md) · [7. Enregistrement ArgoCD](07-argocd-register.md) · [Conventions de nommage](conventions.md) --- ## Summary Deux workflows Gitea Actions vivent dans le dépôt : **`vault.yaml`** applique le Terraform de l'app (`iac/`) en s'authentifiant à Vault via OIDC, et **`dockerimage.yaml`** (optionnel) construit l'image et la pousse au registre Gitea. Le déploiement lui-même n'est pas dans la CI : c'est ArgoCD qui s'en charge ([étape 7](07-argocd-register.md)). ## `vault.yaml` — appliquer le `iac/` de l'app Déclenché sur tout changement de `iac/*.tf`. Deux jobs : obtenir un JWT depuis Gitea, puis `tofu apply`. ```yaml on: workflow_dispatch: {} push: { paths: ['iac/*.tf'] } pull_request: { paths: ['iac/*.tf'] } # job 1 : échange OIDC Gitea → JWT (script base64 fourni en secret d'org) # run: echo -n "${{ secrets.vault_oauth__sh_b64 }}" | base64 -d | bash # job 2 : lire les secrets de bootstrap puis appliquer - name: read vault secret uses: https://gitea.arcodange.lab/arcodange-org/vault-action.git@main with: url: https://vault.arcodange.lab caCertificate: ${{ secrets.HOMELAB_CA_CERT }} jwtGiteaOIDC: ${{ needs.gitea_vault_auth.outputs.gitea_vault_jwt }} role: gitea_cicd_ # ← le rôle JWT de l'app (étape 3) method: jwt path: gitea_jwt secrets: | kvv1/google/credentials credentials | GOOGLE_BACKEND_CREDENTIALS ; kvv1/gitea/tofu_module_reader ssh_private_key | TERRAFORM_SSH_KEY ; - uses: actions/checkout@v4 - name: terraform apply uses: dflook/terraform-apply@v1 with: { path: iac, auto_approve: true } ``` Les deux secrets lus servent au backend (clé GCS `GOOGLE_BACKEND_CREDENTIALS`) et au clone du module partagé en SSH (`TERRAFORM_SSH_KEY`, cf. [étape 5](05-app-terraform.md)). > [!WARNING] > **Piège du `role:` copié-collé.** Le `role:` du step `vault-action` **et** le `role` de `iac/providers.tf` doivent tous deux être `gitea_cicd_`. L'exemple `erp` porte encore `role: gitea_cicd_webapp` dans son [`vault.yaml`](https://gitea.arcodange.lab/arcodange-org/erp/src/branch/main/.gitea/workflows/vault.yaml) (reliquat de copier-coller) alors que son `providers.tf` utilise bien `gitea_cicd_erp`. Vérifie et aligne sur le nom de **ton** app, sinon la CI lit/écrit avec la mauvaise identité. ## `dockerimage.yaml` — construire l'image (si image maison) À n'ajouter **que** si l'app build sa propre image (pas pour une image publique comme `erp`/Dolibarr). Déclenché au push sur `main`, en ignorant `README.md` et `chart/**` (changer le chart ne reconstruit pas l'image). ```yaml on: push: { branches: [main], paths-ignore: ['README.md', 'chart/**'] } jobs: build-and-push-image: steps: - uses: docker/login-action@v3 with: registry: gitea.arcodange.lab username: ${{ github.actor }} password: ${{ secrets.PACKAGES_TOKEN }} # secret d'org (étape 1) - uses: actions/checkout@v4 - run: | TAGS="latest ${{ github.ref_name }}" docker build -t app . for TAG in $TAGS; do docker tag app gitea.arcodange.lab/${{ github.repository }}:$TAG docker push gitea.arcodange.lab/${{ github.repository }}:$TAG done ``` L'image atterrit donc en `gitea.arcodange.lab/arcodange-org/:latest` — exactement ce que `image.repository` du chart référence ([étape 4](04-helm-chart.md)). Un `Dockerfile` multi-stage à la racine convient (cf. [`webapp/Dockerfile`](https://gitea.arcodange.lab/arcodange-org/webapp/src/branch/main/Dockerfile)). ## Vue d'ensemble ```mermaid %%{init: {'theme': 'base'}}%% flowchart TB classDef ci fill:#059669,stroke:#047857,color:#fff classDef out fill:#7c3aed,stroke:#6d28d9,color:#fff PUSH["push sur main"]:::ci PUSH -->|"iac/*.tf modifié"| TF["vault.yaml
OIDC → JWT → tofu apply iac/"]:::ci PUSH -->|"code modifié"| IMG["dockerimage.yaml
build + push image"]:::ci TF --> VR["creds/‹app› + rôle K8s ‹app› + KV"]:::out IMG --> REG["registre gitea.arcodange.lab/arcodange-org/‹app›"]:::out ``` ## Déploiement automatique sur nouvelle image Pour qu'ArgoCD redéploie quand une nouvelle image est poussée, on n'ajoute **rien** dans la CI : ce sont les annotations `argocd-image-updater` posées à l'[étape 7](07-argocd-register.md) (stratégie `digest`) qui surveillent le tag `latest`. ## Notes / contraintes - `concurrency: cancel-in-progress` est activé sur les deux workflows : un nouveau push annule le run précédent sur la même ref. - Le `vault-action` est lui-même un dépôt Gitea (`arcodange-org/vault-action`) épinglé `@main`. ## Related - [3. Vault plateforme](03-vault-platform.md) — d'où vient `gitea_cicd_`. - [5. Terraform de l'app](05-app-terraform.md) — ce que `vault.yaml` applique. - [4. Chart Helm](04-helm-chart.md) — `image.repository` = l'image poussée ici. - [7. Enregistrement ArgoCD](07-argocd-register.md) — déploie, et porte les annotations d'auto-update.