Comprendre la CI Dagger : Easy Mode vs Power Mode¶
Ce que vous allez comprendre¶
- Analyser pourquoi Dagger a été choisi comme moteur CI plutôt qu'une CI YAML classique.
- Comparer Easy Mode (
.gitrust-ci.yml) et Power Mode (.dagger/) et évaluer quand basculer de l'un à l'autre. - Décrire les garanties d'isolation et de reproductibilité offertes par Dagger.
Le problème concret¶
Une CI traditionnelle (GitHub Actions, GitLab CI) exécute des étapes dans un environnement partagé. Deux problèmes fréquents :
- Manque de reproductibilité : « ça passe sur ma machine mais pas en CI » parce que les versions d'outils diffèrent.
- Couplage fort : un pipeline GitLab CI est indissociable de GitLab. Migrer vers une autre plateforme = réécrire tous les pipelines.
L'analogie¶
Dagger, c'est comme Docker pour les pipelines CI : chaque étape s'exécute dans un container isolé, avec des dépendances déclarées et des caches portables. Le pipeline peut tourner identiquement sur votre machine, sur le serveur gitrust, ou sur n'importe quel autre runner qui a Docker installé.
L'analogie avec Docker/Kubernetes est directe : - Docker résout « ça marche sur ma machine » pour les applications. - Dagger résout « ça marche sur ma machine » pour les pipelines.
Le modèle¶
Architecture gitrust CI¶
flowchart LR
Push[git push] --> Hook[receive-pack\nhook]
Hook --> Detect{Détection\nfichier CI}
Detect -->|".gitrust-ci.yml"| Easy[Easy Mode\nDagger générique]
Detect -->|".dagger/"| Power[Power Mode\nModule utilisateur]
Detect -->|Aucun| None[Pas de CI]
Easy --> Worker[CI Worker\nSémaphore N]
Power --> Worker
Worker --> Dagger[dagger call ...]
Dagger --> Logs[Logs DB + SSE]
Logs --> UI[Page pipeline\n/{owner}/{repo}/ci]
La détection est prioritaire : si .dagger/ et .gitrust-ci.yml coexistent, le Power Mode prend la priorité.
Easy Mode — .gitrust-ci.yml¶
Un fichier YAML simple décrit le pipeline. Le moteur Dagger générique de la plateforme l'interprète.
# .gitrust-ci.yml — exemple pour un projet Rust
build:
command: cargo build --release
cache:
- path: ~/.cargo/registry
key: cargo-registry
test:
command: cargo test --workspace
requires_build: true
checks:
- name: fmt
command: cargo fmt --all -- --check
- name: clippy
command: cargo clippy --workspace -- -D warnings
Avantages : - Accessible à tout utilisateur sans connaissance de Dagger. - Standardisé : tous les projets Easy Mode ont la même structure. - Zéro configuration côté plateforme.
Limites : - Pas de logique conditionnelle complexe. - Pas d'accès au Daggerverse (modules Dagger communautaires). - Pas de tests unitaires du pipeline lui-même. - Pas de composition (appeler un module depuis un autre).
Power Mode — .dagger/¶
Le dépôt contient un vrai module Dagger (Go, Python, ou TypeScript) :
// .dagger/main.go — exemple Go
package main
import (
"dagger/gitrust-ci/internal/dagger"
)
type GitrustCi struct{}
func (m *GitrustCi) Test(ctx context.Context, source *dagger.Directory) (string, error) {
return dag.Container().
From("rust:1.77-slim").
WithMountedDirectory("/src", source).
WithWorkdir("/src").
WithExec([]string{"cargo", "test", "--workspace"}).
Stdout(ctx)
}
Gitrust exécute : dagger call -m .dagger/ test --source=.
Avantages : - Logique conditionnelle arbitraire (Go/Python/TS complet). - Accès au Daggerverse : réutiliser des modules existants (Helm, SBOM, Trivy...). - Tests unitaires du pipeline possible (fonctions Dagger sont du vrai code). - Composition : un module peut appeler un autre module. - Isolation totale garantie par les containers Dagger. - Type-safety : le compilateur Go/TS vérifie les appels.
Limites : - Courbe d'apprentissage : il faut écrire du code Go/Python/TS. - Chaque équipe maintient son propre module.
Quand basculer de Easy Mode vers Power Mode ?¶
flowchart TD
Q1{Pipeline simple ?\nbuild + test + lint}
Q1 -->|Oui| Easy[Rester en Easy Mode]
Q1 -->|Non| Q2{Logique conditionnelle ?\nex: déployer seulement sur main}
Q2 -->|Oui| Power[Passer en Power Mode]
Q2 -->|Non| Q3{Composition avec\nd'autres modules Dagger ?}
Q3 -->|Oui| Power
Q3 -->|Non| Q4{Tests du pipeline\nlui-même ?}
Q4 -->|Oui| Power
Q4 -->|Non| Easy
Règle pratique : si votre .gitrust-ci.yml commence à ressembler à un programme avec des if/else imbriqués, c'est le moment de passer en Power Mode.
Tableau comparatif¶
| Critère | Easy Mode (YAML) | Power Mode (Dagger natif) |
|---|---|---|
| Accessibilité | Excellent | Courbe d'apprentissage |
| Puissance | Limitée | Illimitée |
| Testabilité du pipeline | Nulle | Totale |
| Composition (Daggerverse) | Non | Oui |
| Portabilité | Via le moteur gitrust | Native (tout runner Dagger) |
| Alignement philosophie Dagger | Partiel (YAML = anti-pattern) | Total |
| Maintenance plateforme | Le moteur évolue | Chaque repo est autonome |
Position philosophique de Dagger¶
Dagger a été créé explicitement contre le modèle YAML des CI traditionnelles par l'équipe fondatrice de Docker. Le YAML Easy Mode de gitrust est un compromis assumé : on sacrifie la pureté philosophique pour l'accessibilité des 90 % de cas simples. Le YAML Easy Mode ne doit jamais essayer de tout couvrir — dès que la complexité augmente, le Power Mode est la bonne réponse.
Alternatives et compromis¶
Pourquoi pas GitHub Actions ou GitLab CI directement ? Ces systèmes sont couplés à leur plateforme. Un pipeline GitHub Actions ne tourne pas localement sans outil tiers (act). Dagger tourne identiquement en local, sur le runner gitrust, et sur GitHub Actions si nécessaire.
Pourquoi pas Jenkins/Tekton ? L'objectif de gitrust est l'auto-hébergement simple pour des équipes de 3-20 personnes. Ces outils ajoutent une complexité d'administration disproportionnée.
Vérifier votre compréhension¶
-
Un développeur a un
.gitrust-ci.ymlavec 15 étapes et desskip_ifconditionnels simulés via des scripts shell. Doit-il rester en Easy Mode ? Justifiez. -
Quelle propriété de Dagger garantit qu'un pipeline Power Mode qui passe en local passera aussi sur le runner gitrust ? Comment cette propriété est-elle implémentée techniquement ?