Repository navigation
feat(release): API compatibility gate in go-package-release.yml (ADR-0017) - #22
Merged
Merged
Conversation
…0017) go-package-release.yml checks the exported API against the previous published version with a pinned gorelease and stops before the tag step when the version is rejected or the tool fails (otfabric/engineering ADR-0017, REL-003). - Previous version: the highest exact release tag of this module in the major of its module path, by semver; prerelease, moving and other-major tags never count. A base that is not an ancestor of the release commit, or whose go.mod names another module, fails; no other base is chosen. - Majors: v2+ needs the /vN module path; a first /vN release is vN.0.0. First releases use -base=none. - Results: pass, incompatible, or error (tool not installed, base not downloadable, dirty tree), never read as a pass. api-compatibility: enforce (default) stops; report warns, for staged adoption. - v0: a patch changes no exported API; a breaking minor or major needs a "### Breaking" heading in its RELEASE.md section. - Nested modules: module-dir, tags <dir>/vX.Y.Z. - release-evidence.json (artifact and release asset): commit, module, versions, gorelease result and changes, Go, vet/test/race, consumers, exceptions, baseline, and the checks this job does not run. - consumers: optional read-only job that builds, vets and tests direct dependants against the candidate; the token exists only in the fetch step, and consumer code builds offline. A failure names the consumer, its revision, the required version and the candidate commit. - Workflow permissions drop to contents: read; the release job keeps write. Selftest: scripts/selftest/release-gate.sh (48 checks over the D7 cases, file:// module proxy, no tag pushed) and consumers.sh (14 checks); new jobs release-gate and release-consumers. README documents the inputs, the gate and the api-result output. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Summary
go-package-release.ymlnow checks the exported API against the previous published version with a pinnedgorelease, and stops before Create and push annotated tag when the version is rejected or the tool fails. This implements ADR-0017 (accepted 2026-11-14) and REL-003 of otfabric/engineering policy 1.6 (companion PR: https://github.com/otfabric/engineering/pull/125).Today the workflow runs tidy, vet and tests and then tags. It picks the previous version with
git tag -l 'v[0-9]*.[0-9]*.[0-9]*' | sort -V | tail -1, which also matches prerelease tags, and onbump: majorit tagsv2.0.0for a module path without/v2.Behaviour
vX.Y.Z, or<module-dir>/vX.Y.Z), in the major of its module path, compared by semver. Prereleases, moving tags and other majors' tags never count. A base that is not an ancestor of the release commit, or whosego.modnames another module, fails; no other base is picked./vNmodule path. A first/vNrelease isvN.0.0, and first releases use-base=none.pass,incompatible, orerror(tool missing, base not downloadable, dirty tree). Anerroris never read as a pass. Withapi-compatibility: enforce(the default) the job stops;reportwarns and releases, and exists for staged adoption only.### Breakingin itsRELEASE.mdsection.module-dir, with tags<dir>/vX.Y.Z.release-evidence.jsonis uploaded as an artifact and attached as a release asset. It records the commit, module, previous and proposed versions, the gorelease result and its changes, Go version, vet/test/race, consumers, exceptions, baseline, release-notes source, and the checks this job does not run (coverage, govulncheck, lint, fuzz, interop).replacein a temporary clone. The read token exists only in the fetch step, and consumer code builds offline. A failure names the consumer, its revision, the version it requires and the candidate commit, and the release job does not run.contents: readat workflow level;contents: writeonly on the release job.module-dir,api-compatibility,gorelease-version(exact pseudo-version, neverlatest),gorelease-go-version,consumers. New output:api-result. Existing callers keep working: the new inputs have defaults and the root-module behaviour is unchanged except for the gate.Selftest
scripts/selftest/release-gate.shruns 48 checks with the exact step scripts on fixture repositories, with "published" versions in afile://module proxy; no tag is pushed. It covers:/v2fails;/v2release;GOPROXY=offgiveerror, notincompatible;scripts/selftest/consumers.shruns 14 checks: a consumer that no longer compiles is reported with its revision; clone failures and path escapes are reported, not skipped; the token is limited to the fetch step.release-gate(Go 1.26, installs the pinned gorelease read from the workflow default) andrelease-consumers.@latestor running the tag step after a failure, each make the selftest fail.scripts/selftest/pass; the YAML parses; every step passesbash -n;otfabric-policy checkreports compliant.if:expressions, artifact upload and download, and the release asset are first exercised by this PR's Selftest run.Release
The maintainer should tag v3.8.0 after merge. v3.7.0 (6334e54) has no gate, and REL-003 requires v3.8.0 or later.
🤖 Generated with Claude Code