Merge pull request 'A dry-run build is taken in by nothing (hq issue 240)' (#47) from fix/a-dry-run-build-is-not-taken-in into main
mesh/delivery held for a person: merged without a passing check: only a person decides that it goes on
mesh/delivery held for a person: merged without a passing check: only a person decides that it goes on
This commit was merged in pull request #47.
This commit is contained in:
@@ -171,7 +171,7 @@ func answer(ctx context.Context, publisher builder.Publisher, on, workspace stri
|
|||||||
|
|
||||||
result := link.BuildResult{
|
result := link.BuildResult{
|
||||||
ID: request.ID, Repository: request.Repository, Path: request.Path,
|
ID: request.ID, Repository: request.Repository, Path: request.Path,
|
||||||
Ref: request.Ref, On: on, Source: request.Source,
|
Ref: request.Ref, On: on, Source: request.Source, DryRun: request.DryRun,
|
||||||
}
|
}
|
||||||
what := "building " + request.Repository
|
what := "building " + request.Repository
|
||||||
if request.Path != "" {
|
if request.Path != "" {
|
||||||
|
|||||||
@@ -592,6 +592,7 @@ func buildAndShow(ctx context.Context, source buildSource, path, ref string, wai
|
|||||||
ID: link.NewBuildID(time.Now()),
|
ID: link.NewBuildID(time.Now()),
|
||||||
Repository: repository, Path: path, Ref: ref,
|
Repository: repository, Path: path, Ref: ref,
|
||||||
Held: heldBy(ctx), Seats: seatBases(ctx),
|
Held: heldBy(ctx), Seats: seatBases(ctx),
|
||||||
|
DryRun: true,
|
||||||
}, wait)
|
}, wait)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/novox/mesh-controller/internal/link"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A dry run's outcome is looked at, never taken in (novox/hq issue 240). The daemon here holds no
|
||||||
|
// store at all, so anything that tried to record or register would fail rather than pass quietly.
|
||||||
|
func TestADryRunsOutcomeIsTakenInByNothing(t *testing.T) {
|
||||||
|
err := builds{}.Built(t.Context(), link.BuildResult{
|
||||||
|
ID: "build-1", Repository: "ssh://forge/app.git", Ref: "unreviewed", Module: "app", DryRun: true,
|
||||||
|
Manifest: json.RawMessage(`{"module":"app","version":"1"}`),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("a dry run's outcome was not simply set aside: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The mark survives the wire both ways: asked as a dry run, answered as one.
|
||||||
|
func TestTheDryRunMarkTravelsWithTheBuild(t *testing.T) {
|
||||||
|
raw, _ := json.Marshal(link.BuildRequest{ID: "build-1", Repository: "r", DryRun: true})
|
||||||
|
var asked link.BuildRequest
|
||||||
|
if err := json.Unmarshal(raw, &asked); err != nil || !asked.DryRun {
|
||||||
|
t.Fatalf("the request lost its dry-run mark: %s", raw)
|
||||||
|
}
|
||||||
|
raw, _ = json.Marshal(link.BuildResult{ID: "build-1", DryRun: true})
|
||||||
|
var answered link.BuildResult
|
||||||
|
if err := json.Unmarshal(raw, &answered); err != nil || !answered.DryRun {
|
||||||
|
t.Fatalf("the outcome lost its dry-run mark: %s", raw)
|
||||||
|
}
|
||||||
|
raw, _ = json.Marshal(link.BuildResult{ID: "build-2"})
|
||||||
|
if string(raw) != `{"id":"build-2","repository":"","on":""}` {
|
||||||
|
t.Fatalf("an ordinary outcome carries a dry-run mark: %s", raw)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -253,6 +253,13 @@ func parseAround(set *flag.FlagSet, args []string) ([]string, error) {
|
|||||||
// registered, the same as the waiting command does. Said either way, so the daemon's log tells what
|
// registered, the same as the waiting command does. Said either way, so the daemon's log tells what
|
||||||
// became of a build nobody was watching.
|
// became of a build nobody was watching.
|
||||||
func (b builds) Built(ctx context.Context, result link.BuildResult) error {
|
func (b builds) Built(ctx context.Context, result link.BuildResult) error {
|
||||||
|
// **A dry run is looked at, never taken in** (novox/hq issue 240). On 2026-10-04 a dry run of an
|
||||||
|
// unmerged branch was heard here like any build, registered, and its definition reached a machine
|
||||||
|
// before anyone had reviewed it.
|
||||||
|
if result.DryRun {
|
||||||
|
fmt.Printf("%s: a dry run of %s on %s, not taken in\n", result.ID, result.Repository, result.Ref)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
manifest, _, err := takeIn(ctx, b.inv, result)
|
manifest, _, err := takeIn(ctx, b.inv, result)
|
||||||
// When it was asked, so a plan takes as its outcome only a build asked for it or after it
|
// When it was asked, so a plan takes as its outcome only a build asked for it or after it
|
||||||
// (novox/hq 04-ISSUES/219). Zero when the id does not say.
|
// (novox/hq 04-ISSUES/219). Zero when the id does not say.
|
||||||
|
|||||||
@@ -83,6 +83,10 @@ type BuildRequest struct {
|
|||||||
// asking and echoed in the outcome, so whoever hears the outcome can register the module with
|
// asking and echoed in the outcome, so whoever hears the outcome can register the module with
|
||||||
// its true source, whether or not they were the one who asked (novox/hq issue 176).
|
// its true source, whether or not they were the one who asked (novox/hq issue 176).
|
||||||
Source *SourceOnSeat `json:"source,omitempty"`
|
Source *SourceOnSeat `json:"source,omitempty"`
|
||||||
|
// DryRun says the asker wants the outcome to look at and nothing else (novox/hq issue 240): the
|
||||||
|
// builder echoes it, and whoever hears the outcome takes nothing in — no record, no registration,
|
||||||
|
// no plan, nothing a push could send.
|
||||||
|
DryRun bool `json:"dry-run,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SourceOnSeat names a repository by the seat whose holder serves it and its path there.
|
// SourceOnSeat names a repository by the seat whose holder serves it and its path there.
|
||||||
@@ -144,6 +148,9 @@ type BuildResult struct {
|
|||||||
|
|
||||||
// Source is the request's, echoed: the seat form of the repository, for whoever registers.
|
// Source is the request's, echoed: the seat form of the repository, for whoever registers.
|
||||||
Source *SourceOnSeat `json:"source,omitempty"`
|
Source *SourceOnSeat `json:"source,omitempty"`
|
||||||
|
|
||||||
|
// DryRun is the request's, echoed: an outcome nobody may take in (novox/hq issue 240).
|
||||||
|
DryRun bool `json:"dry-run,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadRepository is a repository a build read source from besides the module's own, at the branch,
|
// ReadRepository is a repository a build read source from besides the module's own, at the branch,
|
||||||
|
|||||||
Reference in New Issue
Block a user