Release: dev → main (first public release) #258

Merged
bvandeusen merged 94 commits from dev into main 2026-09-25 10:02:40 -04:00
2 changed files with 21 additions and 8 deletions
Showing only changes of commit 4fa7975963 - Show all commits
+17 -7
View File
@@ -142,6 +142,16 @@ concurrency:
# Deriving it per job invites the two halves to disagree: sign-extension would # Deriving it per job invites the two halves to disagree: sign-extension would
# derive dev's extension version while build-web bundled main's, and the # derive dev's extension version while build-web bundled main's, and the
# release download would 404 on a version that exists perfectly well. # release download would 404 on a version that exists perfectly well.
#
# On every other trigger it is the COMMIT that fired (`github.sha`), never the
# branch name. A branch is re-resolved by each job's checkout when that job
# starts, so a push landing mid-run moved the later jobs onto the new tip: run
# 7499 signed 423275a's extension, then build-web checked out 83e1382 (pushed
# while 7499 ran), derived a version nobody had signed, and 404'd on the
# download (#4427). The guard failed closed that time; a job without one would
# have published a commit the run's own lanes never tested — the lanes check
# out `github.sha` by default, so pinning here makes the publish build exactly
# what they passed.
# IS THIS A BASE REFRESH? Asked in five places and previously spelled five # IS THIS A BASE REFRESH? Asked in five places and previously spelled five
# ways — `github.event_name == 'schedule'` in an `if:`, `$GITHUB_EVENT_NAME` in # ways — `github.event_name == 'schedule'` in an `if:`, `$GITHUB_EVENT_NAME` in
# one shell, an `EVENT:` env passed into another, and a bare expression on # one shell, an `EVENT:` env passed into another, and a bare expression on
@@ -178,7 +188,7 @@ concurrency:
# where a step-level `if:` needs the answer before any shell runs. # where a step-level `if:` needs the answer before any shell runs.
env: env:
IS_REFRESH: ${{ (github.event_name == 'schedule' || format('{0}', github.event.inputs.refresh) == 'true') && 'true' || 'false' }} IS_REFRESH: ${{ (github.event_name == 'schedule' || format('{0}', github.event.inputs.refresh) == 'true') && 'true' || 'false' }}
BUILD_REF: ${{ (github.event_name == 'schedule' || format('{0}', github.event.inputs.refresh) == 'true') && 'main' || github.ref }} BUILD_REF: ${{ (github.event_name == 'schedule' || format('{0}', github.event.inputs.refresh) == 'true') && 'main' || github.sha }}
# Requires repo secret RELEASE_TOKEN — a Forgejo PAT with scopes: # Requires repo secret RELEASE_TOKEN — a Forgejo PAT with scopes:
# - write:package, read:package (for docker push to git.fabledsword.com) # - write:package, read:package (for docker push to git.fabledsword.com)
@@ -605,8 +615,8 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
# Not the triggering ref — see the `env:` block at the top. On a # Not the triggering ref — see the `env:` block at the top. On a
# scheduled refresh this is `main`; on everything else it is the ref # scheduled refresh this is `main`; on everything else it is the
# that fired, so this is a no-op on every ordinary path. # commit that fired, the same one the lanes above tested.
ref: ${{ env.BUILD_REF }} ref: ${{ env.BUILD_REF }}
# Full history is load-bearing, not a convenience: the version this # Full history is load-bearing, not a convenience: the version this
# job signs is derived from the commit TIME of the newest packaged # job signs is derived from the commit TIME of the newest packaged
@@ -945,8 +955,8 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
# Not the triggering ref — see the `env:` block at the top. On a # Not the triggering ref — see the `env:` block at the top. On a
# scheduled refresh this is `main`; on everything else it is the ref # scheduled refresh this is `main`; on everything else it is the
# that fired, so this is a no-op on every ordinary path. # commit that fired, the same one the lanes above tested.
ref: ${{ env.BUILD_REF }} ref: ${{ env.BUILD_REF }}
# Full history: this job RE-DERIVES the extension version rather than # Full history: this job RE-DERIVES the extension version rather than
# being handed it, and a depth-1 clone derives a wrong, too-low value # being handed it, and a depth-1 clone derives a wrong, too-low value
@@ -2174,8 +2184,8 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
# Not the triggering ref — see the `env:` block at the top. On a # Not the triggering ref — see the `env:` block at the top. On a
# scheduled refresh this is `main`; on everything else it is the ref # scheduled refresh this is `main`; on everything else it is the
# that fired, so this is a no-op on every ordinary path. # commit that fired, the same one the lanes above tested.
ref: ${{ env.BUILD_REF }} ref: ${{ env.BUILD_REF }}
# Full history: this job derives its artifact's version from the # Full history: this job derives its artifact's version from the
# commit its shipped files last changed in (milestone 313). A # commit its shipped files last changed in (milestone 313). A
+4 -1
View File
@@ -180,7 +180,10 @@ per `docs/process.md`'s "add deps to the image when used by >1 project".
BUILD_REF` that every checkout in the file takes, rather than per job — BUILD_REF` that every checkout in the file takes, rather than per job —
otherwise `sign-extension` would derive dev's extension version while otherwise `sign-extension` would derive dev's extension version while
`build-web` bundled main's, and the release download would 404 on a version `build-web` bundled main's, and the release download would 404 on a version
that exists perfectly well. Every job then ASSERTS its checkout is `main` that exists perfectly well. On every other trigger `BUILD_REF` is the
triggering COMMIT (`github.sha`), not the branch: a branch is re-resolved
per job, so a push landing mid-run used to move the publishing jobs onto a
commit the run's lanes never tested (run 7499, #4427). Every job then ASSERTS its checkout is `main`
before doing anything, because `env` inside `with:` is not a context this before doing anything, because `env` inside `with:` is not a context this
runner is known to evaluate — if it silently resolved to empty, checkout runner is known to evaluate — if it silently resolved to empty, checkout
would fall back to the triggering ref and the refresh would publish dev's would fall back to the triggering ref and the refresh would publish dev's