fix(release): an unstable version must outrank its stable baseline - #584
Conversation
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>).
|
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 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: |
…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>
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:
It stayed invisible while an app's
developmentsat on a prerelease of its own —X-unstable.<old ts>→X-unstable.<new ts>moves forward. The momentdevelopmentcarried 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:development0.3.41.1.00.2.01.4.10.2.13The 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:
0.3.4-unstable.…0.3.5-unstable.…1.1.0-unstable.…1.1.1-unstable.…0.2.0-unstable.…0.2.1-unstable.…1.4.1-unstable.…1.4.2-unstable.…0.2.13-unstable.…0.2.14-unstable.…1.0.9-unstable.…1.0.10-unstable.…(that comparison is against the stable baseline — which is the operative comparison exactly when
developmenthas reached it)And it stays monotonic against a prerelease head, which is the case that was already working and must not regress:
What this does not change
Stable releases are computed separately via
action-bump-semverfrom 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
[skip ci], which was defect 1 (the bump commit suppressed the single required check, so auto-merge could never fire).action_requiredapproval onapp/github-actionsruns — remains open by decision; it is swept manually each cycle (83 runs approved today).