fix(ci_base_image) — le contexte de build doit être SUR la machine, pas sur le contrôleur #49

Merged
arcodange merged 1 commits from arcodange/image-ci-build-distant into main 2026-07-29 23:51:23 +02:00
Owner

Corrige un défaut de factory#48 trouvé au premier passage réel du playbook, et ajoute la reconstruction conditionnelle.

Le défaut

ansible-playbook 03_cicd.yml est mort sur les deux hôtes :

"/Users/…/collections/…/roles/ci_base_image/files/" is not an existing directory

community.docker.docker_image_build s'exécute sur la cible : son path: désigne un chemin de la cible. Je passais {{ role_path }}/files/, un chemin du contrôleur.

Le motif venait du rôle playwright, qui l'emploie légitimement parce qu'il construit en local. Recopié pour un build distant, il ne pouvait pas marcher — et aucune relecture ne l'aurait montré : --syntax-check passait, le YAML était valide. Seule l'exécution le dit.

L'échec est arrivé avant les tâches qui déploient les runners. Les deux sont restés Up 6 days, aucune CI cassée. Le seul effet fut un jeton d'API Gitea créé par le rôle gitea_token — son comportement normal à chaque passage. C'est la bonne propriété pour un playbook qui touche la CI de toute la forge.

Le correctif

Le contexte de build est déposé sur la machine (/tmp/ci-base-image, variable ci_base_image_contexte) avant le build.

Et la reconstruction devient conditionnelle

rebuild: never en régime normal — le playbook ne rebâtit pas 3,3 Go à chaque passage — mais always dès que le Dockerfile a changé sur la machine (ci_base_image_dockerfile is changed).

Ajouter une bibliothèque à l'image devient donc effectif sans avoir à penser à un drapeau. ci_base_image_force_rebuild reste utile pour ce que le Dockerfile ne montre pas — une montée de bun.lock côté kadans, par exemple, qui change les versions attendues sans changer le fichier.

Vérifié : le playbook passe, et l'image est là

pi1 et pi3 : ok=17 changed=8 failed=0.

pi1 pi3
image ci-node-playwright 3,34 Go 3,34 Go (construite par ce passage)
Node dans l'image v20.20.2 v20.20.2
bun / chromium / headless-shell / ffmpeg
conteneur d'épinglage Created Created
runner après recréation Up Up

La tâche de vérification relit les versions dans l'image sur chaque hôte (docker run … node --version && bun --version && ls /ms-playwright && cat /etc/ci-base.versions) et failed_when refuse une version de Node qui ne serait pas celle attendue — elle ne suppose rien.

Ce qui reste à éprouver

Que la CI de kadans consomme réellement l'image via le label ci-node-playwright. C'est l'objet de kadans#227, et ça se teste par un run déclenché sur sa branche — je le fais dans la foulée.

🤖 Generated with Claude Code

Corrige un défaut de `factory#48` trouvé **au premier passage réel** du playbook, et ajoute la reconstruction conditionnelle. ## Le défaut `ansible-playbook 03_cicd.yml` est mort sur les **deux** hôtes : ``` "/Users/…/collections/…/roles/ci_base_image/files/" is not an existing directory ``` `community.docker.docker_image_build` s'exécute **sur la cible** : son `path:` désigne un chemin de la **cible**. Je passais `{{ role_path }}/files/`, un chemin du **contrôleur**. Le motif venait du rôle `playwright`, qui l'emploie **légitimement** parce qu'il construit en local. Recopié pour un build distant, il ne pouvait pas marcher — et **aucune relecture ne l'aurait montré** : `--syntax-check` passait, le YAML était valide. Seule l'exécution le dit. > ✅ **L'échec est arrivé avant les tâches qui déploient les runners.** Les deux sont restés `Up 6 days`, aucune CI cassée. Le seul effet fut un jeton d'API Gitea créé par le rôle `gitea_token` — son comportement normal à chaque passage. C'est la bonne propriété pour un playbook qui touche la CI de toute la forge. ## Le correctif Le contexte de build est déposé sur la machine (`/tmp/ci-base-image`, variable `ci_base_image_contexte`) avant le build. ## Et la reconstruction devient conditionnelle `rebuild: never` en régime normal — le playbook ne rebâtit pas 3,3 Go à chaque passage — mais **`always` dès que le Dockerfile a changé sur la machine** (`ci_base_image_dockerfile is changed`). Ajouter une bibliothèque à l'image devient donc effectif **sans avoir à penser à un drapeau**. `ci_base_image_force_rebuild` reste utile pour ce que le Dockerfile ne montre pas — une montée de `bun.lock` côté `kadans`, par exemple, qui change les versions attendues sans changer le fichier. ## ✅ Vérifié : le playbook passe, et l'image est là `pi1` et `pi3` : `ok=17 changed=8 failed=0`. | | pi1 | pi3 | |---|---|---| | image `ci-node-playwright` | 3,34 Go | **3,34 Go** (construite par ce passage) | | Node **dans** l'image | **v20.20.2** | **v20.20.2** | | bun / chromium / headless-shell / ffmpeg | ✅ | ✅ | | conteneur d'épinglage | `Created` | `Created` | | runner après recréation | `Up` | `Up` | La tâche de vérification relit les versions **dans** l'image sur chaque hôte (`docker run … node --version && bun --version && ls /ms-playwright && cat /etc/ci-base.versions`) et `failed_when` refuse une version de Node qui ne serait pas celle attendue — elle ne suppose rien. ## Ce qui reste à éprouver Que la CI de `kadans` consomme réellement l'image via le label `ci-node-playwright`. C'est l'objet de [kadans#227](https://gitea.arcodange.lab/arcodange/kadans/pulls/227), et ça se teste par un run déclenché sur sa branche — je le fais dans la foulée. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
arcodange added 1 commit 2026-07-29 23:51:08 +02:00
Le playbook 03_cicd est mort sur les deux hôtes :

  "/Users/…/roles/ci_base_image/files/" is not an existing directory

`docker_image_build` s'exécute SUR LA CIBLE : son `path:` est un chemin de la
cible. Je passais `{{ role_path }}/files/`, un chemin du CONTRÔLEUR.

Le motif venait du rôle `playwright`, qui l'emploie LÉGITIMEMENT parce qu'il
construit en local. Recopié pour un build distant, il ne pouvait pas marcher —
et aucune relecture ne l'aurait montré, seule l'exécution le dit.

⚠ L'échec est arrivé AVANT les tâches qui déploient le runner : les deux
runners sont restés `Up 6 days`, rien n'a été cassé. Le seul effet fut un jeton
d'API Gitea créé par le rôle gitea_token, son comportement normal.

Le contexte est désormais déposé sur la machine (`/tmp/ci-base-image`), et la
RECONSTRUCTION DEVIENT CONDITIONNELLE : `never` en régime normal — le playbook
ne rebâtit pas 3,3 Go à chaque passage — mais `always` dès que le Dockerfile a
CHANGÉ sur la machine. Ajouter une bibliothèque devient donc effectif sans avoir
à penser à un drapeau.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
arcodange merged commit 1a8b6bf36c into main 2026-07-29 23:51:23 +02:00
arcodange deleted branch arcodange/image-ci-build-distant 2026-07-29 23:51:26 +02:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: arcodange-org/factory#49