A CI-only update (the "Discuss and improve release tests" work). No game, server, protocol or file format change: 1.18.9 plays with 1.18.7 and 1.18.8 (protocol 43).
CI: no gameplay or UI tests (.github/workflows/release.yml)
- Owner: "CI should only test meta, builds, sanitizer type stuff ... the game will have already been heavily playtested via testing branch, and it will have to pass all of the local (claude and human) tests, so CI should not include any gameplay type tests, this is a duplication of effort."
- Removed jobs:
linux-testsandwindows-tests(quark_tests, one runner per test group: 25 Linux plus 25 Windows runners per push) andlinux-uitest(quark --uitestunder Xvfb, about 10-15 min). Also removed: meta's test-group list (parsed from tests.cpp), the linux job's group check and the test artifacts. The Windows job still compilesquark_tests.exe, as a build check only. - What CI still checks on every push: meta (VERSION, both changelogs for a release, the release doesn't already exist,
tools/check_secrets.py, the provenance registry), the Windows, Linux and macOS builds and packages, the light bakes and the website's data. A release waits only for those builds:releasefor Windows + Linux + macOS,release-testingfor Windows + Linux. - Why it's safe:
build/quark_tests(every group) and the UI test run locally before every push (CLAUDE.md), and the owner tests every testing build by hand with RELEASE_CHECKLIST.md before production. The CI runs also flaked on timing tests that the change under test never touched: in run 40062619452 the bots group's "0 grapples in 40 s" and the Windows tick-rate stall check failed. - The dead 1.17.0 conditions are gone: the six
base == '1.17.0'alternatives and their comments. The release gates are now plain== 'success'checks, and!cancelled()stays only where a needed job can be skipped (pages on a site-only run, release-testing-macos, deploy-worker). - Release files: before signing, release / release-testing now keep only the platform artifacts (
find ... ! -name windows ! -name linux ...) instead of deleting a list of known non-release artifacts by name. A sanitizer report or a fuzzer crash uploaded in the same run can't end up in SHA256SUMS.
Sanitizers: only for a build a human marks as a final test
- Owner: "the testing branch should only do the sanitizer thing if it is classified as a final test", then "disable sanitizer running unless human specifies final test", and production shouldn't re-run them ("testing will have already passed ... duplication of effort").
- When: a push whose head commit message (for a merged PR, its title) contains
[final], or Actions → build-and-release → Run workflow with the new final box ticked. A final run is meta + the sanitizers on that commit, and nothing is built or published. Any branch counts. Nothing else runs them: work branches and testing pushes didn't used to need a mark, and production tags never run them. No release waits for them. Agents never add the mark themselves. The trigger is one block in meta's channel step (sanitizersoutput). - What fails it: only a sanitizer error (ASan / UBSan) or a fuzzer crash, never a test's own CHECK.
quark_testsruns only to drive the code. Reports go to files (log_path; each forked group writes its own), a hang is cut at 55 min and the reports are still read, and the reports upload as thesanitizer-reportsartifact. Before, any failing gameplay check failed the job too, which made it a second gameplay test run. - A final run gets its own concurrency group, so a testing push queued after it can't replace it.
Docs and tools
- RELEASE_CHECKLIST.md section 0: what CI checks now, marking the final test build, and asking for the local test and UI test results on the commit that ships. HANDOVER.md and UI_TEST.md updated to match.
tools/fetch_ci_build.ps1only takes push runs (a final run has no build to download).