From bf852f27aa2af36a317b1439a025653326f0da14 Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 13 Nov 2026 02:43:18 +0100 Subject: [PATCH] Runner (A-336): a publish heard before its branch's half starts with no steps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A-336 holds for every start of a pipeline: a package-published heard before its branch's catalog half was held still placed steps from empty entries. Its pipelines now start with no steps, placed by A-327's path once the half is held. The hand start already refuses a branch whose half is not held. Builds: design 47 G §200, A-327, A-336 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h --- .../internal/pipeline/start.go | 8 +++++--- .../internal/pipeline/start_test.go | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/modules/mesh-delivery-pipeline/internal/pipeline/start.go b/modules/mesh-delivery-pipeline/internal/pipeline/start.go index 7d209e4d..73ebf5a7 100644 --- a/modules/mesh-delivery-pipeline/internal/pipeline/start.go +++ b/modules/mesh-delivery-pipeline/internal/pipeline/start.go @@ -396,7 +396,9 @@ func (s *Starter) Published(ev builds.PackagePublished, outdated func(catalog.Ou if err != nil { return 0, fmt.Errorf("outdated of %s on %s: %w", ev.Artifact, ev.Branch, err) } - half, _ := view(ev.Branch) + // A publish heard before its branch's half is held starts its pipelines with no steps, never placed from empty entries + // (§200, A-336); Waiting places them once the half is held. + half, held := view(ev.Branch) started := 0 var first error for _, o := range a.Behind { @@ -404,10 +406,10 @@ func (s *Starter) Published(ev builds.PackagePublished, outdated func(catalog.Ou continue } b := Begin{Branch: ev.Branch, Source: ev.Source, Module: o.Module, Revision: half.Revision, Entries: half.Entries, - Published: &seat.Published{Artifact: ev.Artifact, Version: ev.Version}} + Published: &seat.Published{Artifact: ev.Artifact, Version: ev.Version}, unheld: !held} if e, ok := half.Entries[o.Module]; ok { b.Commit, b.Fp, b.Repository = e.Commit, e.Fp, e.Repository - } else { + } else if held { s.logf("the catalog half of %s holds no entry of %s, behind %s: its pipeline starts without its commit", ev.Branch, o.Module, ev.Artifact) } ok, err := s.Start(b) diff --git a/modules/mesh-delivery-pipeline/internal/pipeline/start_test.go b/modules/mesh-delivery-pipeline/internal/pipeline/start_test.go index d084fadf..727e88f7 100644 --- a/modules/mesh-delivery-pipeline/internal/pipeline/start_test.go +++ b/modules/mesh-delivery-pipeline/internal/pipeline/start_test.go @@ -195,4 +195,21 @@ func TestAPipelineStartedBeforeItsRegistrationIsPlacedWhenItArrives(t *testing.T if n != 1 || err != nil || len(p.Steps) == 0 { t.Errorf("the half of next placed %d (%v): %d steps, want the take-in's pipeline placed", n, err, len(p.Steps)) } + // A-336: so does a package published heard before its branch's half is held. + held = false + outdated := func(catalog.OutdatedInput) (catalog.OutdatedAnswer, error) { + return catalog.OutdatedAnswer{Behind: []catalog.Outdated{{Module: "app", Kind: outdatedKind}}}, nil + } + if n, err := s.Published(builds.PackagePublished{Artifact: "mesh-sdk:go", Branch: "next", Source: 7, Module: "mesh-sdk", Version: "0.1.17"}, outdated, late); n != 1 || err != nil { + t.Fatalf("the publish before the half started %d (%v)", n, err) + } + if p, _, _ := store.Get("next.7.app"); len(p.Steps) != 0 { + t.Fatalf("a publish before its branch's half placed %d steps from empty entries, want none", len(p.Steps)) + } + held = true + n, err = s.Waiting(store.memStore, "next", late) + p, _, _ = store.Get("next.7.app") + if n != 1 || err != nil || len(p.Steps) == 0 { + t.Errorf("the half of next placed %d (%v): %d steps, want the publish's pipeline placed", n, err, len(p.Steps)) + } }