Make the Go adapter modules actually resolvable, and gate the four publishes - #103
Merged
Conversation
…blishes
`go/fiber` and `go/gin` are separate Go modules that both carried:
require github.com/SmooAI/observability/go v0.0.0
replace github.com/SmooAI/observability/go => ../
Go honours `replace` only in the MAIN module's go.mod. In a PUBLISHED module it
is invisible: a consumer running `go get .../go/fiber@vX` resolves the core at
`v0.0.0`, a version that has never existed, and fails. Both adapters were
unpublishable, and nothing in the repo could tell — inside the repo the replace
makes everything build.
Demonstrated rather than assumed: dropping the replace on a scratch copy and
building reproduces the consumer's exact error,
go: downloading github.com/SmooAI/observability/go v0.0.0
reading .../go.mod at revision go/v0.0.0: unknown revision go/v0.0.0
Fix: the adapters now require the core at its real released version and carry NO
replace. `go/go.work` supplies the sibling source for local builds and CI, and a
workspace is not published. (The replace has to be version-specific — Go rejects
an all-versions replace of a workspace module — so the go.work line is
version-bearing too and joins sync-versions.mjs's TARGETS, alongside both
require lines. 14 files now, up from 11.)
`scripts/check-go-modules.sh` is the guard, run by BOTH pr-checks and the
publish gate so the two cannot drift:
1. no `replace` in any published go.mod
2. each module path matches its directory
3. Spec B's /vN rule, checked in BOTH directions — a major >= 2 must carry the
suffix, a 0.x/1.x must not. It reads the major from package.json, so it
flips over automatically at the 2.0 bump instead of waiting to be
remembered. Today it asserts the suffix is ABSENT, which is correct at
0.19.x and is the check that would have caught fetch/file/logger.
Negative-controlled by hand: adding a replace back to go/fiber exits 1; setting
package.json to 2.0.0 exits 1 naming all three modules.
publish.yml also gains:
- `go/fiber/v*` and `go/gin/v*` tag triggers, and a `go` job condition widened
to `refs/tags/go/` — the adapters had no way to be published at all
- a `verify` gate every publish job depends on: all 14 version-bearing files
agree with package.json AND the tag names that same version. A mistyped tag
now fails on a bare runner before any toolchain boots, which matters because
crates.io/PyPI/NuGet publishes are irreversible
- `cargo package/publish --locked` instead of bare. --locked, never
--allow-dirty: a publish that has to mutate the lockfile is publishing
something the tag never built
- proxy warming that derives the module path from the tag and retries, so it
serves all three modules and a slow proxy no longer reports a good release as
broken
RELEASING.md documents the whole sequence, including the ordering constraint
that falls out of the above: `go/vX` must be tagged and on the proxy BEFORE
`go/fiber/vX` and `go/gin/vX`, because the adapters require it.
DELIBERATELY NOT DONE: no first publish. crates.io, PyPI and NuGet first
publishes are irreversible and are the user's call. Names verified free on all
three; dry runs all clean (`cargo publish --dry-run --locked` packaged 29 files
and built from the tarball, `uv build` + `twine check` PASSED on both artifacts,
`dotnet pack` produced .nupkg + .snupkg with README and all three TFMs). The
repo is one `git tag && git push` per language away.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC
|
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.
The Go adapters could never have been published
go/fiberandgo/ginare separate Go modules. Both carried:Go honours
replaceonly in the main module's go.mod. In a published module it is invisible: a consumer runninggo get github.com/SmooAI/observability/go/fiber@vXresolves the core atv0.0.0— a version that has never existed — and fails.Nothing in the repo could tell, because inside the repo the replace makes everything build.
Demonstrated, not assumed. Dropping the replace on a scratch copy reproduces the consumer's exact error:
Fix
The adapters now
requirethe core at its real released version and carry noreplace.go/go.worksupplies the sibling source for local builds and CI — and a workspace is not published.The workspace replace has to be version-specific (Go rejects an all-versions replace of a workspace module), so that line is version-bearing too and joins
sync-versions.mjs's TARGETS along with bothrequirelines. 14 files now, up from 11.The guard
scripts/check-go-modules.sh, run by bothpr-checks.ymland the publish gate so the two cannot drift:replacein any publishedgo.mod/vNrule, checked in both directions — a major ≥ 2 must carry the suffix, a 0.x/1.x must not. It reads the major frompackage.json, so it flips over automatically at the 2.0 bump instead of waiting to be remembered. Today it asserts the suffix is absent, correct at 0.19.x, and it is the check that would have caught the fetch/file/logger defect.Negative-controlled by hand: adding a
replaceback togo/fiberexits 1; settingpackage.jsonto2.0.0exits 1 naming all three modules.publish.yml
go/fiber/v*andgo/gin/v*tag triggers, and thegojob condition widened torefs/tags/go/. The adapters previously had no way to be published at all —go/v*does not glob-matchgo/fiber/v0.19.2.verifygate every publish job depends on: all 14 version-bearing files agree withpackage.json, and the tag names that same version. A mistyped tag now fails on a bare runner before any toolchain boots — which matters, because crates.io/PyPI/NuGet publishes are irreversible.cargo package/publish --lockedinstead of bare.--locked, never--allow-dirty: a publish that has to mutate the lockfile is publishing something the tag never built.RELEASING.mddocuments the sequence, including the ordering constraint that falls out of the above:go/vXmust be tagged and on the proxy beforego/fiber/vXandgo/gin/vX.Release readiness — and what is deliberately NOT done
No first publish. crates.io, PyPI and NuGet first publishes are irreversible and are the user's call.
Verified ready:
smooai-observabilitydoes not existcargo publish --dry-run --lockeduv build+twine checkdotnet pack.nupkg+.snupkg, README embedded, all three TFMscheck-go-modules.shclean, all three build and testThe repo is one
git tag && git pushper language away. SeeRELEASING.md.🤖 Generated with Claude Code
https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC