21 Commits
Author SHA1 Message Date
arcodange 0cc8213bff Merge remote-tracking branch 'origin/main' into arcodange/mirror-depots-perso
# Conflicts:
#	ansible/arcodange/factory/inventory/group_vars/all/gitea.yml
2026-07-30 19:55:06 +02:00
CI BotandClaude Opus 5 ba791ed055 fix(ci_base_image) — le contexte de build doit être SUR la machine, pas sur le contrôleur
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]>
2026-07-29 23:41:32 +02:00
CI BotandClaude Opus 5 9f438c4968 fix(ci_base_image) — l'image livrait Node 18 : deux défauts que seule sa CONSTRUCTION a montrés
J'avais écrit dans cette PR « je n'ai pas pu construire l'image, sa base vit
derrière le certificat interne ». C'était une SUPPOSITION NON TESTÉE, et elle est
fausse : `docker pull gitea.arcodange.lab/…/runner-images:ubuntu-latest-ca` passe
sans rien configurer. En la construisant vraiment, deux défauts sont sortis — et
aucun n'était visible à la lecture du Dockerfile.

1. `runner-images:ubuntu-latest-ca` LIVRE NODE 18 (v18.20.8). Or `nuxi` importe
   `node:util.styleText`, absent de Node 18 : c'est la raison d'être du
   `container: node:20-bookworm` de la CI de kadans, que son CLAUDE.md interdit
   de retirer. Sans correctif, basculer la CI sur cette image cassait `nuxt build`
   sur un message parlant d'un import introuvable — jamais d'une version de Node.
   → Node 20 installé depuis NodeSource.

2. ET INSTALLER NE SUFFISAIT PAS. Après l'installation, `node --version` rendait
   TOUJOURS v18.20.8 : 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
     /usr/bin/node --version → v20.20.2   ← le bon, mais il PERD

   → l'entrée 18 du toolcache est retirée ; la résolution retombe sur
     /usr/bin/node. ⚠ Conséquence assumée : `actions/setup-node` ne trouvera plus
     de Node 18 préinstallé — aucun workflow de kadans ne l'utilise, et l'image
     n'est servie qu'aux jobs qui DEMANDENT le label.

Le Dockerfile porte désormais une ASSERTION DE BUILD
(`node --version | grep -q "^v${NODE_MAJOR}\."`) : l'image ne peut plus se
construire si la résolution redevient mauvaise. Et le rôle vérifie la version au
déploiement (`failed_when`), au lieu de la supposer.

