Share artifact declaration validation

This commit is contained in:
2026-11-02 03:23:15 +00:00
parent 6f2e62bea3
commit 0666b68ff6
5 changed files with 67 additions and 43 deletions

View File

@@ -90,3 +90,30 @@ func ExpectedBuild(binaryName, version string, targets []Target) []Declaration {
}
return declarations
}
// ValidateDeclarations matches recorded artifact identities to selected targets.
func ValidateDeclarations(binaryName, version string, targets []Target, recorded []Declaration) error {
if len(recorded) != len(targets) {
return fmt.Errorf("artifact and target counts do not match")
}
want := make(map[Target]string, len(targets))
for _, declaration := range ExpectedBuild(binaryName, version, targets) {
target := declaration.Target
if !ValidComponent(target.OS) || !ValidComponent(target.Arch) {
return fmt.Errorf("invalid target %q/%q", target.OS, target.Arch)
}
if _, exists := want[target]; exists {
return fmt.Errorf("repeats target %q/%q", target.OS, target.Arch)
}
want[target] = declaration.Filename
}
seen := make(map[Target]bool, len(recorded))
for _, declaration := range recorded {
name, ok := want[declaration.Target]
if !ok || seen[declaration.Target] || declaration.Filename != name {
return fmt.Errorf("artifact %q does not match a selected target and its declared name", declaration.Filename)
}
seen[declaration.Target] = true
}
return nil
}

View File

@@ -56,3 +56,31 @@ func TestValidComponentPreservesBuildAndReceiptRules(t *testing.T) {
}
}
}
func TestValidateDeclarationsMatchesTargetsAndNames(t *testing.T) {
linux := Target{OS: "linux", Arch: "amd64"}
windows := Target{OS: "windows", Arch: "arm64"}
first := Declaration{Target: linux, Filename: "app-v1.2.3-linux-amd64"}
second := Declaration{Target: windows, Filename: "app-v1.2.3-windows-arm64.exe"}
for _, test := range []struct {
name string
targets []Target
recorded []Declaration
valid bool
}{
{"reordered", []Target{linux, windows}, []Declaration{second, first}, true},
{"count", []Target{linux, windows}, []Declaration{first}, false},
{"duplicate target", []Target{linux, linux}, []Declaration{first, first}, false},
{"duplicate artifact", []Target{linux, windows}, []Declaration{first, first}, false},
{"incorrect name", []Target{linux}, []Declaration{{Target: linux, Filename: "other"}}, false},
{"unknown target", []Target{linux}, []Declaration{second}, false},
{"unsafe target", []Target{{OS: "linux/other", Arch: "amd64"}}, []Declaration{{Target: linux, Filename: first.Filename}}, false},
} {
t.Run(test.name, func(t *testing.T) {
err := ValidateDeclarations("app", "v1.2.3", test.targets, test.recorded)
if (err == nil) != test.valid {
t.Fatalf("ValidateDeclarations() error = %v, valid = %t", err, test.valid)
}
})
}
}