Skip to Content
Mélodium 0.10.1 is now available!
DocsExemplesPipeline CI

Pipeline CI

Source: 16_ci_pipeline

Un pipeline CI en trois étapes s’exécutant entièrement sur des conteneurs cloud provisionnés : build (binaire Rust en release), test (cargo test avec un sidecar Postgres), package (archive tar.gz). Les étapes 1 et 2 s’exécutent en parallèle ; l’étape 3 ne démarre qu’après la fin des deux.

Exécution

melodium run 16_ci_pipeline/Compo.toml \ --api_token "my-api-token" \ --repo_url "https://github.com/my-org/my-project.git"
[…] info: ci: pipeline started […] info: build: build succeeded […] info: test: all tests passed […] info: ci: pipeline complete — artifact written

Fonctionnement

Un seul modèle CicdDispatchEngine gère toute l’infrastructure :

model Dispatcher(const api_token: string) : CicdDispatchEngine { api_token = |wrap<string>(api_token) }

Chaque étape est un sous-traitement encapsulant simpleStep ou simpleStepWithInput, qui abstraient le provisionnement, l’exécution, les E/S de fichiers et le nettoyage en un seul appel.

Étapes concurrentes avec fork-join

Les étapes 1 et 2 démarrent toutes les deux depuis startup.trigger :

startup.trigger -> build.trigger startup.trigger -> test.trigger

L’étape 3 attend que les deux se terminent grâce à flock<void>(), qui collecte deux signaux Block<void> et émet un Stream<void> une fois les deux reçus. Un trigger<void>() convertit ce flux en un seul Block<void> pour déclencher package :

bothFinished: flock<void>() build.finished -> bothFinished.a test.finished -> bothFinished.b bothTrigger: trigger<void>() bothFinished.stream -> bothTrigger.stream bothTrigger.start -> package.trigger
See in Compositeur Studio

Binaire pipé entre les étapes

Le binaire compilé produit par l’étape 1 est pipé directement dans l’étape 3 sans passer par le disque local :

build.data -> package.data

simpleStepWithInput stream les octets reçus dans /mnt/data/binary sur le conteneur distant avant d’exécuter les commandes.

Sidecar de service

L’étape test attache un conteneur Postgres 16 comme sidecar accessible par le nom d’hôte postgres :

service_containers = [ |service_container( "postgres", 512, 1000, 2048, |amd64(), [], "postgres:16", _, |wrap<StringMap>(|map([ |entry<string>("POSTGRES_USER", "ci"), |entry<string>("POSTGRES_PASSWORD", "ci"), |entry<string>("POSTGRES_DB", "ci_test") ])), _ ) ]

DATABASE_URL est définie sur postgres://ci:ci@postgres/ci_test dans l’environnement du conteneur de test.

Fusion des erreurs

Si l’étape 1 ou 2 échoue ou produit une erreur, un message est journalisé et l’étape 3 se déclenche quand même (sur bothFinished) — permettant au pipeline de continuer jusqu’à la tentative de packaging. Pour annuler à la place, connectez oneAnyFailed.value à un traitement qui annule le pipeline explicitement.

Dépendances

[dependencies] std = "0.10.1" # flux de base, journalisation, structures de données fs = "0.10.1" # lecture/écriture de fichiers locaux process = "0.10.1" # exécution de commandes shell work = "0.10.1" # provisionnement de runners cloud distrib = "0.10.1" # distribution de flux entre runners cicd = "0.10.1" # dispatch et orchestration d'étapes CI/CD