Merge remote-tracking branch 'origin/main' into arcodange/mirror-depots-perso
# Conflicts: # ansible/arcodange/factory/inventory/group_vars/all/gitea.yml
This commit is contained in:
@@ -48,3 +48,41 @@ gitea_mirrored_repos:
|
|||||||
# l'ID du namespace « arcodange » sur gitlab.com (Settings → General) : sans lui,
|
# l'ID du namespace « arcodange » sur gitlab.com (Settings → General) : sans lui,
|
||||||
# la création GitLab retomberait dans le groupe arcodange-org.
|
# la création GitLab retomberait dans le groupe arcodange-org.
|
||||||
gitlab_personal_namespace_id: ~
|
gitlab_personal_namespace_id: ~
|
||||||
|
|
||||||
|
# ══════════════════════════════════════════════════════════════════════════
|
||||||
|
# VERSION DU RUNNER GITEA ACTIONS — ÉPINGLÉE, ET C'EST LE POINT.
|
||||||
|
#
|
||||||
|
# Le playbook 03_cicd déployait `gitea/act_runner:latest` avec `pull: missing`,
|
||||||
|
# c'est-à-dire la pire combinaison possible : un tag FLOTTANT qui n'est JAMAIS
|
||||||
|
# rafraîchi. Chaque hôte garde ce que « latest » voulait dire le jour de son
|
||||||
|
# premier pull — d'où deux machines censées être équivalentes qui divergent
|
||||||
|
# (constaté le 2026-07-30) :
|
||||||
|
#
|
||||||
|
# pi1 : sha256:7bdc8d31… → act_runner v0.3.1
|
||||||
|
# pi3 : sha256:0f65fa10… → act_runner v0.2.13
|
||||||
|
#
|
||||||
|
# Effet mesuré : le MÊME job, sur la MÊME image de CI, met 511 s sur pi1 et
|
||||||
|
# 397 s sur pi3 — 114 s d'écart imputables à la machine. Et pi3 (v0.2.13) a mal
|
||||||
|
# lu la définition d'un job dont il dépendait (« 'runs-on' key not defined »,
|
||||||
|
# puis « No steps found »).
|
||||||
|
#
|
||||||
|
# ⚠ NE PAS remplacer par `latest` + `pull: always` : `latest` vaut aujourd'hui
|
||||||
|
# 0.6.1, soit 3 à 4 versions mineures devant tout ce qui est éprouvé ici. Le
|
||||||
|
# runner exécute TOUTE la CI de la forge — une montée subie, non datée et non
|
||||||
|
# choisie, s'y paie cher. Une version épinglée se relit, se date et se recule.
|
||||||
|
# ⚠ L'IMAGE A CHANGÉ DE NOM. `gitea/act_runner` est gelée à 0.6.1 ; le
|
||||||
|
# successeur officiel est `gitea/runner`, et son binaire s'appelle désormais
|
||||||
|
# `gitea-runner` (plus `act_runner`).
|
||||||
|
# Vérifié avant de basculer — c'est un REMPLACEMENT DIRECT pour ce compose :
|
||||||
|
# • entrypoint identique : /sbin/tini -- run.sh
|
||||||
|
# • mêmes variables lues : CONFIG_FILE, GITEA_INSTANCE_URL,
|
||||||
|
# GITEA_RUNNER_{REGISTRATION_TOKEN,NAME,LABELS}
|
||||||
|
# • config.yaml compatible : capacity, labels, cache.*, container.force_pull,
|
||||||
|
# options, valid_volumes, host.workdir_parent — AUCUNE clé utilisée ici n'a
|
||||||
|
# disparu (comparé à `gitea-runner generate-config` de la 2.3.0).
|
||||||
|
# Le blog de Gitea 1.27 recommande « Gitea Runner 2.0.0 » ; 2.3.0 est la même
|
||||||
|
# lignée majeure, en plus récent. Gitea reste par ailleurs compatible fil-à-fil
|
||||||
|
# avec les runners plus anciens — il désactive simplement les fonctionnalités
|
||||||
|
# qu'ils n'annoncent pas.
|
||||||
|
gitea_runner_image: "gitea/runner"
|
||||||
|
gitea_runner_version: "2.3.0"
|
||||||
|
|||||||
@@ -1,4 +1,13 @@
|
|||||||
gitea_version: 1.25.5
|
# ⚠ Montée 1.25.5 → 1.27.1 : DEUX versions mineures, avec migrations de base
|
||||||
|
# IRRÉVERSIBLES (Gitea ne sait pas redescendre après migration). Sauvegardes du
|
||||||
|
# jour vérifiées avant la bascule (pg_dumpall 13 Mo intègre + archive fichiers
|
||||||
|
# 1,7 Go intègre, /mnt/backups).
|
||||||
|
# Changements cassants relevés dans les notes de version, et leur portée ICI :
|
||||||
|
# • workflows réutilisables externes retirés → AUCUN dans nos trois dépôts (vérifié)
|
||||||
|
# • nonce CSP exigé pour les scripts inline → concerne les templates
|
||||||
|
# personnalisés ; nous n'en avons pas
|
||||||
|
# • X-Content-Type-Options: nosniff par défaut
|
||||||
|
gitea_version: 1.27.1
|
||||||
|
|
||||||
gitea_database:
|
gitea_database:
|
||||||
db_name: gitea
|
db_name: gitea
|
||||||
|
|||||||
@@ -5,6 +5,13 @@
|
|||||||
|
|
||||||
roles:
|
roles:
|
||||||
- arcodange.factory.gitea_token # generate gitea_api_token used to replace generated token with set name if required
|
- arcodange.factory.gitea_token # generate gitea_api_token used to replace generated token with set name if required
|
||||||
|
# Image de base des jobs CI lourds (Node + Bun + Chromium), construite ICI,
|
||||||
|
# sur chaque machine à runner, puis épinglée contre le ramasse-miettes Docker.
|
||||||
|
# Le même groupe d'hôtes que le runner, et ce n'est pas un détail : avec
|
||||||
|
# `capacity: 1` (ci-dessous), le parallélisme vient de PLUSIEURS machines, et
|
||||||
|
# `container:` est résolu par le runner — un job qui atterrit là où l'image
|
||||||
|
# manque échoue AVANT sa première étape.
|
||||||
|
- arcodange.factory.ci_base_image
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
|
|
||||||
@@ -23,7 +30,14 @@
|
|||||||
name: arcodange_factory_gitea_action
|
name: arcodange_factory_gitea_action
|
||||||
services:
|
services:
|
||||||
gitea_action:
|
gitea_action:
|
||||||
image: gitea/act_runner:latest
|
# ⚠ VERSION ÉPINGLÉE (inventory/group_vars/all/gitea.yml), PAS `latest`.
|
||||||
|
# `latest` + `pull: missing` = tag flottant JAMAIS rafraîchi : chaque
|
||||||
|
# hôte gardait ce que « latest » voulait dire à son premier pull, d'où
|
||||||
|
# pi1 en v0.3.1 et pi3 en v0.2.13 sur des machines censées être
|
||||||
|
# équivalentes (114 s d'écart mesurés sur le même job).
|
||||||
|
# Avec un tag épinglé, `pull: missing` redevient CORRECT : changer la
|
||||||
|
# version change le tag, donc l'image est absente, donc elle est tirée.
|
||||||
|
image: "{{ gitea_runner_image }}:{{ gitea_runner_version }}"
|
||||||
container_name: gitea_action
|
container_name: gitea_action
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
@@ -32,7 +46,7 @@
|
|||||||
http://{{ hostvars[groups.gitea[0]].ansible_host }}:3000
|
http://{{ hostvars[groups.gitea[0]].ansible_host }}:3000
|
||||||
GITEA_RUNNER_REGISTRATION_TOKEN: "{{ gitea_runner_token_cmd.stdout }}"
|
GITEA_RUNNER_REGISTRATION_TOKEN: "{{ gitea_runner_token_cmd.stdout }}"
|
||||||
GITEA_RUNNER_NAME: arcodange_global_runner_{{ inventory_hostname }}
|
GITEA_RUNNER_NAME: arcodange_global_runner_{{ inventory_hostname }}
|
||||||
GITEA_RUNNER_LABELS: ubuntu-latest:docker://gitea.arcodange.lab/arcodange-org/runner-images:ubuntu-latest-ca,ubuntu-latest-ca:docker://gitea.arcodange.lab/arcodange-org/runner-images:ubuntu-latest-ca
|
GITEA_RUNNER_LABELS: ubuntu-latest:docker://gitea.arcodange.lab/arcodange-org/runner-images:ubuntu-latest-ca,ubuntu-latest-ca:docker://gitea.arcodange.lab/arcodange-org/runner-images:ubuntu-latest-ca,ci-node-playwright:docker://ci-node-playwright:latest
|
||||||
ports:
|
ports:
|
||||||
- "43707:43707"
|
- "43707:43707"
|
||||||
networks:
|
networks:
|
||||||
@@ -91,6 +105,15 @@
|
|||||||
labels:
|
labels:
|
||||||
- "ubuntu-latest:docker://gitea.arcodange.lab/arcodange-org/runner-images:ubuntu-latest-ca"
|
- "ubuntu-latest:docker://gitea.arcodange.lab/arcodange-org/runner-images:ubuntu-latest-ca"
|
||||||
- "ubuntu-latest-ca:docker://gitea.arcodange.lab/arcodange-org/runner-images:ubuntu-latest-ca"
|
- "ubuntu-latest-ca:docker://gitea.arcodange.lab/arcodange-org/runner-images:ubuntu-latest-ca"
|
||||||
|
# Jobs CI lourds (Node + Bun + Chromium préinstallés) —
|
||||||
|
# image construite LOCALEMENT par le rôle ci_base_image, sur
|
||||||
|
# cette machine. Elle n'est volontairement PAS dans le
|
||||||
|
# registre : 3,81 Go dont une couche de 1,36 Go, dont le
|
||||||
|
# push casse en « connection reset by peer » (mesuré
|
||||||
|
# 2026-07-29, kadans#225). `force_pull: false` ci-dessous
|
||||||
|
# est donc REQUIS pour ce label — sans lui, act_runner
|
||||||
|
# tenterait un pull et échouerait.
|
||||||
|
- "ci-node-playwright:docker://ci-node-playwright:latest"
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
# Enable cache server to use actions/cache.
|
# Enable cache server to use actions/cache.
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
---
|
||||||
|
# Image de base des jobs CI lourds (Node + Bun + Chromium), construite SUR CHAQUE
|
||||||
|
# machine qui héberge un runner Gitea.
|
||||||
|
#
|
||||||
|
# POURQUOI CONSTRUIRE PLUTÔT QUE POUSSER (mesuré le 2026-07-29, kadans#224/#225) :
|
||||||
|
# une image Node + Playwright + Chromium pèse 3,81 Go, avec une couche unique de
|
||||||
|
# 1,36 Go. Son `docker push` vers gitea.arcodange.lab casse en
|
||||||
|
# « connection reset by peer » : 7 couches passent, 3 sont réinitialisées et
|
||||||
|
# retentées 50 fois avant abandon. À titre de comparaison,
|
||||||
|
# `runner-images:ubuntu-latest-ca` (534,7 Mo, plus grosse couche 261 Mo) passe
|
||||||
|
# sans problème — la limite est donc entre 261 Mo et ~500 Mo par couche.
|
||||||
|
#
|
||||||
|
# Construire localement supprime le problème : aucune couche ne traverse le
|
||||||
|
# réseau. Et comme `capacity: 1` par runner (03_cicd.yml), le parallélisme vient
|
||||||
|
# de PLUSIEURS machines — l'image doit donc exister sur CHACUNE d'elles, ce que
|
||||||
|
# ce rôle garantit.
|
||||||
|
|
||||||
|
# On hérite de l'image de runner maison : elle porte DÉJÀ le certificat de la CA
|
||||||
|
# interne (step-ca). Repartir de `node:20-bookworm` obligerait à réinjecter le CA
|
||||||
|
# à la main, et un job qui parle à gitea.arcodange.lab échouerait en TLS.
|
||||||
|
ci_base_image_from: gitea.arcodange.lab/arcodange-org/runner-images:ubuntu-latest-ca
|
||||||
|
|
||||||
|
ci_base_image_name: ci-node-playwright
|
||||||
|
ci_base_image_tag: latest
|
||||||
|
|
||||||
|
# ⚠ Ces versions doivent suivre le `bun.lock` du dépôt kadans. Le dépôt s'en
|
||||||
|
# protège : l'image écrit ce qu'elle a cuit dans /etc/ci-base.versions, et la CI
|
||||||
|
# de kadans CONFRONTE ce fichier à son lockfile pour échouer FORT plutôt que de
|
||||||
|
# dériver en silence (des navigateurs qui ne correspondent plus au client
|
||||||
|
# Playwright donnent « Executable doesn't exist », loin de la cause).
|
||||||
|
ci_base_image_bun_version: '1.3.14'
|
||||||
|
ci_base_image_playwright_version: '1.61.1'
|
||||||
|
|
||||||
|
# ⚠ NODE 20 EST OBLIGATOIRE, ET CE N'EST PAS UN CONFORT.
|
||||||
|
# `runner-images:ubuntu-latest-ca` livre Node **18** (v18.20.8, constaté en
|
||||||
|
# lançant l'image). Or `nuxi` importe `node:util.styleText`, absent de Node 18 :
|
||||||
|
# c'est la raison d'être du `container: node:20-bookworm` que portait la CI de
|
||||||
|
# kadans, et que son CLAUDE.md interdit de retirer. Sans cette surcharge, tout
|
||||||
|
# job Nuxt basculé sur cette image casse au premier build, sur un message qui
|
||||||
|
# parle d'un import introuvable et jamais d'une version de Node.
|
||||||
|
ci_base_image_node_major: 20
|
||||||
|
|
||||||
|
# Épinglage par conteneur factice — remède décrit par
|
||||||
|
# docs/adr/20260407-docker-storage-gitea-runner.md §1, jusqu'ici resté à l'état
|
||||||
|
# de proposition (system_docker.yml n'applique que le data-root et les log-opts).
|
||||||
|
# Sans lui, le ramasse-miettes de Docker supprime l'image dès que le disque se
|
||||||
|
# remplit, et la CI casse sur une image manquante — panne déjà constatée sur les
|
||||||
|
# images de runner elles-mêmes.
|
||||||
|
ci_base_image_pin: true
|
||||||
|
|
||||||
|
# Où le contexte de build est déposé SUR LA MACHINE CIBLE. `docker_image_build`
|
||||||
|
# s'exécute sur la cible : son `path:` est un chemin de la cible, jamais du
|
||||||
|
# contrôleur. (Première version : `{{ role_path }}/files/` → le playbook mourait
|
||||||
|
# sur « is not an existing directory », sur les deux hôtes.)
|
||||||
|
ci_base_image_contexte: /tmp/ci-base-image
|
||||||
|
|
||||||
|
# Reconstruire même si l'image existe déjà. ⚠ Inutile pour un simple changement
|
||||||
|
# du Dockerfile : le rôle le détecte et reconstruit tout seul (voir tasks/).
|
||||||
|
# Ce drapeau sert aux cas 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.
|
||||||
|
ci_base_image_force_rebuild: false
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
# Image de base des jobs CI lourds — construite SUR CHAQUE machine à runner.
|
||||||
|
#
|
||||||
|
# Elle cuit une fois pour toutes ce que chaque exécution de CI réinstallait.
|
||||||
|
# Mesures du dépôt kadans (run 628, 2026-07-29, runner ARM64 2 vCPU / 3 Gio) :
|
||||||
|
#
|
||||||
|
# npm install -g bun → 8,6 s par run
|
||||||
|
# playwright install --with-deps chromium → 104,0 s par run (apt-get)
|
||||||
|
# ────────
|
||||||
|
# 112,6 s jetées à CHAQUE run,
|
||||||
|
# sur le job du chemin critique
|
||||||
|
#
|
||||||
|
# Le cache `actions/cache` ne peut rien contre ces 104 s : il couvre le
|
||||||
|
# NAVIGATEUR (299 Mo déjà mis en cache), pas ses dépendances SYSTÈME —
|
||||||
|
# `--with-deps` relance `apt-get` quoi qu'il arrive.
|
||||||
|
#
|
||||||
|
# ⚠ ON HÉRITE DE L'IMAGE DE RUNNER MAISON, ET C'EST ESSENTIEL : elle porte le
|
||||||
|
# certificat de la CA interne (step-ca). Une image repartant de `node:20-bookworm`
|
||||||
|
# ne ferait pas confiance à gitea.arcodange.lab, et tout job qui lui parle
|
||||||
|
# échouerait en TLS.
|
||||||
|
ARG CI_BASE_FROM=gitea.arcodange.lab/arcodange-org/runner-images:ubuntu-latest-ca
|
||||||
|
FROM ${CI_BASE_FROM}
|
||||||
|
|
||||||
|
ARG BUN_VERSION=1.3.14
|
||||||
|
ARG PLAYWRIGHT_VERSION=1.61.1
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
# Chemin des navigateurs, figé et hors du HOME : un job qui tourne sous un autre
|
||||||
|
# utilisateur doit les retrouver.
|
||||||
|
ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright
|
||||||
|
|
||||||
|
# ══════════════════════════════════════════════════════════════════════════
|
||||||
|
# ⚠ TROIS `RUN` SÉPARÉS, ET C'EST LE POINT DE CONCEPTION DE CE FICHIER.
|
||||||
|
#
|
||||||
|
# La première version faisait `npm i -g bun` puis `playwright install --with-deps`
|
||||||
|
# en deux couches, dont une de 1,36 Go — irrecevable par le registre. Ici, même
|
||||||
|
# si l'on décidait un jour de pousser cette image, chaque couche reste du même
|
||||||
|
# ordre de grandeur que celles qui passent déjà (261 Mo pour la plus grosse de
|
||||||
|
# `runner-images:ubuntu-latest-ca`).
|
||||||
|
#
|
||||||
|
# Ne pas fusionner ces `RUN` pour « gagner une couche » : le gain serait nul et
|
||||||
|
# la couche redeviendrait impossible à transporter.
|
||||||
|
# ══════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
# 0. NODE 20, ET C'EST OBLIGATOIRE — pas une préférence.
|
||||||
|
#
|
||||||
|
# ⚠ `runner-images:ubuntu-latest-ca` livre **Node 18** (v18.20.8, vérifié en le
|
||||||
|
# lançant). Or `nuxi` importe `node:util.styleText`, ABSENT de Node 18 : c'est la
|
||||||
|
# raison d'être du `container: node:20-bookworm` que la CI de kadans portait, et
|
||||||
|
# que son `CLAUDE.md` interdit explicitement de retirer.
|
||||||
|
#
|
||||||
|
# Sans cette couche, une CI qui bascule sur cette image casse au premier `nuxt
|
||||||
|
# build` — et le message parle d'un import introuvable, pas d'une version de Node.
|
||||||
|
# Le défaut a été trouvé en CONSTRUISANT l'image puis en lançant `node --version`
|
||||||
|
# dedans ; aucune lecture du Dockerfile ne l'aurait montré.
|
||||||
|
# ⚠⚠ ET INSTALLER NE SUFFIT PAS — il faut aussi que `node` RÉSOLVE vers le bon.
|
||||||
|
# Constaté en lançant l'image : après l'installation de Node 20 par apt,
|
||||||
|
# `node --version` rendait toujours **v18.20.8**, parce que l'image de base
|
||||||
|
# précuit un node pour le toolcache d'act et le met EN TÊTE du PATH :
|
||||||
|
#
|
||||||
|
# which node → /opt/acttoolcache/node/18.20.8/arm64/bin/node
|
||||||
|
# PATH → /opt/acttoolcache/node/18.20.8/arm64/bin:/usr/local/sbin:/usr/bin:…
|
||||||
|
# /usr/bin/node --version → v20.20.2 ← le bon, mais il PERD
|
||||||
|
#
|
||||||
|
# On retire donc l'entrée 18 du toolcache : le segment de PATH devient inexistant
|
||||||
|
# (inoffensif) et la résolution retombe sur /usr/bin/node, en 20.
|
||||||
|
# ⚠ Conséquence assumée : `actions/setup-node` ne trouvera plus de Node 18
|
||||||
|
# préinstallé dans cette image. Aucun workflow de kadans ne l'utilise, et l'image
|
||||||
|
# n'est servie qu'aux jobs qui DEMANDENT le label `ci-node-playwright`.
|
||||||
|
ARG NODE_MAJOR=20
|
||||||
|
RUN curl -fsSL "https://deb.nodesource.com/setup_${NODE_MAJOR}.x" -o /tmp/nodesource.sh \
|
||||||
|
&& bash /tmp/nodesource.sh \
|
||||||
|
&& apt-get install -y --no-install-recommends nodejs \
|
||||||
|
&& rm -f /tmp/nodesource.sh \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
|
&& rm -rf /opt/acttoolcache/node \
|
||||||
|
&& echo "node résolu : $(which node) $(node --version)" \
|
||||||
|
&& node --version | grep -q "^v${NODE_MAJOR}\."
|
||||||
|
|
||||||
|
# 1. Bun (~180 Mo) — installé APRÈS Node 20, pour que son npm global soit celui
|
||||||
|
# de Node 20 et non celui de Node 18.
|
||||||
|
RUN npm install -g "bun@${BUN_VERSION}" \
|
||||||
|
&& npm cache clean --force
|
||||||
|
|
||||||
|
# 2. Les dépendances SYSTÈME de Chromium — c'est CETTE couche qui rachète les
|
||||||
|
# 104 s d'apt-get de chaque run.
|
||||||
|
RUN npx --yes "playwright@${PLAYWRIGHT_VERSION}" install-deps chromium \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# 3. Le navigateur lui-même, séparé de ses dépendances système : les deux ne
|
||||||
|
# bougent pas au même rythme, et Docker ne réinvalide alors que la bonne.
|
||||||
|
RUN npx --yes "playwright@${PLAYWRIGHT_VERSION}" install chromium
|
||||||
|
|
||||||
|
# La trace opposable de ce qui est réellement cuit ici. La CI de kadans la LIT et
|
||||||
|
# la confronte à son `bun.lock` : une dérive de version doit échouer FORT, avec sa
|
||||||
|
# cause, plutôt que de se manifester par un « Executable doesn't exist » à
|
||||||
|
# vingt minutes de là.
|
||||||
|
RUN printf 'node=%s\nbun=%s\nplaywright=%s\n' \
|
||||||
|
"$(node --version)" "$(bun --version)" "${PLAYWRIGHT_VERSION}" \
|
||||||
|
> /etc/ci-base.versions \
|
||||||
|
&& cat /etc/ci-base.versions
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
---
|
||||||
|
# Construit l'image de base des jobs CI sur la machine courante, puis l'épingle.
|
||||||
|
#
|
||||||
|
# À exécuter sur les MÊMES hôtes que le runner Gitea (03_cicd.yml) : comme
|
||||||
|
# `capacity: 1`, le parallélisme vient de plusieurs machines, et un job qui
|
||||||
|
# atterrit sur une machine sans l'image échouerait AVANT sa première étape —
|
||||||
|
# `runs-on`/`container:` est résolu par le runner, pas par le workflow.
|
||||||
|
|
||||||
|
# ══════════════════════════════════════════════════════════════════════════
|
||||||
|
# ⚠ LE CONTEXTE DE BUILD DOIT ÊTRE SUR LA MACHINE, PAS SUR LE CONTRÔLEUR.
|
||||||
|
#
|
||||||
|
# `docker_image_build` s'exécute SUR LA CIBLE : son `path:` est un chemin de la
|
||||||
|
# cible. La première version passait `{{ role_path }}/files/` — un chemin du
|
||||||
|
# CONTRÔLEUR — et le playbook mourait sur les deux hôtes :
|
||||||
|
#
|
||||||
|
# "/Users/…/roles/ci_base_image/files/" is not an existing directory
|
||||||
|
#
|
||||||
|
# Le motif venait du rôle `playwright`, qui l'utilise LÉGITIMEMENT parce qu'il
|
||||||
|
# construit en local ; recopié tel quel pour un build distant, il ne peut pas
|
||||||
|
# marcher. On copie donc le contexte d'abord.
|
||||||
|
# ══════════════════════════════════════════════════════════════════════════
|
||||||
|
- name: Créer le répertoire de contexte de build sur la machine
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: '{{ ci_base_image_contexte }}'
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Déposer le Dockerfile sur la machine
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: Dockerfile
|
||||||
|
dest: '{{ ci_base_image_contexte }}/Dockerfile'
|
||||||
|
mode: '0644'
|
||||||
|
register: ci_base_image_dockerfile
|
||||||
|
|
||||||
|
- name: Construire {{ ci_base_image_name }}:{{ ci_base_image_tag }}
|
||||||
|
community.docker.docker_image_build:
|
||||||
|
name: '{{ ci_base_image_name }}'
|
||||||
|
tag: '{{ ci_base_image_tag }}'
|
||||||
|
path: '{{ ci_base_image_contexte }}'
|
||||||
|
# RECONSTRUCTION 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 — c'est ce qui rend l'ajout d'une bibliothèque
|
||||||
|
# effectif sans avoir à penser à un drapeau.
|
||||||
|
rebuild: >-
|
||||||
|
{{ "always"
|
||||||
|
if (ci_base_image_force_rebuild or ci_base_image_dockerfile is changed)
|
||||||
|
else "never" }}
|
||||||
|
args:
|
||||||
|
CI_BASE_FROM: '{{ ci_base_image_from }}'
|
||||||
|
NODE_MAJOR: '{{ ci_base_image_node_major }}'
|
||||||
|
BUN_VERSION: '{{ ci_base_image_bun_version }}'
|
||||||
|
PLAYWRIGHT_VERSION: '{{ ci_base_image_playwright_version }}'
|
||||||
|
register: ci_base_image_build
|
||||||
|
|
||||||
|
# ⚠ CE CONTENEUR NE TOURNE JAMAIS — il ne sert qu'à référencer l'image.
|
||||||
|
# Remède décrit par docs/adr/20260407-docker-storage-gitea-runner.md §1, resté
|
||||||
|
# jusqu'ici à l'état de proposition : `system_docker.yml` n'applique que le
|
||||||
|
# data-root sur disque externe et les log-opts. Sans épinglage, le ramasse-miettes
|
||||||
|
# de Docker supprime l'image dès que le disque se remplit — panne DÉJÀ constatée
|
||||||
|
# sur les images de runner elles-mêmes, et qui casse la CI de tous les dépôts.
|
||||||
|
#
|
||||||
|
# `state: present` (et non `started`) : Docker considère l'image comme utilisée
|
||||||
|
# tant qu'un conteneur la référence, même à l'arrêt. Aucun CPU, aucune mémoire.
|
||||||
|
- name: Épingler {{ ci_base_image_name }} contre le ramasse-miettes Docker
|
||||||
|
community.docker.docker_container:
|
||||||
|
name: 'pin-{{ ci_base_image_name }}'
|
||||||
|
image: '{{ ci_base_image_name }}:{{ ci_base_image_tag }}'
|
||||||
|
state: present
|
||||||
|
command: ['sh', '-c', 'sleep infinity']
|
||||||
|
auto_remove: false
|
||||||
|
restart_policy: 'no'
|
||||||
|
when: ci_base_image_pin
|
||||||
|
|
||||||
|
# Contrôle de sortie : on VÉRIFIE que l'image répond, plutôt que de supposer que
|
||||||
|
# le build a suffi. Une image construite mais dont `bun` n'est pas dans le PATH
|
||||||
|
# passerait le build et casserait tous les jobs.
|
||||||
|
- name: Vérifier que l'image livre bien Node {{ ci_base_image_node_major }}, bun et chromium
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: >-
|
||||||
|
docker run --rm {{ ci_base_image_name }}:{{ ci_base_image_tag }}
|
||||||
|
sh -c "node --version && bun --version && ls /ms-playwright && cat /etc/ci-base.versions"
|
||||||
|
register: ci_base_image_check
|
||||||
|
changed_when: false
|
||||||
|
# ⚠ La version de Node est VÉRIFIÉE, pas supposée : l'image de base en livre
|
||||||
|
# une trop ancienne (18), et une régression silencieuse ici casserait tout job
|
||||||
|
# Nuxt sur un message qui ne nomme pas la cause.
|
||||||
|
failed_when: >-
|
||||||
|
ci_base_image_check.rc != 0
|
||||||
|
or ('v' ~ ci_base_image_node_major ~ '.') not in ci_base_image_check.stdout
|
||||||
|
|
||||||
|
- name: Ce que l'image contient réellement
|
||||||
|
ansible.builtin.debug:
|
||||||
|
var: ci_base_image_check.stdout_lines
|
||||||
Reference in New Issue
Block a user