ci(test): sérialise vraiment le job test entre runs concurrents #96
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/ci-test-job-serialization"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Contexte
En diagnostiquant une contention sévère aujourd'hui sur 3 PR en cours
(#93/#94/#95 — Postgres coupé en cours de run, collisions de cache
d'actions, timeouts Cypress, jusqu'à une violation de clé étrangère au
seed des tour scenarios), j'ai retrouvé une session précédente qui avait
déjà entièrement diagnostiqué et corrigé exactement ce problème —
branche
claude/magical-stonebraker-5dc636, mémoire projetci-forgejo-runner-constraints— mais jamais ouvert de PR ni mergé.Ce PR reprend ce travail tel quel (diff identique, appliqué proprement sur
le
mainactuel, aucun conflit).Le problème
Deux jobs
testqui se chevauchent partagent un seul conteneur--name postgressur le réseau docker du runner (pas de blocservices:) : leursprisma migrate deploy+seedReferenceData(beforeAll racine Mocha)rentrent en collision —
Unique constraint failed on (key), "No pendingmigrations" alors qu'il en reste, décalages d'id
tech_step/dietcassantdes assertions sans rapport ; et même en dehors de ça ils s'affament
mutuellement en RAM/CPU (chacun entraîne aussi un modèle spaCy) jusqu'à ce
que
resetDatabase()dépasse le timeout de hook Mocha (10s) et que çacascade. Touché à répétition (PR #47, #53, #54, et de nouveau aujourd'hui),
à chaque fois résolu par une relance à vide une fois le runner plus calme —
jamais un vrai bug de la PR concernée.
concurrency:(le vrai correctif GitHub) est silencieusement ignoré par ceForgejo (9.0.3, arrivé en Forgejo v14/Gitea 1.26).
Le fix
Un objet de verrou (réseau, conteneur, fichier) fuirait : ce runner
(forgejo-runner v3.5.0) n'exécute pas les steps
if: always()suivant unstep en échec, donc pas de libération fiable en fin de job. À la place :
s'appuyer sur ce que le runner nettoie toujours lui-même — le conteneur du
job (supprimé en succès, échec et annulation) — et attendre tant qu'un job
testde task id inférieur tourne encore. Le plus petit id part enpremier, donc deux jobs démarrés ensemble ne peuvent pas se bloquer
mutuellement ; rien à libérer explicitement.
Trois ajouts, purement additifs (aucune ligne existante modifiée) :
docker ps, plafond~25min) juste avant le démarrage de Postgres ;
timeout-minutes: 45sur le job (couvre le temps d'attente éventuel +garde-fou si le job reste bloqué, vu l'absence de
--exitsur Mocha) ;docker rm -f postgresexistant balaie aussi les conteneurspostgres-<suffixe>orphelins.Vérification
Déjà vérifié fonctionnel en conditions réelles par la session précédente
(run 130 : "12x waiting for earlier test job(s)... puis proceeding").
Impossible de re-simuler la course en local (pas de second runner ici),
mais le diff s'applique sans le moindre conflit sur l'état actuel de
main— les trois commits deci.ymlsurvenus depuis (upload-artifactv3, bit gradlew, build-android) touchent un job entièrement différent du
fichier.
🤖 Generated with Claude Code