Skip to content

fix(release): an unstable version must outrank its stable baseline - #584

Merged
rubenvdlinde merged 1 commit into
mainfrom
fix/unstable-version-must-outrank-the-stable-baseline
Aug 27, 2026
Merged

fix(release): an unstable version must outrank its stable baseline#584
rubenvdlinde merged 1 commit into
mainfrom
fix/unstable-version-must-outrank-the-stable-baseline

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Closes the generating half of defect 2. The guard (#566) already blocks these merges — this stops them being created.

The defect

The unstable branch reused the stable baseline verbatim:

UNSTABLE_VERSION="${STABLE}-unstable.${TIMESTAMP}"

That is a downgrade by construction. A prerelease sorts below the release of the same core version:

0.2.0-unstable.20260827023555  <  0.2.0

It stayed invisible while an app's development sat on a prerelease of its own — X-unstable.<old ts>X-unstable.<new ts> moves forward. The moment development carried a stable version, every release this job opened proposed to move the app backwards.

Five apps are in that state today, derived mechanically (no prerelease suffix in development's <version>), not from a remembered list:

app development
integriq 0.3.4
thematiq 1.1.0
humaniq 0.2.0
versioniq 1.4.1
planninq 0.2.13

The fix

The beta branch immediately below already computed this correctly — its own comment says "Beta is always one patch ahead of stable" — and was never affected. Unstable was the odd one out. This makes it agree.

Verification

Ran both computations over all five stable baselines plus a prerelease one, and compared semver-aware:

baseline old new
0.3.4 0.3.4-unstable.… DOWNGRADE 0.3.5-unstable.… forward
1.1.0 1.1.0-unstable.… DOWNGRADE 1.1.1-unstable.… forward
0.2.0 0.2.0-unstable.… DOWNGRADE 0.2.1-unstable.… forward
1.4.1 1.4.1-unstable.… DOWNGRADE 1.4.2-unstable.… forward
0.2.13 0.2.13-unstable.… DOWNGRADE 0.2.14-unstable.… forward
1.0.9 1.0.9-unstable.… DOWNGRADE 1.0.10-unstable.… forward

(that comparison is against the stable baseline — which is the operative comparison exactly when development has reached it)

And it stays monotonic against a prerelease head, which is the case that was already working and must not regress:

1.0.9-unstable.20260826010101  ->  1.0.10-unstable.20260827093000   forward

What this does not change

Stable releases are computed separately via action-bump-semver from the latest stable tag — untouched. The only change is that an unstable build now numbers itself as a preview of the next patch rather than of the one already released, which is what the scheme meant all along.

Related

  • fix(release): drop [skip ci] so the required check can run #578 dropped [skip ci], which was defect 1 (the bump commit suppressed the single required check, so auto-merge could never fire).
  • Gate 2 — org-level action_required approval on app/github-actions runs — remains open by decision; it is swept manually each cycle (83 runs approved today).

The unstable branch reused the stable baseline verbatim:

    UNSTABLE_VERSION="${STABLE}-unstable.${TIMESTAMP}"

That is a downgrade by construction. A prerelease sorts BELOW the
release of the same core version, so 0.2.0-unstable.20260827023555
is LESS than 0.2.0.

It stayed invisible while an app's development sat on a prerelease of
its own. The moment development carried a stable version, every release
this job opened proposed to move the app backwards. Five apps are in
that state today: integriq 0.3.4, thematiq 1.1.0, humaniq 0.2.0,
versioniq 1.4.1, planninq 0.2.13.

The beta branch immediately below already computed it correctly --
"Beta is always one patch ahead of stable" -- and was never affected.
This makes unstable agree with it.

Measured over all five stable baselines plus a prerelease one: 0 of 6
now compute a downgrade, and the result still moves forward against a
prerelease development head (1.0.9-unstable.<old> -> 1.0.10-unstable.<new>).
@rubenvdlinde

Copy link
Copy Markdown
Contributor Author

Correction: this was not sufficient, and I said it closed defect 2. It did not.

It bumps the patch of the stable baseline, but that baseline comes from the latest stable tag, which on six apps trails development — e.g. versioniq's tag is v1.2.0 while development is 1.4.1, so this still computes 1.2.1-unstable.<ts>, below what is shipping.

Simulated over all 21 apps' real tags and development versions: 6 of 21 still downgrade with this merged. Taking the max of the baseline and the branch's own version gives 0 of 21. Follow-up opened.

Also worth recording: shillinq is affected and my original enumeration missed it, because I selected apps by "does development carry a stable version" — shillinq's is a prerelease. The right condition is "has development outrun the latest tag", a strictly larger set.

rubenvdlinde added a commit that referenced this pull request Aug 27, 2026
…589)

#584 was not enough, and I merged it saying it closed defect 2. It did
not. This is the correction.

#584 made the unstable version one patch ahead of the STABLE BASELINE.
But that baseline comes from the latest stable tag (or main's info.xml),
and on several apps it trails `development` badly:

    thematiq   tag v1.0.0   development 1.1.0
    versioniq  tag v1.2.0   development 1.4.1
    planninq   tag v0.1.3   development 0.2.13
    shillinq   tag v0.1.9   development 0.2.1-unstable.*
    integriq   no tag       development 0.3.4
    humaniq    no tag       development 0.2.0

Bumping the patch of a baseline that already trails still lands below
what is shipping: 1.2.1-unstable.<ts> is less than 1.4.1.

Taking the max of the baseline and the branch's own version is what
actually closes it.

Simulated against all 21 apps' real tags and development versions:

    downgrades with #584 as merged     6 / 21
    downgrades with the baseline max   0 / 21

The six are integriq, thematiq, shillinq, humaniq, versioniq, planninq.
shillinq is a sixth app the earlier analysis missed entirely: its
development carries a PRERELEASE, so it passed the "does development
carry a stable version" test, yet its tag trails anyway. The real
condition was never "development is stable" -- it is "development has
outrun the latest tag", which is a strictly larger set.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
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