ci: Forgejo Actions workflow with a boot-from-COPY check #31
No reviewers
Labels
No labels
autopilot:pending-human
source:analyste
source:defenseur
source:human
source:medic
status:approved
status:blocked
status:in-progress
status:needs-clarification
status:needs-fix
status:ready
status:review
status:triage
type:bug
type:feature
type:infra
type:refactor
type:schema
type:security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: maximus/vps-health-api#31
Loading…
Reference in a new issue
No description provided.
Delete branch "issue-24-forgejo-ci"
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?
Fixes #24
What
.forgejo/workflows/ci.yml: one job incontainer: node:22-alpine(the Dockerfile base), runningnpm ci,npm test,bash test-curl.sh,sh scripts/boot-from-copy.sh. It triggers on every pull request, with nobranches:filter so intermediate stack links are built, and on push tomain.scripts/boot-from-copy.sh: copies only the DockerfileCOPYsources into an empty directory and runs theCMDasnode. It expects 401 without a token, 200 with one, and non-zero disk and memory metrics. This replaces a realdocker build, which would need the Docker socket in the instance-scoped runner and would therefore give every workflow root on the prod VPS.__tests__/ci.test.js: 7 pins. The container image must equalFROM, all four steps must be present,pull_requestmust have no branch filter whilepushtargetsmain, no runner-rejected forms,USER node, and an exec-formCMD.CLAUDE.md: new CI section; test count updated to 308.Local verification (glibc host, no Docker available)
npm test: 308/308bash test-curl.sh: 45/45boot-from-copy.sh: PASS. Withmetrics.jsremoved fromCOPYit FAILs and printsCannot find module './metrics.js'(MODULE_NOT_FOUND).ci.test.jsmutation (branches: [main]underpull_request, pluscontainer: node:22): both targeted pins go red (2 failed, 5 passed). Tree restored.CI evidence
Commit statuses and job logs, the logs read from the Forgejo database on the VPS:
4e7879d(this PR)boot-from-copy: PASSincluding non-zero disk/memory under busyboxdf93a59a2(throwaway PR #32, stacked on this branch)metrics.jsremoved fromCOPYImage file set (2): index.js package.json,Error: Cannot find module './metrics.js',code: 'MODULE_NOT_FOUND',FAIL: the server died at startupThe red ran on a throwaway stacked PR, so no broken commit reaches
mainhistory. It also shows that a PR whose base is notmaindoes get built. PR #32 is closed and its branch deleted.🤖 Generated with Claude Code
Revue adversariale — PR #31 (issue #24)
Verdict : APPROVE
Résumé : le workflow et
boot-from-copy.shfont ce que la PR annonce, et le contrôle duCOPYattrape le défaut réel de #11. Les preuves de CI ont été vérifiées dans le log du run et non sur parole. Rien de bloquant.Vérifications faites
4e7879d:CI / verification (pull_request)= success, 21 s. Le log du run 1 (route web/actions/runs/1/jobs/0/logs) montre node v22.23.3, vitest 308 passed, test-curl 45 passed, 0 failed,Image file set (3), les troisoketboot-from-copy: PASS, puisJob succeeded.vitestdonne 308/308 etboot-from-copy.shrenvoie PASS.metrics.jsretiré duCOPY: FAIL,the server died at startup(MODULE_NOT_FOUND)execSynccassé dansmetrics.js, donc des métriques disque à zéro : FAIL,/health reported empty disk or memory metricsCMD node index.js(forme shell) : le script échoue bruyamment, et 1 épingle sur 7 tombebranches: [main]souspull_request: 1 épingle sur 7 tomberun: bash test-curl.shremplacé parecho skipped: 1 épingle sur 7 tombecontinue-on-error: truesur l'étape du boot check : 0 épingle tombe (voir la suggestion 1)boot-from-copy-tokenest local et éphémère). Le refus du socket Docker est justifié. L'interpolation danssu -cne porte que sur des valeurs contrôlées (leCMDest filtré par^[A-Za-z0-9._/-]+$, etAPP_DIRvient demktemp).COPY, des flags, la forme JSON, une source absente ou un dossier) échouent toutes bruyamment. Je n'ai trouvé aucun chemin de faux PASS silencieux sur leCOPY.Suggestions (non bloquantes)
continue-on-errorn'est pas épinglé (__tests__/ci.test.js). Uncontinue-on-error: trueajouté sur une étape la rend verte même quand elle échoue, et les 7 épingles restent vertes. C'est précisément le « succès apparent » qu'on cherche à éviter. Il suffirait d'une ligne :expect(ciCode).not.toMatch(/continue-on-error:/).Refs #24, pasFixes #24. LeFixes #24du corps de la PR ne sert à rien si le merge est poussé en fast-forward. Il faut donc fermer #24 à la main après le merge, ou reformuler le commit.boot-from-copy.sh: si un autre serveur tient déjà:3097, lecurlde la boucle d'attente peut obtenir une réponse de ce voisin avant que le serveur lancé ne meure enEADDRINUSE, et les assertions visent alors le mauvais processus. Ce n'est pas un risque en CI, où le conteneur est neuf. En local,BOOT_PORTpermet de contourner. Une garde peu coûteuse : vérifier que le port est libre avant le démarrage, ou refaire unkill -0 $SERVER_PIDaprès les assertions./healthest sollicité. Unrequire()paresseux, placé dans un handler d'une autre route, échapperait au contrôle. Ce n'est pas le cas aujourd'hui, puisque tous lesrequiresont au niveau module dansindex.jsetmetrics.js. On pourrait le noter dans l'en-tête du script.🤖 Generated with Claude Code
Mergé en fast-forward sur
main(4e7879d) après rejeu local du tip :npm ci, 308/308 vitest, 45/45test-curl.sh,boot-from-copy: PASS. Forgejo ne détecte pas le ff local, fermeture manuelle.Pull request closed