Toolchain Validation Checks

May 31, 2026 ยท View on GitHub

GitHub Actions now provides two hosted guardrails around the local/manual toolchain checks:

  • .github/workflows/push-verification.yml runs the current subsystem parity lanes plus Linux/macOS native POSIX builds on direct pushes and uploads the same evidence roots as the focused PR workflows.
  • .github/workflows/nightly-build.yml runs scheduled Linux/macOS native POSIX builds plus a Windows modern compatibility package, assigns the Windows package a traceable nightly version, and publishes the platform packages, checksums, and manifest metadata to a GitHub Release as well as workflow artifacts.

The local commands below remain authoritative when a contributor needs strict retail toolchain evidence, especially for v100 validation that is not assumed to be present on hosted runners.

QVM toolchain guard

The QVM guard runs locally on a Unix-like host, executes tools/ci/verify-qvm-toolchain.sh, rebuilds the clean-room shared objects, and then runs tests/run_harnesses.py --target qvm. The prerequisite script still validates perl, make, gcc, the legacy src/q3asm/ and src/lcc/ makefiles, and the historical wrapper scripts before the harnesses start.

Native DLL validation

The native DLL validation path runs locally on Windows before it executes the shared harness bundle. The lane now:

  1. Installs the optional Visual Studio 2010 v100 component.
  2. Verifies that the v100 toolset and dumpbin.exe are available.
  3. Runs tools/ci/validate-windows-native.ps1 -PlatformToolset v100 -RuntimeProfile retail, which audits project metadata, checks the retail launcher payload and CRT availability, builds Release|Win32, validates awesomium_process.exe, assembles build\win32\<Config>\retail-runtime\ from the rebuilt binaries plus the exact retail DLL payload, audits that staged root for missing or extra DLLs, and asserts the gameplay DLL export manifest.
  4. Runs tests/test_default_cfg_presence.py and tests/run_harnesses.py --target dll so the parity harnesses operate on the same verified native pipeline.

Optional modern-host path

Local contributors can validate the hosted-compatible v143 lane on current Windows hosts:

  1. Verify the Visual Studio 2022 v143 component with pwsh tools/ci/verify-vs-toolchain.ps1 -PlatformToolset v143 -RequireToolset.
  2. Run pwsh tools/ci/validate-windows-native.ps1 -PlatformToolset v143 -RuntimeProfile modern, which validates the launcher payload plus modern CRT availability, builds the native targets with the hosted-compatible toolset, and checks the rebuilt gameplay DLL export manifest without claiming a strict retail runtime stage.

Push verification

The Push Verification workflow runs on every push and can also be started manually. It fans out across the same focused validation surfaces used by the dedicated PR workflows, then builds the native POSIX targets:

  • Linux-hosted lanes: module, renderer, and UI parity validation.
  • Windows-hosted lanes: client, qcommon, server, and engine host/support parity validation.
  • Build lanes: Linux .so and macOS .dylib native POSIX packages from tools/ci/build-posix-native.sh, covering the real src/code baseq3 native modules plus the dedicated host.

Artifacts are retained for 14 days under names prefixed with push-. The lane does not launch the game or exercise live online services; it only runs the deterministic Python, bundle, and headless validation commands already used by the subsystem gates and publishes the native POSIX package manifest/tarball.

Versioned nightly builds

The Nightly Build workflow runs daily at 03:17 UTC and can also be started manually for Release or Debug. It follows the release workflow shape used by the sibling FnQuake3 project: a prepare job resolves one version manifest, platform jobs build packages from that shared version, and a final manifest job indexes the uploaded archives with SHA256 sums before creating or updating the nightly entry in GitHub Releases. Linux jobs build a native POSIX package with .so module outputs, macOS jobs build a native POSIX package with .dylib module outputs, and those tarballs are attached to the release beside the Windows package. The Windows package job uses the hosted-compatible v143 toolset plus the modern runtime profile to package only rebuilt outputs:

  • quakelive_steam.exe
  • awesomium_process.exe
  • qagamex86.dll
  • cgamex86.dll
  • uix86.dll
  • optional qzeroded.exe and UI bundle output when present

Nightly versions are generated by tools/ci/nightly_build.py using the shape nightly-YYYYMMDD.<run>-g<shortsha>, with a companion SemVer-style string, release title, source SHA, and archive prefix in artifacts/nightly/version.json. The Windows package also writes nightly-release-manifest.json and SHA256SUMS.txt; the final workflow job assembles the same release-style index for all uploaded nightly package archives, stages release-notes.md, and publishes those files plus version.json as release assets. The release is tagged with the nightly artifact version, explicitly marked with GitHub's Latest release label, and updated in place when the same workflow run is retried. The packages intentionally do not include retail pk3 files, the retail launcher DLL payload, Steam credentials, live-service material, or reverse clean-room comparison DLLs; those prototypes stay in the reverse-engineering harness lanes instead of the runtime packages. Versioning stays in the external manifest and artifact name so the retail-aligned PE version resources remain governed by the metadata audits. The hosted Windows modern lane disables optional OGG, PNG, and FreeType bootstraps so nightlies do not depend on ignored local codec/font import libraries; full codec-enabled validation remains a local/dependency-staged toolchain exercise.

Runbook Quick Reference

  • Re-run the QVM prerequisite guard locally with tools/ci/verify-qvm-toolchain.sh.
  • Re-run the native DLL guard locally with pwsh tools/ci/install-vs-v100.ps1, pwsh tools/ci/verify-vs-toolchain.ps1 -RequireV100, and pwsh tools/ci/validate-windows-native.ps1 -PlatformToolset v100 -RuntimeProfile retail.
  • Re-run the modern-host compatibility guard locally with pwsh tools/ci/verify-vs-toolchain.ps1 -PlatformToolset v143 -RequireToolset and pwsh tools/ci/validate-windows-native.ps1 -PlatformToolset v143 -RuntimeProfile modern.
  • Re-run the shared harness bundle with python tests/run_harnesses.py --target qvm or python tests/run_harnesses.py --target dll after the prerequisite steps above.
  • Preview a nightly version locally with python tools/ci/nightly_build.py version --output artifacts/nightly/version.json.