Show a lobby notice when a newer release is out
The macOS release binary can now tell the candidate when the rolling latest release is a newer build, in the scope agreed on #543.
How it is enabled: CODETRIAL_UPDATE_CHECK=true in config/codetrial.env.local. It is off by default, and documented in docs/install.md, the README configuration table and config/codetrial.env.example.
What it does: the server asks GitHub (GET /repos/sysprog21/codetrial/releases/tags/latest) which commit latest names, caches the answer for ten minutes (kept even when the lobby that asked goes away mid-request), and answers /api/update with whether that differs from the build. The lobby asks when it loads, which covers both starting the binary and coming back from an interview, since leaving an interview navigates to /, and on every hour it stays open. An interview replaces the lobby page, so nothing is checked during one. A newer release shows a card in the lobby's corner with both commits and a link to the release page; its message is a status line, written a frame after the card shows so it is announced without taking focus. A later answer that no longer names a newer release, or a release dismissed in another tab, takes the card down. Dismissing it stores that release's commit and hides the card until a different one is named. The page's connect-src is unchanged.
When nothing is compared: the setting is off, the build is not macOS, CODETRIAL_BUILD_COMMIT did not come from GITHUB_SHA, or the server was started with --no-update-check, which the desktop app passes because it is published as desktop-latest and latest never names its server. build.rs now records the last as CODETRIAL_RELEASE_COMMIT, empty for a local build. The server then answers enabled: false, asks GitHub nothing, and the lobby stops asking. Every GitHub failure (no network, an error status or rate limit, the 404 while latest is republished, a body without a full commit) answers "no update" and shows nothing, and the lobby keeps checking on the hour; a lobby that cannot reach its own server stops until the next load.
/api/update answers without a session, like /api/session: both commits are public, and the cache means a caller cannot make the server ask GitHub more often.
Tests: tests/unit/web/update.rs runs the lookup against a stub GitHub for the matching-commit, differing-commit and failed-check cases (500, 403, 429, 404, a missing, short or non-hex target_commitish, a closed port), for the cache, and for a lookup whose caller went away mid-request; tests/web/update.rs goes through the router and shows a server with the check off makes no request to the stub; tests/config.rs pins the opt-in, platform and CI-commit rule, and checks that a CI build records its GITHUB_SHA as the release commit, which fails with build.rs recording nothing; tests/unit/bin.rs and desktop/tests/unit/server.rs cover --no-update-check and the launcher passing it; tests/browser/update-notice.test.js covers what the lobby shows, when its message is written, following a later release, taking it down without moving focus that was elsewhere, dismissing, the hourly schedule staying single across a restored page, and the stops, plus one Chromium run of the real lobby by keyboard. Each new assertion was checked to fail with its change reverted. The route allowlists in tests/web/routes.rs and tests/web/accounts.rs list the new route.
Validation, on the single commit rebased onto 38d53a7: ./scripts/test.sh rust, ./scripts/test.sh portable and the three browser shards pass locally, cargo clippy --all-targets -- -D warnings is clean, and cargo test in desktop/ passes. cargo-mutants was not available here, so the four mutants the gate missed, and the new flag's comparison and override, were applied by hand: each fails a test. The same was done for every new branch in web/update-notice.js, which the mutation gate does not cover.
Manual check on an Apple Silicon Mac, against the real GitHub API, with builds from this branch:
- Older build, check on: built with
GITHUB_SHAset to an older commit ofmainandCODETRIAL_UPDATE_CHECK=true. The notice shows both commits, and its link opens the release page.
VIDEO 1 HERE <<<
https://github.com/user-attachments/assets/258fe309-232e-4f3d-9b33-513e5a5f720a
- Dismissed: after Dismiss and a reload, the notice stays hidden.
VIDEO 2 HERE <<<
https://github.com/user-attachments/assets/c8f6073a-45a2-4c5e-8f08-8fe85828b1d2
- Current build: no notice shows when the build is the one
latestnames.- Read the commit
latestnames:git ls-remote https://github.com/sysprog21/codetrial refs/tags/latest. - With
CODETRIAL_UPDATE_CHECK=truestill set, start the server built from that commit:GITHUB_SHA=<that commit> make web. - Remove
codetrial:updateDismissedfrom the page's local storage, so the dismissal from step 2 does not hide the result, and reload the lobby. - No notice shows, and
curl -s http://127.0.0.1:3000/api/updateanswers{"available":false,"enabled":true}.
- Read the commit
VIDEO 3 HERE <<<
https://github.com/user-attachments/assets/ef631446-8660-4057-8ed4-3ad4d120730d
- Check off: nothing is compared, even for an older build, when the setting is absent.
- Remove
CODETRIAL_UPDATE_CHECK=truefromconfig/codetrial.env.local. - Start the server built from the older commit of step 1:
GITHUB_SHA=<older commit> make web. - Reload the lobby: no notice shows, and
curl -s http://127.0.0.1:3000/api/updateanswers{"enabled":false}.
- Remove
VIDEO 4 HERE <<<
https://github.com/user-attachments/assets/43245dbf-fa50-4f37-a864-16cb8e7b3ee9
Close #543
Summary by cubic
The macOS release binary now shows a lobby notice when the rolling latest release names a newer build, behind CODETRIAL_UPDATE_CHECK=true (off by default). Closes #543.
How it works
- The server asks GitHub which commit
latestnames, caches the answer for ten minutes, and answers/api/update; the lobby checks on load and hourly. - A newer release shows a card in the lobby corner with both commits and a link to the release page; dismissing it hides it until a different release is named.
- The status line is written a frame after the card shows so screen readers announce it, and a later check that names no newer release takes the card down.
- Every GitHub failure answers "no update" and shows nothing, and the page's
connect-srcis unchanged.
When nothing is compared
- The check runs only in a macOS build CI made:
build.rsrecords theGITHUB_SHAcommit asCODETRIAL_RELEASE_COMMIT, and other builds answerenabled: falseand ask GitHub nothing. - The desktop app always passes
--no-update-check, overriding its config file, because it is published asdesktop-latest.
Manual check on an Apple Silicon Mac, against the real GitHub API, with builds from this branch:
- Older build, check on: the notice shows both commits, and its link opens the release page.
- Dismissed: after Dismiss and a reload, the notice stays hidden.
- Current build: no notice shows when the build is the one
latestnames. - Check off: nothing is compared, even for an older build, when the setting is absent.