ci: gate the public API against the published release, and stop the pins drifting - #63
Merged
Conversation
…ins drifting Eleven crates are on crates.io at 2.1.0 -- the issue said ten -- and no workflow ran cargo-semver-checks. Removing a `pub fn` from `launchbound-space` shipped without a signal. ## Why the release type is forced Measured, not assumed. Removing `Config::kernel` from launchbound-space while bumping the manifest to 3.0.0 in the same PR: inferred "0 checks: 0 pass, 254 skip" exit 0 --release-type patch "1 major and 0 minor checks failed" exit 100 cargo-semver-checks compares the manifest version to the baseline and runs only the lints that bump would not already excuse. Declare the major bump in the same commit as the break and it has nothing left to say -- the gate ends up agreeing with whatever the PR claims about itself. `patch` means "no API change of any kind is excused", so every lint fires. `patch` does NOT forbid additions: cargo-semver-checks reports breaking changes only. Verified against this branch, which carries #61's `pub use Summary` and #62's `known_capabilities()`: 223 checks, 223 pass. A deliberate break carries the new `breaking` label, which switches the job to `major`. Three of the eleven published crates are binary-only (cli, tui, runner) and have no library API; the eight that do are covered by `--workspace`. cargo-semver-checks arrives as a prebuilt binary through the same install-action the rest of this workflow uses -- never built from source, never restored from a cache. ## The pins were not only cosmetic `[workspace.dependencies]` pinned the path crates at 2.0.0 while `workspace.package.version` was 2.1.0, so `launchbound-prune` 2.1.0 declared compatibility with a `launchbound-space` release it was never built against. Harmless for a path build, which is why it survived the whole 2.1.0 line. Not harmless for the next major: with the pins at 2.0.0, bumping the workspace to 3.0.0 makes `cargo metadata` refuse outright -- failed to select a version for the requirement `launchbound-build = "^2.0.0"` candidate versions found which didn't match: 3.0.0 -- which I hit while building the experiment above. The drift breaks the release after next, not this one, which is the worst kind. `scripts/check-versions.sh` (in `just ci`, beside `check-pins.sh` and bash-3.2-portable for the macOS leg) asserts the workspace version, the eight internal pins, and that no crate sets a literal version of its own. Both failure shapes were exercised: a pin left at 2.0.0, and a crate replacing `version.workspace = true` with a literal. ## docs/RELEASING.md Step 1 now says to bump the pins with the version, and `baseline-version` gets its own step after the publish: left at the old release it compares against a version nobody can install and carries this release's own breaks forward; moved before the publish it names one that does not exist yet. Closes #56 Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com>
This was referenced Sep 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Milestone 2.2.0, issue #56.
Eleven crates are on crates.io at 2.1.0 — the issue said ten — and no workflow ran
cargo-semver-checks. Removing apub fnfromlaunchbound-spaceshipped without a signal.Why
--release-typeis forced, measured rather than assumedRemoving
Config::kernelfromlaunchbound-spacewhile bumping the manifest to 3.0.0 in the same PR:0 checks: 0 pass, 254 skip— "no semver update required"--release-type patch1 major and 0 minor checks failed— namesConfig::kernelcargo-semver-checkscompares the manifest version to the baseline and runs only the lints that bump would not already excuse. Declare the major bump in the same commit as the break and it has nothing left to say — the gate agrees with whatever the PR claims about itself. That is exactly the done-when this issue asked for.patchmeans "no API change of any kind is excused", so every lint fires. It does not forbid additions —cargo-semver-checksreports breaking changes only. Verified against this branch, which carries #61'spub use Summaryand #62'sknown_capabilities(): 223 checks, 223 pass.A deliberate break carries the new
breakinglabel, which switches the job tomajor.Three of the eleven published crates are binary-only (
cli,tui,runner) and have no library API; the eight that do are covered by--workspace.cargo-semver-checksarrives as a prebuilt binary through the sameinstall-actionthe rest of the workflow uses — never built from source, never restored from a cache.The pins were not only cosmetic
[workspace.dependencies]pinned the path crates at2.0.0whileworkspace.package.versionwas2.1.0, solaunchbound-prune2.1.0 declared compatibility with alaunchbound-spacerelease it was never built against. Harmless for a path build — which is why it survived the whole 2.1.0 line.Not harmless for the next major. With the pins at 2.0.0, bumping the workspace to 3.0.0 makes
cargo metadatarefuse outright:I hit that while building the experiment above. The drift breaks the release after next, not this one — the worst kind.
scripts/check-versions.sh(injust ci, besidecheck-pins.sh, bash-3.2-portable for the macOS leg) asserts the workspace version, the eight internal pins, and that no crate sets a literal version of its own. Both failure shapes were exercised:docs/RELEASING.mdStep 1 now says to bump the pins with the version.
baseline-versiongets its own step after the publish: left at the old release it compares against a version nobody can install and carries this release's own breaks forward as if new; moved before the publish it names a version that does not exist yet and the job cannot fetch it.One thing this PR does not fix
mainhas no branch protection at all (gh api .../branches/main/protection→ 404). So this gate — and every other — reports rather than blocks; a red PR can still be merged. The milestone is called "a gate that can fail", and a gate nothing requires is half of one. I have not changed repo settings, since that is your call, but reconverge has protection and this repo does not.Closes #56
Signed-off-by: Vyncint Ng 115854244+vyncint@users.noreply.github.com