MESURES RÉELLES (construite en linux/arm64, l'architecture des runners) :

  TOTAL                              4,58 Go
  ├─ playwright install chromium     1,01 Go
  ├─ playwright install-deps          405 Mo
  ├─ Node 20 (NodeSource)             183 Mo
  └─ bun                              179 Mo

  Vérifié dans l'image : which node → /usr/bin/node v20.20.2 · bun 1.3.14 ·
  chromium-1228 + headless-shell + ffmpeg · /etc/ci-base.versions cohérent.

⚠ Ce que ces chiffres tranchent : le découpage en RUN séparés N'A PAS suffi à
rendre l'image poussable — 1,01 Go pour la plus grosse couche, soit ~4× les
261 Mo que le registre accepte (runner-images:ubuntu-latest-ca). Le build LOCAL
n'est donc pas une préférence, c'est la seule voie. Mesuré, plus supposé.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-07-29 23:09:14 +02:00
CI BotandClaude Opus 5 fdecabf8ca feat(ci): construire l'image des jobs CI lourds sur chaque machine à runner
Les jobs CI du dépôt kadans réinstallent, à CHAQUE exécution, des choses qui
changent tous les trimestres. Mesuré le 2026-07-29 sur le run 628 (runner
ARM64, 2 vCPU / 3 Gio) :

  npm install -g bun                        →    8,6 s
  playwright install --with-deps chromium   →  104,0 s   (apt-get, à chaque run)
                                               ────────
                                                112,6 s jetées par run, sur le
                                                job qui EST le 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 quoi qu'il arrive.

POURQUOI CONSTRUIRE ICI PLUTÔT QUE POUSSER UNE IMAGE. La tentative de publier
l'image au registre a échoué (kadans#224 puis #225) : 3,81 Go dont une couche
unique de 1,36 Go, `docker push` casse en « connection reset by peer » — 7
couches passent, 3 sont retentées 50 fois puis abandonnées. À titre de
comparaison, runner-images:ubuntu-latest-ca (534,7 Mo, plus grosse couche
261 Mo) passe sans problème : la limite est entre 261 Mo et ~500 Mo par couche.
Construire localement supprime le problème — aucune couche ne traverse le
réseau.

Et c'est bien sur CHAQUE machine : avec `capacity: 1`, le parallélisme vient de
plusieurs Raspberry, et `container:` est résolu par le runner. Un job qui
atterrit là où l'image manque échoue AVANT sa première étape.

Trois choix de conception :

1. L'image hérite de runner-images:ubuntu-latest-ca, donc du certificat de la CA
   interne (step-ca). Repartir de node:20-bookworm obligerait à réinjecter le CA
   à la main, et tout job parlant à gitea.arcodange.lab échouerait en TLS.

2. TROIS `RUN` séparés (bun / dépendances système / navigateur), délibérément.
   La version qui a échoué faisait une couche de 1,36 Go. Ne pas les fusionner
   pour « gagner une couche ».

3. L'image est ÉPINGLÉE par un conteneur factice — ce qui implémente enfin la
   section 1 de docs/adr/20260407-docker-storage-gitea-runner.md, restée à
   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.

Le rôle vérifie sa sortie (`docker run … bun --version`) au lieu de supposer que
le build a suffi, et l'image écrit ses versions dans /etc/ci-base.versions pour
que la CI de kadans puisse les confronter à son bun.lock et échouer FORT sur une
dérive, plutôt que de la découvrir en « Executable doesn't exist ».

Nouveau label runner `ci-node-playwright`. `container.force_pull: false` est
déjà en place et devient REQUIS pour ce label : sans lui, act_runner tenterait
un pull d'une image qui n'est dans aucun registre.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-07-29 20:23:59 +02:00
arcodangeandClaude Opus 5 e84383ee34 feat(miroirs) — un dépôt personnel n'est pas une organisation
Le rôle gitea_repo ne savait viser qu'un propriétaire : l'organisation, des
deux côtés à la fois. Les dépôts qui vivent sous le compte personnel
`arcodange` ne pouvaient donc pas sortir du homelab — ni être balayés par
gitea_sync, qui n'interroge que /orgs/<org>/repos.

Trois séparations, toutes rétrocompatibles (les défauts reconduisent le
comportement org-vers-org des dix dépôts déjà en miroir) :

- le propriétaire côté Gitea (`gitea_repo_owner`) n'est plus le même objet que
  celui d'en face (`github_owner`, `gitlab_owner`) ;
- un compte personnel n'est pas une organisation : GitHub ne crée pas le dépôt
  au même endroit, d'où `github_owner_is_org` qui route vers POST /user/repos ;
- GitLab devient facultatif (`gitea_mirror_gitlab`). Il ne l'était pas : sa
  création attendait un 201 sans ignore_errors, si bien qu'un échec GitLab
  avortait l'itération — y compris la moitié GitHub, qui n'y était pour rien.

Deux défauts corrigés au passage, tous deux silencieux :

- les trois listages de gitea_sync ne paginaient pas (30 chez GitHub, 20 chez
  GitLab). Sous la taille d'une page tout va bien ; au-delà, la différence
  entre forges désigne de FAUX dépôts manquants et le rôle les « répare » ;
- la migration entrante posait `repo_owner: github_organization` pour désigner
  le propriétaire DANS Gitea.

Et un piège découvert en exécutant : un dépôt GitHub créé vide adopte comme
branche par défaut la PREMIÈRE branche que le miroir lui pousse — `kadans` a
atterri sur `arcodange/adr-ddd-front`. Le rôle réaligne désormais sur la
branche par défaut de Gitea ; le miroir étant asynchrone, l'alignement échoue
au run qui crée le dépôt et réussit au suivant, d'où le failed_when permissif.

Ce qui sort du homelab reste un CHOIX : playbooks/07_mirrors.yml parcourt une
liste explicite et relue (`gitea_mirrored_repos`) plutôt que la différence
automatique entre forges, qui recréerait un dépôt supprimé exprès.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-07-27 13:34:26 +02:00
arcodange 5b3c896a25 use self signed cert for internal domain arcodange.lab 2025-12-31 17:38:04 +01:00
arcodange 6ec2d299fc fix gitea action registration 2025-08-27 18:11:14 +02:00
arcodange 3cfc5f2bfd refactor storage and setup shared backup directory 2025-08-27 17:26:05 +02:00
arcodange 561331b825 fixes 2025-08-07 15:51:53 +02:00
arcodange b8636a6d48 document uv python package manager command for ansible setup - minor fixes in playbook 2025-08-05 12:22:27 +02:00
arcodange b185999478 add pi3 to inventory + fixes 2024-12-15 22:13:03 +01:00
arcodange 50399328dc configure vault oidc login and cicd jwt login 2024-10-07 17:39:27 +02:00
arcodange 407bf12165 setup gitea as oidc provider for tool vault 2024-09-27 18:21:52 +02:00
arcodange 3b4140a0c1 deploy argo cd 2024-08-21 18:46:41 +02:00
arcodange 95f365dbb5 provide PACKAGES_TOKEN secret 2024-08-20 11:25:19 +02:00
arcodange aaaee3066a new gitea_sync role 2024-08-18 11:34:37 +02:00
arcodange 22533623bd désactiver le mode mirroir pour pouvoir 'git push' sur gitea 2024-08-17 14:15:40 +02:00
arcodange 459d255471 new role gitea_repo 2024-08-16 13:53:03 +02:00
arcodange cb4d679d8b k3s setup and git action runner 2024-08-12 21:45:16 +02:00
arcodange f4b54d2941 ansible: playbook for postgres and gitea 2024-07-18 10:36:12 +02:00
arcodange 397a5d3b7f init arcodange factory 2024-07-05 16:16:11 +02:00