ci(release): the nightly moves forward during merge bursts instead of waiting for main to be quiet #2556

Merged
hckrman101 merged 1 commit from ci/nightly-moves-forward into main 2026-11-12 02:43:14 +00:00
hckrman101 commented 2026-11-11 23:09:47 +00:00 (Migrated from github.com)

Why

The nightly only took a push's files when that push's commit was still main's newest (scripts/release_upload.sh). Pushes to main build one at a time per workflow, and a waiting run is replaced by a newer push's. So during a burst of merges, every build that finished was already behind main and skipped the upload. The nightly stayed put until main was quiet.

Seen today: run 43112700938 (commit 57ed3aa8), step "AppImage to the release":

nightly: 57ed3aa8... is no longer main's newest commit (...); its own run updates the nightly

The nightly stayed at v2.1.0-rc.3-153-g15646d18 (both platforms' files from 21:42-21:45 UTC) for over an hour while main kept moving.

What

  • A run now takes the nightly when its commit comes after the commit the nightly tag holds. This uses GitHub's compare API (compare/<held>...<sha> is ahead), so the release job needs no full-history checkout. It no longer has to be main's newest commit.
  • The tag is moved as a fast-forward (PATCH git/refs/tags/nightly with force=false). If the other platform's run has moved the tag past this commit since we looked, GitHub refuses the move, we look again, and this run stops without uploading anything. The tag never goes back. A run of an older commit, or a re-run of an old one, changes nothing.
  • Each platform's files never go back either, because the workflows' concurrency runs main's pushes one at a time per workflow (the concurrency blocks now say this is relied on). The Linux files (AppImage, .zsync, hookshot-linux.txt) are always from one commit, and so are the Windows files (HookshotBuilder.exe, hookshot-setup.txt, the RecompLauncher zip). Each set is named by its commit: the version in the file name, the tag in the list file. Each platform's updater reads only its own list (Updater.cs, linux_update.py), and the AppImage's zsync update info matches its own .zsync. So while main is moving, one platform's files can be a commit or two behind the other's without anything getting mixed up. The tag is at the newer of the two.
  • If main was rewritten (the tag's commit is no longer on main, so the compare says diverged), only main's newest commit takes the tag, as before.
  • The notes no longer name one commit and date: the two platforms' runs would race to write them. They now say that each file names the commit it was built from, and that Windows and Linux can be a commit apart during merges.
  • Comments in both workflows and docs/versioning.md are updated to match.

How verified

  • bash -n scripts/release_upload.sh; py_compile of the test.
  • tests/test_release_scripts.py: the stand-in gh now knows main's history (for compare), refuses tag moves that are not fast-forwards, can inject a race (the tag moves between a run's look and its move), and handles gh release view/edit/delete-asset. New tests:
    • moves forward while main has newer commits (old AppImage/.zsync removed, SHA256SUMS remade, force=false)
    • never goes back (Linux and Windows)
    • the other platform's run of the same commit adds its files without moving the tag
    • the two platforms move on their own
    • race lost to a newer commit: nothing changes
    • race with an older commit: still moves forward
    • two real runs at once, in both orders: tag ends at the newer commit, Linux's files are all from one commit
    • no tag yet
    • main rewritten

Not tested

  • The test suite is not run yet.
  • Not run on GitHub: the fast-forward refusal and the compare statuses are GitHub's documented behavior, simulated by the stand-in.
  • actionlint and shellcheck are not available here.
## Why The nightly only took a push's files when that push's commit was still main's newest (`scripts/release_upload.sh`). Pushes to main build one at a time per workflow, and a waiting run is replaced by a newer push's. So during a burst of merges, every build that finished was already behind main and skipped the upload. The nightly stayed put until main was quiet. Seen today: run 43112700938 (commit 57ed3aa8), step "AppImage to the release": ``` nightly: 57ed3aa8... is no longer main's newest commit (...); its own run updates the nightly ``` The nightly stayed at `v2.1.0-rc.3-153-g15646d18` (both platforms' files from 21:42-21:45 UTC) for over an hour while main kept moving. ## What - A run now takes the nightly when its commit comes after the commit the `nightly` tag holds. This uses GitHub's compare API (`compare/<held>...<sha>` is `ahead`), so the release job needs no full-history checkout. It no longer has to be main's newest commit. - The tag is moved as a fast-forward (`PATCH git/refs/tags/nightly` with `force=false`). If the other platform's run has moved the tag past this commit since we looked, GitHub refuses the move, we look again, and this run stops without uploading anything. The tag never goes back. A run of an older commit, or a re-run of an old one, changes nothing. - Each platform's files never go back either, because the workflows' concurrency runs main's pushes one at a time per workflow (the concurrency blocks now say this is relied on). The Linux files (AppImage, `.zsync`, `hookshot-linux.txt`) are always from one commit, and so are the Windows files (`HookshotBuilder.exe`, `hookshot-setup.txt`, the RecompLauncher zip). Each set is named by its commit: the version in the file name, the tag in the list file. Each platform's updater reads only its own list (`Updater.cs`, `linux_update.py`), and the AppImage's zsync update info matches its own `.zsync`. So while main is moving, one platform's files can be a commit or two behind the other's without anything getting mixed up. The tag is at the newer of the two. - If main was rewritten (the tag's commit is no longer on main, so the compare says `diverged`), only main's newest commit takes the tag, as before. - The notes no longer name one commit and date: the two platforms' runs would race to write them. They now say that each file names the commit it was built from, and that Windows and Linux can be a commit apart during merges. - Comments in both workflows and `docs/versioning.md` are updated to match. ## How verified - `bash -n scripts/release_upload.sh`; `py_compile` of the test. - `tests/test_release_scripts.py`: the stand-in `gh` now knows main's history (for compare), refuses tag moves that are not fast-forwards, can inject a race (the tag moves between a run's look and its move), and handles `gh release view/edit/delete-asset`. New tests: - moves forward while main has newer commits (old AppImage/.zsync removed, SHA256SUMS remade, `force=false`) - never goes back (Linux and Windows) - the other platform's run of the same commit adds its files without moving the tag - the two platforms move on their own - race lost to a newer commit: nothing changes - race with an older commit: still moves forward - two real runs at once, in both orders: tag ends at the newer commit, Linux's files are all from one commit - no tag yet - main rewritten ## Not tested - The test suite is not run yet. - Not run on GitHub: the fast-forward refusal and the `compare` statuses are GitHub's documented behavior, simulated by the stand-in. - actionlint and shellcheck are not available here.
Commenting is not possible because the repository is archived.
No description provided.