Repository navigation
ci: GitHub Actions workflow for tests, style and judging (#80) - #81
Merged
Merged
Conversation
Closes #80. Three jobs, split by what they can actually prove. **backend** — PHP 8.3, composer cache, PHPUnit, Pint. `--no-coverage` is load-bearing rather than an optimisation: phpunit.xml configures <coverage> reports, and with no driver installed PHPUnit aborts with "No tests executed!" and exit code 0. Without the flag this job would be permanently, silently green having run nothing. E2E is excluded here because those suites compile and run real submissions and need the fourteen language toolchains plus bubblewrap; the judge-image job runs them where that exists. 658 tests remain. Pint is scoped to files a change *adds*. 278 of the repo's 363 PHP files predate Pint, so a repo-wide --test fails today, and even an all-changed-files check would redden a PR over formatting it inherited rather than wrote. The comment records the path out: a one-off repo-wide `pint`, then --diff-filter=ACMR, then the plain whole-repo check. **judge-image** — builds Dockerfile.judge (the fourteen toolchains plus bubblewrap) against the GHA layer cache and runs the whole suite inside it, --privileged, the way docker-compose.yml runs the autojudge service. This is the job that answers the question this project most needs answered on a PR: does judging still work? `--fail-on-skipped` is what makes the answer trustworthy -- the judging suites skip themselves when no usable sandbox exists, so without it a broken sandbox reads as a green build that quietly tested nothing. **frontend** — Node 22, npm cache, frontend tests, production asset build. Node 22 is not arbitrary: tests/Frontend/vue-loader.js calls module.registerHooks(), which only exists from Node 22.15. On Node 20 -- which is what docker-compose.yml's node service still pins -- features.test.js dies at import time and eleven of the twenty-six tests never run while the suite still reports success. Worth reconciling separately. Verified against this commit rather than assumed: the backend job's command is green (658 tests), the judge-image command is green with --fail-on-skipped (739 tests, 3818 assertions) in an image built from Dockerfile.judge and run --privileged, `npm ci && npm run build` succeeds on Linux, and the frontend suite is 26/26 on Node 22 against 14/15 on Node 20. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pvf2R8xtgbWQm1wRvjBqQY
matbrgz
added a commit
that referenced
this pull request
Sep 13, 2026
The CI workflow proposed in #81 gates Laravel Pint on files a change adds, which is everything new here: the exception, the test trait, the confinement suite and the isolation suite. The pre-existing files this branch also touches are left alone -- 278 of the repo's 363 PHP files predate Pint, and reformatting them from here would bury the actual change. No behaviour change: 135 tests / 535 assertions still green in an image built from Dockerfile.judge. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pvf2R8xtgbWQm1wRvjBqQY
The judge-image job failed its first real run with 241 errors, every one of them a storage write: "Unable to create a directory at /var/www/html/storage/...", "could not be opened", "Permission denied". Dockerfile.judge runs as its own `judge` user (uid 1000) and the runner owns the checkout as a different uid, so the mounted workspace is effectively read-only to the test process. It does not reproduce on a developer machine because Docker Desktop's bind mounts ignore uid ownership. Widening the directories the suite writes to is the targeted fix. The alternative -- running the container as the runner's uid -- would stop matching how docker-compose.yml runs the autojudge service, which is the thing this job exists to verify. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pvf2R8xtgbWQm1wRvjBqQY
This was referenced Sep 13, 2026
Closed
matbrgz
added a commit
that referenced
this pull request
Sep 13, 2026
…) (#103) Closes #101. docker-compose pinned node:20-alpine and the frontend suite needs 22.15. On Node 20, tests/Frontend/vue-loader.js dies at import -- module.registerHooks() does not exist there -- and features.test.js goes with it. Measured: node:20 # tests 15 # pass 14 # fail 1 node:22 # tests 26 # pass 26 # fail 0 Eleven tests missing, and `node --test` reports one failed file rather than eleven absent tests. The total changes too, so nothing looks wrong unless you already know the number. CI has been on 22 since #81 and is green at 26/26, which is exactly the split worth closing: a developer running `docker compose --profile dev up` saw fourteen passing and had no reason to doubt it. engines.node makes npm say so at install time, rather than leaving a vanished test to be the signal. Verified on node:22-alpine, the image the compose file now uses: 26/26. Claude-Session: https://claude.ai/code/session_01Pvf2R8xtgbWQm1wRvjBqQY Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #80.
Três jobs, separados pelo que cada um consegue de fato provar.
backend— PHP 8.3, composer cache, PHPUnit, Pint--no-coveragenão é otimização, é obrigatório. Ophpunit.xmlconfigura relatórios de<coverage>; sem driver instalado o PHPUnit aborta comNo tests executed!e exit code 0. Sem a flag este job ficaria permanentemente verde sem ter rodado nada — descobri isso na marra enquanto testava a #77.E2Efica de fora aqui porque essas suítes compilam e executam submissões reais e precisam das 14 toolchains + bubblewrap, que um runner pelado não tem. O jobjudge-imageroda a suíte inteira onde isso existe. Sobram 658 testes.Pint roda só nos arquivos que o PR adiciona. 278 dos 363 arquivos PHP do repo são anteriores ao Pint, então um
--testno repo inteiro falha hoje — e mesmo um check em "todos os arquivos alterados" deixaria o PR vermelho por formatação que ele herdou em vez de escrever. Arquivo novo não tem essa desculpa. O comentário no workflow registra o caminho de saída: um./vendor/bin/pintúnico na árvore, depois--diff-filter=ACMR, depois o check repo-wide simples.judge-image— a suíte inteira dentro da imagem real do juizBuilda o
Dockerfile.judgecontra o layer cache do GHA e roda tudo lá dentro,--privileged, do jeito que odocker-compose.ymlroda o serviçoautojudge.É o job que responde a pergunta que mais importa num PR deste projeto: o julgamento ainda funciona? O
--fail-on-skippedé o que torna a resposta confiável — as suítes de julgamento se auto-skipam quando não há sandbox utilizável, então sem ele um sandbox quebrado apareceria como build verde que silenciosamente não testou nada.frontend— Node 22, npm cache, testes, build de produçãoNode 22 não é arbitrário:
tests/Frontend/vue-loader.jschamamodule.registerHooks(), que só existe a partir do Node 22.15. No Node 20 — que é o que o serviçonodedodocker-compose.ymlainda fixa — ofeatures.test.jsmorre no import e 11 dos 26 testes nunca rodam, com a suíte ainda reportando sucesso. Vale reconciliar isso separadamente.Verificado, não presumido
Rodei cada comando do workflow contra este commit antes de escrevê-lo:
phpunit --no-coverage --exclude-testsuite E2E(runner pelado)phpunit --no-coverage --fail-on-skippedna imagem do juiz,--privilegednpm ci && npm run buildno Linuxnpm run test:frontendO build da imagem do juiz leva ~2 min localmente com cache quente; na primeira execução do CI paga os downloads do Kotlin (GitHub releases) e do Free Pascal (SourceForge). Se o SourceForge se mostrar instável, esse job é o candidato natural a virar
schedulenoturno em vez de rodar em todo PR.🤖 Generated with Claude Code
https://claude.ai/code/session_01Pvf2R8xtgbWQm1wRvjBqQY