Skip to content

feat(version): add force-stable and create-rc-baseline inputs - #24

Merged
gamechanger1s merged 3 commits into
mainfrom
feat/version-stable-mode
Aug 18, 2026
Merged

gamechanger1s merged 3 commits into
mainfrom
feat/version-stable-mode

Conversation

@gamechanger1s

@gamechanger1s gamechanger1s commented Aug 17, 2026 •

Copy link
Copy Markdown
Contributor

What

Three new opt-in inputs on .github/workflows/version.yml, all defaulting to preserve current behaviour:

  • force-stable (default false) — when true, non-default branches cut a stable release instead of a -rc.N prerelease. Passes --ci-condition-opt "defaultBranch=<current-ref>" so semrel's condition-github plugin accepts the non-default branch.
  • create-rc-baseline (default true) — gates the existing "Create next RC baseline" step on the default branch. Set to false when the RC line is no longer maintained (typical sibling to force-stable: true on the RC-side workflow).
  • expose-latest-on-noops (default false) — when semrel exits with no new release (rubber-stamp merges where the tag already exists), populate outputs.version from gh release list instead of leaving it empty. Prevents downstream build/deploy/announce steps from falling back to a stale git describe result across divergent merges.

Why

Support a "non-default branch owns version cutting, default branch rubber-stamps deploy" release model — one SemVer number per deployable artifact, born on the RC branch and consumed by the default branch. Today version.yml hardcodes --prerelease on non-default branches, RC baseline seeding on the default branch, and only exposes a version when a new tag is cut. None can be opted out of. These three inputs let a caller adopt the model without changing anything for existing consumers.

Verified

Piloted end-to-end on a downstream consumer:

  • Non-default branch cut a stable release via force-stable: true.
  • Default branch merge triggered semrel to look up the latest release (found version: <tag> / no change) — rubber-stamp confirmed.
  • Follow-up commit fixes the condition-github guard for non-default branches (needed --ci-condition-opt).
  • Follow-up commit adds expose-latest-on-noops after git describe returned the wrong tag on the default-branch merge commit (closer by rev-list distance than the actual latest tag on the divergent branch).

Two new opt-in inputs on the reusable version.yml workflow, both
defaulting to preserve current behaviour so existing consumers are
byte-identical.

- force-stable (default false): when true, non-default branches skip
  the --prerelease --maintained-version flags and cut a stable release
  the same way the default branch does. Enables a "dev cuts the version,
  default branch rubber-stamps the deploy" model where the RC line is
  not maintained.

- create-rc-baseline (default true): gates the "Create next RC baseline"
  step on the default branch. Set to false when the RC line is not
  maintained (typically alongside force-stable=true on the RC-side
  workflow), preventing orphan vX.Y.0-rc.1 tags from piling up.

Backwards-compatible minor change — no consumer needs to update inputs.
The condition-github plugin refuses a non-default branch with
"configured to only publish from <default>" unless the config passed
to it says otherwise. Semrel's main.go forwards repoInfo.DefaultBranch
(fetched from the GitHub API) as the ci-condition's defaultBranch by
default; the previous force-stable path didn't override it, so semrel
exited with code 66 before cutting the tag.

Fix: pass --ci-condition-opt "defaultBranch=$CURRENT_REF" when
force-stable=true on a non-default branch. This makes the condition
see branch==defaultBranch and proceed. The RC prerelease path was
implicitly relying on --maintained-version setting defaultBranch to "*"
inside semrel core, so it didn't need this workaround.

Verified failure: ago-web-frontend run 32020117652 exited at the ci
condition step with the "only publish from main" error.
@gamechanger1s

gamechanger1s commented Aug 17, 2026 •

Copy link
Copy Markdown
Contributor Author

Follow-up commit (eb22969) on feat/version-stable-mode — fixes a bug found during E2E testing.

Bug: force-stable: true alone wasn't enough. semrel's condition-github plugin refuses non-default branches with this test run was triggered on the branch dev, while semantic-release is configured to only publish from main. Only the RC prerelease path passed this check (because --maintained-version implicitly sets defaultBranch to *).

Fix: when force-stable: true, pass --ci-condition-opt "defaultBranch=$CURRENT_REF" so the CI condition sees branch == defaultBranch and proceeds.

In the rubber-stamp release model, the default branch merges an
already-tagged branch and semrel correctly exits with "no change"
(the release exists via GH API lookup, no new bump needed). Downstream
build/deploy/announce steps that fall back to \`git describe\` when
outputs.version is empty can pick the WRONG tag: rev-list distance
between HEAD and the actual latest tag can be huge across a divergent
merge (all the docs: changelog auto-commits + hotfix merges on the
default branch that aren't reachable from the tag's commit).

Fix: opt-in input that populates outputs.version from GH's release
list on no-op, using the same source semrel uses when it looks up
the "latest release". Callers set expose-latest-on-noop: true on the
default-branch's version job to guarantee outputs.version reflects
the actual latest stable release, not whatever git describe returns.

Default false preserves existing behaviour for all consumers.

Verified failure: AmericanGunOwners/ago-web-frontend PR #645 merge —
main pipeline no-oped correctly, but git describe returned v1.17.0
(6 commits away via first-parent) instead of v1.18.0 (58 commits away
by rev-list distance, but only 1 hop via second-parent). Prod
/version.json ended up stamped 1.17.0 despite v1.18.0 being the
actual latest release.
@gamechanger1s
gamechanger1s force-pushed the feat/version-stable-mode branch from 4a4a6d4 to 0bdf9ba Compare August 17, 2026 11:24
@gamechanger1s
gamechanger1s merged commit 090a42e into main Aug 18, 2026
1 check passed
@gamechanger1s
gamechanger1s deleted the feat/version-stable-mode branch August 18, 2026 07:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant