From ea223fcf985f3b2970981330fe42269b6b260774 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Wed, 7 Oct 2026 14:44:36 +0000 Subject: [PATCH] Check effective release target membership --- docs/roadmap/remediation.md | 7 ++++++- scripts/release_test.go | 36 +++++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/docs/roadmap/remediation.md b/docs/roadmap/remediation.md index 8ac3739..dc7b8ff 100644 --- a/docs/roadmap/remediation.md +++ b/docs/roadmap/remediation.md @@ -4,7 +4,7 @@ `3c405f0524ec6c098d00d4e371abbace7648d446`. **Scope:** ReleaseKit adoption commits after `721365e`, including CLI version reporting, local release wiring, CI delivery, tests, and documentation. -**Status:** R1 addressed; R2–R3 pending. The findings below describe the reviewed +**Status:** R1–R2 addressed; R3 pending. The findings below describe the reviewed baseline; completed work is recorded under Resolution Record. ## Architecture Assessment @@ -136,3 +136,8 @@ matrix. trailing arguments. Non-help usage errors retain status `2`. Regression tests reproduced both defects before the fix; `go test ./internal/cli ./cmd/audita` passed afterward. The CLI contract reflects ordinary help behavior. +- **R2:** Delivery targets are compared as sets using the standard library. + Regression cases reject either missing Linux target concealed by duplicates + and an unintended target, while accepting equivalent reordered/repeated lists. + The cases reproduced the faulty membership behavior before the fix; + `go test ./scripts` passed afterward. diff --git a/scripts/release_test.go b/scripts/release_test.go index bfa2fa9..6d4a29d 100644 --- a/scripts/release_test.go +++ b/scripts/release_test.go @@ -2,6 +2,7 @@ package scripts import ( "encoding/json" + "maps" "os" "os/exec" "path/filepath" @@ -147,6 +148,27 @@ func TestReleaseKitProfileDeclaresProductAndDeliverySettings(t *testing.T) { } } +func TestReleaseKitTargetMembership(t *testing.T) { + want := []string{"linux/amd64", "linux/arm64"} + for _, test := range []struct { + name string + targets []string + match bool + }{ + {"missing amd64", []string{"linux/arm64", "linux/arm64"}, false}, + {"missing arm64", []string{"linux/amd64", "linux/amd64"}, false}, + {"additional target", []string{"linux/amd64", "linux/arm64", "darwin/arm64"}, false}, + {"reordered", []string{"linux/arm64", "linux/amd64"}, true}, + {"repeated", []string{"linux/amd64", "linux/arm64", "linux/amd64"}, true}, + } { + t.Run(test.name, func(t *testing.T) { + if got := sameMembers(test.targets, want); got != test.match { + t.Fatalf("target membership for %q = %t, want %t", test.targets, got, test.match) + } + }) + } +} + type releaseTestLayout struct { repo string caller string @@ -257,15 +279,15 @@ func hasAdjacentArguments(args []string, first, second string) bool { } func sameMembers(got, want []string) bool { - if len(got) != len(want) { - return false - } + gotSet := make(map[string]struct{}, len(got)) for _, value := range got { - if !containsArgument(want, value) { - return false - } + gotSet[value] = struct{}{} } - return true + wantSet := make(map[string]struct{}, len(want)) + for _, value := range want { + wantSet[value] = struct{}{} + } + return maps.Equal(gotSet, wantSet) } func hasKey(values map[string]string, key string) bool {