mesh/merge-gate error: the check could not run: a throwaway postgres:17-alpine could not be raised: docker run --label mesh.build=build-1791317509716888018…
mesh/delivery delivered
An image is not byte-reproducible, so ADR 0236's 'same artifacts is no move' never held for one: a catalogue merge that did not touch the bus rebuilt it, and every send to the control node waited for a planned bus upgrade. The builder now records a source fingerprint per build (module tree, context trees, bases and toolchains by digest). A rebuild with the fingerprint of the build it repeats is registered with that build's artifacts, handed to modules standing on it, holds no push, demands no bus step, and a plan sends and gates nothing for it. Identical artifacts remain a second way to be no move.
77 lines
2.9 KiB
Go
77 lines
2.9 KiB
Go
package builder
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// A build's source fingerprint (novox/hq issue 280): what it was made from, so a rebuild of an unchanged
|
|
// source is one build however the image digest it made differs.
|
|
|
|
const anImage = `{"module":"bus","version":"1",
|
|
"build":{"on":[{"arg":"BASE","image":"vendor/server@sha256:` + "1111111111111111111111111111111111111111111111111111111111111111" + `"}],
|
|
"artifacts":[{"name":"server","kind":"image","from":"Dockerfile"}]},
|
|
"resources":[{"id":"svc","type":"container","name":"bus","artifact":"server"}]}`
|
|
|
|
func fingerprintOf(t *testing.T, manifest, tree string, mirrored string) string {
|
|
t.Helper()
|
|
r, workspace := aRepository(t, manifest, map[string]string{"modules/bus/Dockerfile": "ARG BASE\nFROM ${BASE}"})
|
|
r.contents["modules/bus/module.json"] = manifest
|
|
r.tree = tree
|
|
m := &mirroring{recorded: r, at: mirrored}
|
|
got, err := Build(context.Background(), r.run, m, "https://forge.invalid/catalogue.git", "modules/bus", "", workspace,
|
|
nil, Npmrc{}, GitCredential{}, nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return got.Source
|
|
}
|
|
|
|
// mirroring is a store that copies a vendor's image into the mesh's registry, at an address a test says.
|
|
type mirroring struct {
|
|
*recorded
|
|
at string
|
|
}
|
|
|
|
func (m *mirroring) MirrorImage(_ context.Context, from, repository string) (string, error) {
|
|
_, digest, _ := strings.Cut(from, "@")
|
|
return m.at + "/" + repository + "@" + digest, nil
|
|
}
|
|
|
|
func TestASourceFingerprintNamesWhatABuildWasMadeFrom(t *testing.T) {
|
|
one := fingerprintOf(t, anImage, "aaaa", "registry-a:5000")
|
|
if !strings.HasPrefix(one, sourcePrefix) {
|
|
t.Fatalf("no fingerprint: %q", one)
|
|
}
|
|
// The same tree and base, the base copied to another registry address: one source.
|
|
if again := fingerprintOf(t, anImage, "aaaa", "registry-b:5000"); again != one {
|
|
t.Fatalf("one source has two fingerprints: %s %s", one, again)
|
|
}
|
|
// The module's tree changed: another source.
|
|
if changed := fingerprintOf(t, anImage, "bbbb", "registry-a:5000"); changed == one {
|
|
t.Fatal("a changed tree kept its fingerprint")
|
|
}
|
|
// The base moved: another source.
|
|
moved := strings.Replace(anImage, "1111111111111111111111111111111111111111111111111111111111111111",
|
|
"2222222222222222222222222222222222222222222222222222222222222222", 1)
|
|
if changed := fingerprintOf(t, moved, "aaaa", "registry-a:5000"); changed == one {
|
|
t.Fatal("a moved base kept its fingerprint")
|
|
}
|
|
}
|
|
|
|
func TestABuildTheRegistryDecidesHasNoFingerprint(t *testing.T) {
|
|
s := newSourceInputs("app")
|
|
s.tree = "aaaa"
|
|
if s.fingerprint() == "" {
|
|
t.Fatal("a pinned source has no fingerprint")
|
|
}
|
|
s.notPinned("it resolves packages from the mesh's registry at build time")
|
|
if got := s.fingerprint(); got != "" {
|
|
t.Fatalf("a build the registry decides has a fingerprint: %s", got)
|
|
}
|
|
if (&sourceInputs{module: "app"}).fingerprint() != "" {
|
|
t.Fatal("a build whose tree was not named has a fingerprint")
|
|
}
|
|
}
|