Skip to content

fix(release): derive release tag from the normalized Go-module subdir (v0/v1)#7

Merged
daniel-garcia merged 2 commits into
mainfrom
fix-derivetag-v1-module-path
Jun 10, 2026
Merged

fix(release): derive release tag from the normalized Go-module subdir (v0/v1)#7
daniel-garcia merged 2 commits into
mainfrom
fix-derivetag-v1-module-path

Conversation

@daniel-garcia

Copy link
Copy Markdown
Contributor

What

Release tags were derived as <api-id>/v<version>, where the api-id includes the version line
(e.g. proto/payments/ledger/v1). For the v0/v1 line that produced a tag like
proto/payments/ledger/v1/v1.0.0-alpha.1, which does not resolve as a version of the published
Go module
.

Go's semantic-import-versioning rule: a module path must not carry a /v1 suffix (only /v2+):

$ go mod init example.com/foo/proto/payments/ledger/v1
go: invalid module path: major version suffixes must be in the form of /vN and are only allowed for v2 or later

So the v1 line's module is …/proto/payments/ledger (no suffix — which apx already derives
correctly for go.mod), and its tag must therefore be proto/payments/ledger/v1.0.0-alpha.1. apx
had applied the "strip the version suffix" rule to the module path but not the tag.

This is finding #3 of #5, and the reason a freshly cut tag could not be go get-ed.

Fix

New config.DeriveTagPrefix(apiID) returns the normalized Go-module subdirectory (= DeriveGoModDir):
v0/v1 drop the line segment, v2+ keep /vN. Both the forward path (DeriveTag) and the reverse
path (TagManager.ListVersionsForAPI) route through it, so tags resolve as module versions and
forward/reverse stay consistent:

line Go module tag
v1 …/proto/payments/ledger proto/payments/ledger/v1.0.0-alpha.1
v2 …/proto/payments/ledger/v2 proto/payments/ledger/v2/v2.0.0 (unchanged)

ListVersionsForAPI also skips tags that belong to a deeper module sharing the v0/v1 prefix
(e.g. a …/v2/ tag), so each line lists only its own versions. Callers already filter by line
major via LatestVersion, so the shared v0/v1 prefix is safe.

Tests updated accordingly (TestDeriveTag incl. v0/v2 cases; tags_test fixtures now use the real
scheme and exercise the deeper-module skip; manifest/record/report assertions). go build,
go vet, and go test ./internal/... ./cmd/... . pass.

Scope

Findings #2 (finalize unwired in canonical CI) and #4 (auth login token persistence) of #5 remain
open.

Go disallows a /v1 module path suffix (only /v2+ are allowed), so the v0/v1
line's published module has no version suffix and its release tag must drop the
line segment (proto/x/v1 -> tag proto/x/v1.0.0); v2+ keep it (proto/x/v2 -> tag
proto/x/v2/v2.0.0). DeriveTag and TagManager.ListVersionsForAPI now route
through a new DeriveTagPrefix (= DeriveGoModDir) so a release tag resolves as a
version of the published Go module, and forward/reverse tag handling stay
consistent. Fixes finding #3 of #5.
The v1 line's release tag no longer carries the /v1 segment
(proto/payments/ledger/v1.0.0-beta.1); update the inspect Tag assertions and
the publish_ledger derived-tag check + setup tag. v2 tags are unchanged.
@daniel-garcia daniel-garcia merged commit 8426d64 into main Jun 10, 2026
9 of 10 checks passed
@daniel-garcia daniel-garcia deleted the fix-derivetag-v1-module-path branch June 10, 2026 12:30
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