diff --git a/.github/workflows/vendor.yml b/.github/workflows/vendor.yml index a79596d..f7580c1 100644 --- a/.github/workflows/vendor.yml +++ b/.github/workflows/vendor.yml @@ -442,3 +442,26 @@ jobs: --notes "Static build toolchain $tag — clang/make/git built from source; bpftool/esbuild/libbpf headers re-hosted; qemu for the kernel-matrix runner." # --clobber so a same-version re-run refreshes assets. gh release upload "$tag" dist/* --clobber + + - name: Open maintenance branch for a new minor/major line + if: steps.ver.outputs.skip != 'true' && github.ref_name == 'master' + run: | + set -euo pipefail + # When master cuts a NEW line (vX.Y.0), fork release/vX.Y at the same + # immutable commit so future back-ports have somewhere to land. + # Patches (vX.Y.Z, Z>0) and flavor builds (vX.Y.Z-) don't open + # a line. Creating the branch is safe: the branch-creation push is + # ignored by the detect guard, so it won't cut a spurious release. + ver="${TC}" + case "$ver" in *-*) echo "flavor build ($ver) — no maintenance branch"; exit 0 ;; esac + if [ "${ver##*.}" != 0 ]; then echo "patch release ($ver) — no new line"; exit 0; fi + br="release/v${ver%.*}" # release/vX.Y + if git ls-remote --exit-code --heads origin "$br" >/dev/null 2>&1; then + echo "$br already exists — leaving it"; exit 0 + fi + # HEAD is the immutable lock commit the v${ver} tag points at. + if git push origin "HEAD:refs/heads/${br}"; then + echo "opened maintenance branch ${br} at $(git rev-parse --short HEAD)" + else + echo "::warning::could not open ${br} (ruleset/permissions?) — create it manually if a back-port is needed" + fi diff --git a/README.md b/README.md index 1c96748..c15ff39 100644 --- a/README.md +++ b/README.md @@ -90,21 +90,23 @@ real toolchain change. ### Back-patching an older line -To ship a fix on an older release while `master` has moved on, branch the line -from its tag and push fixes there: +Every time `master` cuts a new line (`vX.Y.0`), CI **auto-opens** the +`release/vX.Y` maintenance branch at that commit (patches and flavor builds +don't open a line). So to ship a fix on an older release while `master` has +moved on, just PR it into the existing branch: ``` -git branch release/v0.6 v0.6.0 && git push origin release/v0.6 -# PR the fix into release/v0.6, then merge +# release/v0.6 already exists (opened when v0.6.0 was cut) +# open a PR against release/v0.6, then merge (rebase) ``` -A push to `release/*` runs the same workflow, but the version is computed from -the highest tag **reachable on that branch** — so a fix on `release/v0.6` -(forked at `v0.6.0`) publishes `v0.6.1`, independent of whatever `master` is on. -On `release/*` an unmarked commit defaults to a **patch** bump (not minor), so a -hotfix can't accidentally collide with a mainline minor tag; use `[bump:minor]` -/`[bump:major]` to override. The branch name is convention only — `release/vX.Y` -(the minor line) is the natural granularity since patches walk it forward. +A push to `release/*` runs the same workflow, but the version is scoped **by +name** to that line's tags — so a fix on `release/v0.6` publishes `v0.6.1`, +independent of whatever `master` is on. On `release/*` an unmarked commit +defaults to a **patch** bump (not minor), so a hotfix can't accidentally collide +with a mainline tag; use `[bump:minor]`/`[bump:major]` to override. (If a line +predates auto-creation, fork it manually: `git branch release/vX.Y vX.Y.0 && +git push origin release/vX.Y`.) ### Flavored variants diff --git a/build/versions.env b/build/versions.env index 0db349e..a04fd4c 100644 --- a/build/versions.env +++ b/build/versions.env @@ -4,7 +4,9 @@ # Toolchain bundle version. Each publish is an immutable, version-tagged # release `v` holding the whole set; consumers pin this one # number, and the cache is keyed by it (cache/yeet/toolchain/v//). CI -# bumps it by 0.1 on every publish (which only happens when build/ changes). +# sets it to the next semver tag it computes from the [bump:*] commit markers +# (default minor; see the README). A release is cut only when build/ or the +# vendor workflow changes. TOOLCHAIN_VERSION=0.1 # Where a consumer fetches assets from: the version-tagged release. The fetch