From ab502a717432e4906d8c1d6cb6dc6be726fc0ff9 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 4 Nov 2026 13:39:08 +0100 Subject: [PATCH] DLV-C3r1: a group's Go package version is keyed by the module path go-package-registry's published names The seat's contract now carries the Go module path, so the checker no longer works it out from the artifact's paths, which could disagree with it. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig --- .../mesh-delivery-checker/integration_test.go | 2 +- .../internal/check/pins_test.go | 20 +++++++-- .../internal/check/tagwanted.go | 41 +++++-------------- 3 files changed, 27 insertions(+), 36 deletions(-) diff --git a/modules/mesh-delivery-checker/cmd/mesh-delivery-checker/integration_test.go b/modules/mesh-delivery-checker/cmd/mesh-delivery-checker/integration_test.go index fb88e588..719773f5 100644 --- a/modules/mesh-delivery-checker/cmd/mesh-delivery-checker/integration_test.go +++ b/modules/mesh-delivery-checker/cmd/mesh-delivery-checker/integration_test.go @@ -896,7 +896,7 @@ func TestAMemberNamingAMeshSDKCommitOffTheTrunkIsJudgedAndNotRefused(t *testing. if v, err := b.buckets[delivery.CheckerVerdictsBucket].Get(b.ctx, key); err == nil && !strings.Contains(string(v.Value()), `"running"`) { t.Fatalf("the group was judged before its tagged version was published: %s", v.Value()) } - published, _ := json.Marshal(gopackageregistry.PublishedEvent{Holder: "gitea", Kind: "package", Name: "mesh-sdk/go", Commit: head2, Tag: "feat-x", Version: "0.1.15-feat-x.1", + published, _ := json.Marshal(gopackageregistry.PublishedEvent{Holder: "gitea", Kind: "package", Name: "mesh-sdk/go", Module: check.SDKModulePath, Commit: head2, Tag: "feat-x", Version: "0.1.15-feat-x.1", Digest: "sha256:" + strings.Repeat("0", 64)}) if _, err := b.js.Publish(b.ctx, gopackageregistry.SubjectPublished, published); err != nil { t.Fatal(err) diff --git a/modules/mesh-delivery-checker/internal/check/pins_test.go b/modules/mesh-delivery-checker/internal/check/pins_test.go index 0babb1b6..890eb6d8 100644 --- a/modules/mesh-delivery-checker/internal/check/pins_test.go +++ b/modules/mesh-delivery-checker/internal/check/pins_test.go @@ -104,6 +104,8 @@ func TestAGroupMemberIsBuiltAgainstTheSDKMembersHeadWhateverItsGoModNames(t *tes // fetch takes from the registry; nil checks none. built map[string]string node map[string]any + // noModule: the Go seat's published names no Go module path (ruling 1 on A2d's finding 1: never worked out). + noModule bool }{ {name: "a group", pulls: []delivery.CandidatePull{pullOf(repoA, 7, head1), sdkPull()}, published: []string{"go-package-registry", "npm-package-registry"}, wants: 2, @@ -114,6 +116,9 @@ func TestAGroupMemberIsBuiltAgainstTheSDKMembersHeadWhateverItsGoModNames(t *tes published: []string{"go-package-registry"}, wants: 2, built: map[string]string{contractsGo: "v0.1.15-feat-x.1", seatGo: "v0.1.3-feat-x.1"}}, {name: "a lone pull request", pulls: []delivery.CandidatePull{sdkPull()}}, + {name: "a Go published naming no module", pulls: []delivery.CandidatePull{pullOf(repoA, 7, head1), sdkPull()}, + published: []string{"go-package-registry", "npm-package-registry"}, wants: 2, noModule: true, + fails: "no published of the tagged version of go of mesh-sdk (novox/mesh-sdk#12) on go-package-registry within 50ms"}, {name: "a package never published", pulls: []delivery.CandidatePull{pullOf(repoA, 7, head1), sdkPull()}, published: []string{"go-package-registry"}, wants: 2, fails: "no published of the tagged version of lib of mesh-sdk (novox/mesh-sdk#12) on npm-package-registry within 50ms"}, @@ -124,7 +129,7 @@ func TestAGroupMemberIsBuiltAgainstTheSDKMembersHeadWhateverItsGoModNames(t *tes b.ex.Modules = langs{repoA: {buildrun.GoBuildModule, buildrun.NodeBuildModule}} raw, _ := json.Marshal(sdk) b.ex.Forge = headFiles{repoSDK + " module.json " + head2: string(raw)} - tags := &recordedTags{heard: &PublishedHeard{}, publish: row.published} + tags := &recordedTags{heard: &PublishedHeard{}, publish: row.published, noModule: row.noModule} b.ex.Tags, b.ex.PublishBound = tags, 50*time.Millisecond b.asks.Answer = func(a delivery.StepAsk) delivery.Step { if len(tags.wanted) != row.wants { @@ -180,8 +185,10 @@ func (h headFiles) File(_ context.Context, repository, path, ref string) (string type recordedTags struct { heard *PublishedHeard publish []string - mu sync.Mutex - wanted []TagWanted + // noModule publishes a Go package naming no Go module path, against go-package-registry's contract. + noModule bool + mu sync.Mutex + wanted []TagWanted } func (r *recordedTags) Want(_ context.Context, w TagWanted) error { @@ -193,7 +200,12 @@ func (r *recordedTags) Want(_ context.Context, w TagWanted) error { if w.Package == "go-gopackageregistry" { version = "0.1.3-feat-x.1" } - r.heard.Heard(seat, TaggedPublished{Name: w.Package, Kind: "package", Commit: w.Head, Tag: "feat-x", Version: version}) + module := "" // go-package-registry's published names the Go module path (its contract); npm's names none + if seat == "go-package-registry" && !r.noModule { + module = map[string]string{repoSDK + " go": SDKModulePath, "novox/mesh-catalog go": "git.novox.be/novox/mesh-catalog/go", + "novox/mesh-catalog go-gopackageregistry": "git.novox.be/novox/mesh-catalog/go/seats/gopackageregistry"}[w.Repository+" "+w.Package] + } + r.heard.Heard(seat, TaggedPublished{Name: w.Package, Kind: "package", Commit: w.Head, Tag: "feat-x", Version: version, Module: module}) } return nil } diff --git a/modules/mesh-delivery-checker/internal/check/tagwanted.go b/modules/mesh-delivery-checker/internal/check/tagwanted.go index 8e1f5b20..bc0595c7 100644 --- a/modules/mesh-delivery-checker/internal/check/tagwanted.go +++ b/modules/mesh-delivery-checker/internal/check/tagwanted.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "maps" - "path" "slices" "strings" "sync" @@ -43,6 +42,9 @@ type TaggedPublished struct { Commit string `json:"commit,omitempty"` Tag string `json:"tag,omitempty"` Version string `json:"version,omitempty"` + // Module is the Go module path a Go package is fetched under, as go-package-registry's published names it (its + // contract requires it of a Go package). + Module string `json:"module,omitempty"` } // TagAsks says tag-wanted and hears the registry seats' published: nil asks nothing, and a group's check builds its @@ -76,10 +78,10 @@ func (h *PublishedHeard) init() { } } -// Heard takes one published of a seat in; one of no tagged version (no tag, or no commit) is left out and answers false. -// A later published of the same name and head replaces the earlier. +// Heard takes one published of a seat in; one of no tagged version (no tag, or no commit), and a Go package's that names +// no Go module path, are left out and answer false. A later published of the same name and head replaces the earlier. func (h *PublishedHeard) Heard(seat string, p TaggedPublished) bool { - if p.Tag == "" || p.Commit == "" { + if p.Tag == "" || p.Commit == "" || (seat == PackageSeats["go"] && p.Module == "") { return false } h.mu.Lock() @@ -138,33 +140,10 @@ type declaredPackage struct { } // publishedNames are the names a registry seat's published may carry for a declared package: the builder's -// `/` (its versions' name), the artifact's name, and a Go package's module path. +// `/` (its versions' name) and the artifact's name. A Go package's module path is the published's own +// `module` (go-package-registry's contract), never worked out here. func (d declaredPackage) publishedNames() []string { - names := []string{d.module + "/" + d.name, d.name} - if d.language == "go" { - names = append(names, d.goModulePath("")) - } - return names -} - -// goModulePath is the Go module path of a declared Go package (design 51 *Go packages*): the forge's module prefix, the -// repository's name, the module's directory and the artifact's first named path; a published name that is already a -// module path of the forge's is taken as it is. -func (d declaredPackage) goModulePath(published string) string { - if strings.HasPrefix(published, delivery.ForgeModulePrefix) { - return published - } - _, name, _ := strings.Cut(d.pull.Repository, "/") - parts := []string{strings.TrimSuffix(delivery.ForgeModulePrefix, "/") + "/" + name} - if dir := strings.Trim(d.dir, "/"); dir != "" && dir != delivery.RootPath { - parts = append(parts, dir) - } - if len(d.paths) > 0 { - if p := strings.Trim(strings.TrimPrefix(d.paths[0], "./"), "/"); p != "" && p != "." { - parts = append(parts, p) - } - } - return path.Join(parts...) + return []string{d.module + "/" + d.name, d.name} } // manifestAtHead is a touched module's manifest read from the forge at its member's head (the lead's ruling 4 on A2c's @@ -309,7 +288,7 @@ func (g *groupVersions) took(d declaredPackage, p TaggedPublished) { if g.goPackages == nil { g.goPackages = delivery.PackageVersions{} } - g.goPackages[d.goModulePath(p.Name)] = goVersion(p.Version) + g.goPackages[p.Module] = goVersion(p.Version) // Heard took no Go published without its module case "typescript": if g.node == nil { g.node = map[string]NodePackage{}