A merge rebuilds what it changed, and what packages it
Three faults in one path. A merge rebuilt every module built from the repository, so one change in a repository holding twenty-six of them meant twenty-six builds. A merge into a repository a module only *packages* source from rebuilt nothing — two modules are built from the control plane's own repository and neither had ever been rebuilt when it moved — because the manifest the mesh keeps carries no build section, so a build now says which repositories it read and the mesh keeps that beside what it stood on. And a module handed over by hand could record a repository with no directory inside it, which is a module nothing can ever rebuild (novox/hq 04-ISSUES/131, /132). A change inside no module's own directory is a change to what they share, and everything built from that repository is rebuilt: rebuilding too much is the safe direction, because the fault this whole path exists for is a mesh that believes it is current and is not.
This commit is contained in:
@@ -61,6 +61,12 @@ type Result struct {
|
||||
Commit string
|
||||
// Built is each artifact, for reporting.
|
||||
Built []catalogue.Built
|
||||
|
||||
// Read is every repository this build read source from besides the module's own — the second
|
||||
// repository an artifact's recipe names (ArtifactContext). Reported because the manifest the
|
||||
// mesh keeps carries no build section, so nothing else could say that a merge there is a
|
||||
// change to this module (novox/hq 04-ISSUES/131).
|
||||
Read []catalogue.ArtifactContext
|
||||
}
|
||||
|
||||
// GitCredential is the forge credential a clone may present when the server asks for one.
|
||||
@@ -220,7 +226,7 @@ func Build(ctx context.Context, run Runner, publish Publisher,
|
||||
}
|
||||
say("done", "%s at %s — %d artifact(s) pinned", manifest.Module, short(commit), len(built))
|
||||
return Result{Manifest: resolved, Commit: commit, Built: built,
|
||||
Against: against(within, manifest, stoodOn)}, nil
|
||||
Against: against(within, manifest, stoodOn), Read: readBy(manifest)}, nil
|
||||
}
|
||||
|
||||
// Log is where a build says what it is doing, step by step. Nil is silent — the tests pass none,
|
||||
@@ -1016,3 +1022,31 @@ func instructions(recipe string) []string {
|
||||
flush()
|
||||
return out
|
||||
}
|
||||
|
||||
// readBy is every repository other than the module's own that this build's recipes read source from,
|
||||
// each once and in a fixed order, so two builds of one commit report the same thing the same way.
|
||||
func readBy(manifest catalogue.Manifest) []catalogue.ArtifactContext {
|
||||
if manifest.Build == nil {
|
||||
return nil
|
||||
}
|
||||
seen := map[string]bool{}
|
||||
var out []catalogue.ArtifactContext
|
||||
for _, a := range manifest.Build.Artifacts {
|
||||
if a.Context == nil || a.Context.Repository == "" {
|
||||
continue
|
||||
}
|
||||
key := a.Context.Repository + "#" + a.Context.Ref
|
||||
if seen[key] {
|
||||
continue
|
||||
}
|
||||
seen[key] = true
|
||||
out = append(out, *a.Context)
|
||||
}
|
||||
sort.Slice(out, func(i, j int) bool {
|
||||
if out[i].Repository != out[j].Repository {
|
||||
return out[i].Repository < out[j].Repository
|
||||
}
|
||||
return out[i].Ref < out[j].Ref
|
||||
})
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -179,3 +179,24 @@ func TestTheBasesABuildWasHandedAreWhatItStoodOn(t *testing.T) {
|
||||
t.Fatalf("the bases the build was handed were not what it stood on: %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
// What a build read besides its module's own repository is the second repository its recipes name,
|
||||
// each once: a module that packages source living elsewhere is affected when that source moves.
|
||||
func TestWhatABuildReadIsTheRepositoriesItsRecipesName(t *testing.T) {
|
||||
elsewhere := catalogue.ArtifactContext{Repository: "http://forge.internal:20000/novox/mesh-controller.git", Ref: "main"}
|
||||
manifest := catalogue.Manifest{
|
||||
Module: "builder",
|
||||
Build: &catalogue.Build{Artifacts: []catalogue.Artifact{
|
||||
{Name: "server", Kind: catalogue.ArtifactImage, From: "Dockerfile", Context: &elsewhere},
|
||||
{Name: "tools", Kind: catalogue.ArtifactImage, From: "Dockerfile", Context: &elsewhere},
|
||||
{Name: "config", Kind: catalogue.ArtifactArchive, From: "etc"},
|
||||
}},
|
||||
}
|
||||
read := readBy(manifest)
|
||||
if len(read) != 1 || read[0] != elsewhere {
|
||||
t.Fatalf("the repositories this build read are %+v", read)
|
||||
}
|
||||
if readBy(catalogue.Manifest{Module: "gitea", Build: &catalogue.Build{}}) != nil {
|
||||
t.Fatal("a module whose recipes name no other repository read one")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user