Build a TypeScript package with the Node build module, published only for a trunk fingerprint; a version taken fails the key until the fingerprint changes (issue 1587, B5, ADR 0498 §5, ADR 0500 §4)
This commit is contained in:
@@ -104,6 +104,8 @@ func PlanOf(m catalogue.Manifest) (Plan, error) {
|
||||
return Plan{}, &NotPinned{Artifact: a.Name, From: a.From}
|
||||
case a.Kind == catalogue.ArtifactUpstream:
|
||||
p.Tasks = append(p.Tasks, Task{Artifact: a.Name, Kind: a.Kind, Module: ImageBuildModule, From: a.From})
|
||||
case a.Kind == catalogue.ArtifactPackage && a.Language == "typescript":
|
||||
p.Tasks = append(p.Tasks, Task{Artifact: a.Name, Kind: a.Kind, Module: buildrun.NodeBuildModule, Language: "typescript"})
|
||||
case a.Kind == catalogue.ArtifactBundle:
|
||||
return Plan{}, &Refused{Artifact: a.Name, What: fmt.Sprintf("bundle of language %q", a.Language)}
|
||||
case a.Kind == catalogue.ArtifactPackage:
|
||||
|
||||
@@ -155,3 +155,48 @@ func TestACopyThatFailsNotStoredFailsTheKeyAndIsBuiltAgain(t *testing.T) { // B4
|
||||
t.Errorf("build = %+v, want done on the new revision", v)
|
||||
}
|
||||
}
|
||||
|
||||
var tsPackage = catalogue.Artifact{Name: "lib", Kind: "package", Language: "typescript"}
|
||||
|
||||
func TestATypeScriptPackageIsBuiltByTheNodeModuleAndPublishedOnlyForTheTrunk(t *testing.T) { // B5, ADR 0498 clause 5, ADR 0500 clause 4
|
||||
c := newRig(t, tsPackage)
|
||||
c.bm.packages["lib"] = "@novox/mesh-sdk@0.1.15"
|
||||
trunkModule(t, c)
|
||||
c.b.Candidate(context.Background(), "feat%2Fx", candidateValue(t, "feat/x", 7, headX))
|
||||
c.b.Wait()
|
||||
v := valueOf(t, c.st, c.key)
|
||||
if v.State != delivery.BuildDone || len(v.Artifacts) != 1 || v.Artifacts[0].Kind != "package" || v.Artifacts[0].Reference != "" {
|
||||
t.Fatalf("candidate build = %+v, want done with the packed digest and no reference", v)
|
||||
}
|
||||
for _, call := range c.bm.callsOf("build_node_build") {
|
||||
if _, ok := call.body.(map[string]any)["publish"]; ok {
|
||||
t.Errorf("a candidate's package build was asked to publish: %+v", call.body)
|
||||
}
|
||||
}
|
||||
|
||||
r := newRig(t, tsPackage)
|
||||
r.bm.packages["lib"] = "@novox/mesh-sdk@0.1.15"
|
||||
v = r.consider(t, "modules/m")
|
||||
if v.State != delivery.BuildDone || v.Artifacts[0].Reference != "@novox/mesh-sdk@0.1.15" {
|
||||
t.Fatalf("trunk build = %+v, want done naming the published version", v)
|
||||
}
|
||||
if n := len(r.bm.callsOf("build_node_build")); n == 0 {
|
||||
t.Error("the package was not built by the Node build module")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAVersionTakenFailsTheKeyUntilTheFingerprintChanges(t *testing.T) { // B5, ADR 0498 clause 5
|
||||
r := newRig(t, tsPackage)
|
||||
r.bm.packages["lib"] = "@novox/mesh-sdk@0.1.15"
|
||||
r.bm.fails["ace/build_node_build"] = delivery.VersionTaken + "@novox/mesh-sdk@0.1.15 is published with another packed file"
|
||||
r.bm.fails["novox/build_node_build"] = r.bm.fails["ace/build_node_build"]
|
||||
v := r.consider(t, "modules/m")
|
||||
if v.State != delivery.BuildFailed || !strings.HasPrefix(v.Error, delivery.VersionTaken) || !strings.Contains(v.Error, "0.1.15") {
|
||||
t.Fatalf("build = %+v, want failed opening %q naming the version", v, delivery.VersionTaken)
|
||||
}
|
||||
writes := r.st.writes
|
||||
r.consider(t, "modules/m")
|
||||
if r.st.writes != writes {
|
||||
t.Errorf("a version-taken key was built again (%d writes, was %d)", r.st.writes, writes)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ type buildModules struct {
|
||||
fails map[string]string // `<node>/<tool>` -> the reason the step fails with
|
||||
// noRef names `<node>/<artifact>` whose bundle or archive build answers no reference (its push not answered).
|
||||
noRef map[string]bool
|
||||
// packages are the package artifacts by name, each with the `<name>@<version>` its trunk build publishes (ADR 0498 clause 5).
|
||||
packages map[string]string
|
||||
// hold, when set before the builds start, blocks every call until it is closed; entered is sent to as a call arrives.
|
||||
// conflicts, when set, is a file a fetch with a base reports in conflict; noMerge makes it answer neither a merge nor a conflict.
|
||||
conflicts string
|
||||
@@ -34,7 +36,7 @@ type buildModules struct {
|
||||
}
|
||||
|
||||
func newBuildModules() *buildModules {
|
||||
return &buildModules{steps: &fakeSteps{steps: map[string]delivery.Step{}}, digests: map[string]string{}, fails: map[string]string{}, noRef: map[string]bool{}}
|
||||
return &buildModules{steps: &fakeSteps{steps: map[string]delivery.Step{}}, digests: map[string]string{}, fails: map[string]string{}, noRef: map[string]bool{}, packages: map[string]string{}}
|
||||
}
|
||||
|
||||
func (b *buildModules) CallOn(node, key string, body any) (json.RawMessage, error) {
|
||||
@@ -71,6 +73,11 @@ func (b *buildModules) CallOn(node, key string, body any) (json.RawMessage, erro
|
||||
}
|
||||
if tool == "build_image_copy" { // mesh-build-image's copy answers the digest and where it copied to (ADR 0498 clause 4)
|
||||
step.Result = json.RawMessage(`{"artifact":"` + fmt.Sprint(args["artifact"]) + `","digest":"` + d + `","reference":"registry.example/` + fmt.Sprint(args["module"]) + `/` + fmt.Sprint(args["artifact"]) + `@` + d + `","pushed":true}`)
|
||||
} else if pkg, ok := b.packages[fmt.Sprint(args["artifact"])]; ok { // a package names its version only when published
|
||||
step.Result = json.RawMessage(`{"digest":"` + d + `"}`)
|
||||
if args["publish"] == true {
|
||||
step.Result = json.RawMessage(`{"digest":"` + d + `","reference":"` + pkg + `"}`)
|
||||
}
|
||||
} else if tool == "build_image_build" && args["publish"] == true {
|
||||
step.Result = json.RawMessage(`{"digest":"` + d + `","reference":"registry.example/m/` + fmt.Sprint(args["artifact"]) + `@` + d + `"}`)
|
||||
} else if tool != "build_image_build" && !b.noRef[node+"/"+fmt.Sprint(args["artifact"])] {
|
||||
|
||||
Reference in New Issue
Block a user