Repository navigation
Install real toolchains for every judge-offered language - #39
Merged
Merged
Conversation
Language::getDefaultLanguages() already listed Java, Node, TypeScript,
Kotlin, C#, Rust, Go, PHP, Ruby and Pascal as is_active, and the
Contest Wizard already lets admins select any of them -- but
Dockerfile.dev/Dockerfile only ever installed gcc/g++/python3. Every
other language silently failed to compile/run; participants and
admins were offered languages the judge couldn't actually execute.
- Add openjdk21-jdk, nodejs, npm, dotnet8-sdk, go, rust, cargo, ruby to
both Dockerfiles (apk packages, verified in Alpine 3.24).
- Install TypeScript globally (npx tsc) and Kotlin from JetBrains'
GitHub release zip (no Alpine package exists).
- Install Free Pascal (FPC) from the official per-arch SourceForge
binary tarball, also with no Alpine package; the RUN step detects
x86_64 vs aarch64 and retries the (occasionally truncated) download
up to 6 times, verifying the tarball with `tar -tf` before trusting it.
- Fix Node/TypeScript run_command: they called nvm, but the container
only installs one Node runtime -- switched to plain `node`, and
deactivated the Node 20/22 catalog entries that no longer correspond
to an installed binary (kept for a future real multi-version setup).
Fixed TypeScript's compile_command too: `tsc --outFile` was removed
in TypeScript 7.
- Fix C#: `dotnet build`/`dotnet run` need a project, not a bare .cs
file. Added resources/judge-runtime/csharp/{compile,run}.sh, which
scaffold a throwaway console project around the submitted source
before building -- referenced via a new {judge_runtime} placeholder
resolved by AutoJudgeService (not baked into the catalog directly,
since Language::getDefaultLanguages() runs in contexts, like PHPUnit
data providers, where the app isn't booted and base_path() fails).
- Deactivate PyPy: no musl/Alpine build exists upstream; CPython 3.12
already covers the language, so it's left inactive with a comment
rather than silently failing every submission.
- Add tests/E2E/MultiLanguageJudgingTest.php: submits a real, correct
"A + B" solution in every is_active language and asserts a real AC,
nothing mocked (same style as FullBocaLifecycleTest) -- the
regression net for all of the above.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011u3o4QCgpcqH51edYyRPMn
- Bring Dockerfile.judge (the standalone autojudge:start worker image, used by docker-compose.yml's separate autojudge service) up to the same toolchain set as Dockerfile/Dockerfile.dev. It only had gcc/g++/python3/go/rust/ruby and an nvm-based multi-Node setup defaulting to v20; C# and Pascal were completely missing, and Java was still 17, not 21 -- every one of those submissions would fail with "command not found" or a version mismatch in that worker while looking correct from the other two Dockerfiles alone. - Fix a real permission bug: npm/npx (TypeScript), dotnet, and go all write caches under $HOME, but PHP-FPM runs the judge as the `www` user without setting HOME, so it inherits (or is left without) a HOME the worker can't write to. Reproduced directly (a `dotnet build` under HOME=/root as uid 1000 fails with EPERM creating ~/.dotnet) and fixed by explicitly setting HOME to the run's own writable working directory on both Process::run() calls in AutoJudgeService. - Replace the `find ... -name 'ppc*'` FPC binary lookup (could match more than one file and break `install`) with the exact known filename per architecture (ppcx64/ppca64). - Remove `cargo`: the only active Rust language compiles directly with `rustc`, never invokes cargo. - Fix a stale comment referencing the old "TypeScript (Node 22)" name. - tests/E2E/MultiLanguageJudgingTest.php: activeLanguages() silently drops any is_active language missing from its solutions map instead of failing, which would let a newly-activated untested language ship green. Added a companion test that fails loudly if the two ever diverge. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011u3o4QCgpcqH51edYyRPMn
This was referenced Sep 10, 2026
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.
Summary
Language::getDefaultLanguages()already lists Java, Node, TypeScript, Kotlin, C#, Rust, Go, PHP, Ruby and Pascal asis_active, and the Contest Wizard already lets an admin select any of them per contest -- but the Docker images that actually run the judge only ever installedgcc/g++/python3. Every other language was offered but silently failed to compile/run.Dockerfile.devandDockerfile(apk packages where available; Kotlin and Free Pascal have none, so they're installed from their official upstream releases, with retry+verification for the flaky SourceForge FPC download).run_commandcallednvm, but the container only installs one real Node runtime -- switched to plainnode, deactivated the two Node versions that no longer correspond to an installed binary (kept for a future real multi-version setup). Also fixed TypeScript'scompile_command:tsc --outFilewas removed in TypeScript 7.dotnet build/dotnet runneed a project, not a bare.csfile -- addedresources/judge-runtime/csharp/{compile,run}.shto scaffold a throwaway console project around the submitted source before building.Test plan
tests/E2E/MultiLanguageJudgingTest.php: submits a real, correct "A + B" solution in everyis_activelanguage and asserts a real AC verdict -- nothing mocked, same style asFullBocaLifecycleTest. All 14 active languages pass.🤖 Generated with Claude Code
https://claude.ai/code/session_011u3o4QCgpcqH51edYyRPMn