Make product checks additive
This commit is contained in:
@@ -130,7 +130,7 @@ func TestExampleProfileLoads(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if settings.Product != "Example" || settings.Remote != "origin" || len(settings.Checks) != 1 {
|
||||
if settings.Product != "Example" || settings.Remote != "origin" || len(settings.Checks) != 0 {
|
||||
t.Fatalf("example settings = %#v", settings)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func run(ctx context.Context, args []string, stdout, stderr io.Writer) int {
|
||||
}
|
||||
if len(settings.Checks) != 0 {
|
||||
checks := settings.Checks
|
||||
request.Validate = func(ctx context.Context, candidate releasekit.Candidate) error {
|
||||
request.AdditionalChecks = func(ctx context.Context, candidate releasekit.Candidate) error {
|
||||
return cli.RunChecks(ctx, candidate.RepositoryDir, checks, map[string]string{
|
||||
"RELEASEKIT_VERSION": candidate.Version,
|
||||
"RELEASEKIT_CANDIDATE": candidate.Commit,
|
||||
|
||||
@@ -50,21 +50,27 @@ func TestUnknownCommand(t *testing.T) {
|
||||
func TestCheckCommandBindsConfiguredChecksToCapturedCandidate(t *testing.T) {
|
||||
repository := newCLIRepository(t)
|
||||
profilePath := filepath.Join(t.TempDir(), "profile with spaces.json")
|
||||
orderPath := filepath.Join(t.TempDir(), "check-order")
|
||||
t.Setenv("RELEASEKIT_CHECK_ORDER_FILE", orderPath)
|
||||
executable, err := os.Executable()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
settings := cli.Settings{
|
||||
Product: "Example Product",
|
||||
Remote: "origin",
|
||||
Checks: []cli.CheckCommand{{
|
||||
Args: []string{executable, "-test.run=TestCandidateCheckHelper", "--"},
|
||||
check := func(name string) cli.CheckCommand {
|
||||
return cli.CheckCommand{
|
||||
Args: []string{executable, "-test.run=TestCandidateCheckHelper", "--", name},
|
||||
Env: map[string]string{
|
||||
"RELEASEKIT_CHECK_HELPER": "1",
|
||||
"RELEASEKIT_CHECK_NAME": name,
|
||||
"RELEASEKIT_VERSION": "profile version",
|
||||
"RELEASEKIT_CANDIDATE": "profile commit",
|
||||
},
|
||||
}},
|
||||
}
|
||||
}
|
||||
settings := cli.Settings{
|
||||
Product: "Example Product",
|
||||
Remote: "origin",
|
||||
Checks: []cli.CheckCommand{check("first"), check("second")},
|
||||
}
|
||||
contents, err := json.Marshal(settings)
|
||||
if err != nil {
|
||||
@@ -80,8 +86,11 @@ func TestCheckCommandBindsConfiguredChecksToCapturedCandidate(t *testing.T) {
|
||||
t.Fatalf("run() status = %d; stdout=%q stderr=%q", status, stdout.String(), stderr.String())
|
||||
}
|
||||
commit := cliGitOutput(t, repository, "rev-parse", "HEAD")
|
||||
if want := "v1.2.3|" + commit; stderr.String() != want {
|
||||
t.Fatalf("configured check received %q, want captured candidate %q", stderr.String(), want)
|
||||
if got, err := os.ReadFile(orderPath); err != nil || string(got) != "first\nsecond\n" {
|
||||
t.Fatalf("configured check order = %q, error = %v", got, err)
|
||||
}
|
||||
if got, want := strings.Count(stderr.String(), "v1.2.3|"+commit), 2; got != want {
|
||||
t.Fatalf("configured checks received captured candidate %d times, want %d; stderr=%q", got, want, stderr.String())
|
||||
}
|
||||
if want := fmt.Sprintf("local candidate v1.2.3 at %s is valid\n", commit); stdout.String() != want {
|
||||
t.Fatalf("stdout = %q, want %q", stdout.String(), want)
|
||||
@@ -93,14 +102,6 @@ func TestPublishCommandPublishesConfiguredCandidate(t *testing.T) {
|
||||
settings := cli.Settings{
|
||||
Product: "Example Product",
|
||||
Remote: "origin",
|
||||
Checks: []cli.CheckCommand{{
|
||||
Args: []string{"go", "test", "-mod=readonly", "-count=1", "./..."},
|
||||
Env: map[string]string{
|
||||
"GOTOOLCHAIN": "local",
|
||||
"GOPROXY": "off",
|
||||
"GOSUMDB": "off",
|
||||
},
|
||||
}},
|
||||
}
|
||||
contents, err := json.Marshal(settings)
|
||||
if err != nil {
|
||||
@@ -207,6 +208,22 @@ func TestCandidateCheckHelper(t *testing.T) {
|
||||
if os.Getenv("RELEASEKIT_CHECK_HELPER") != "1" {
|
||||
return
|
||||
}
|
||||
if orderPath := os.Getenv("RELEASEKIT_CHECK_ORDER_FILE"); orderPath != "" {
|
||||
file, err := os.OpenFile(orderPath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o600)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(9)
|
||||
}
|
||||
if _, err := fmt.Fprintln(file, os.Getenv("RELEASEKIT_CHECK_NAME")); err != nil {
|
||||
_ = file.Close()
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(9)
|
||||
}
|
||||
if err := file.Close(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(9)
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(os.Stdout, "%s|%s", os.Getenv("RELEASEKIT_VERSION"), os.Getenv("RELEASEKIT_CANDIDATE"))
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ import (
|
||||
)
|
||||
|
||||
func TestReleaseWrapperPreservesNativeExitStatuses(t *testing.T) {
|
||||
if os.Getenv("RELEASEKIT_SKIP_WRAPPER_TEST") == "1" {
|
||||
t.Skip("release wrapper is already running candidate validation")
|
||||
}
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("POSIX release entry point")
|
||||
}
|
||||
@@ -26,6 +29,19 @@ func TestReleaseWrapperPreservesNativeExitStatuses(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
updatedSources := map[string][]byte{}
|
||||
for _, path := range []string{
|
||||
"check.go", "publish.go", "internal/candidate/check.go", "internal/publish/publish.go",
|
||||
"build_test.go", "publish_test.go", "internal/candidate/check_test.go",
|
||||
"cmd/releasekit/main_test.go", "cmd/releasekit/release_wrapper_test.go",
|
||||
"cmd/releasekit/internal/cli/config_test.go", "examples/releasekit.json",
|
||||
} {
|
||||
contents, err := os.ReadFile(filepath.Join(root, path))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
updatedSources[path] = contents
|
||||
}
|
||||
wrapper, err := os.ReadFile(filepath.Join(root, "scripts/release"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -36,6 +52,7 @@ func TestReleaseWrapperPreservesNativeExitStatuses(t *testing.T) {
|
||||
version string
|
||||
}{{"success", 0, "v1.2.3"}, {"invalid", 2, "invalid"}, {"rejected", 1, "v1.2.3"}, {"unknown", 3, "v1.2.3"}} {
|
||||
t.Run(mode.name, func(t *testing.T) {
|
||||
t.Setenv("RELEASEKIT_SKIP_WRAPPER_TEST", "1")
|
||||
repository := filepath.Join(t.TempDir(), "source")
|
||||
clone := exec.Command(realGit, "clone", "--local", "--no-hardlinks", root, repository)
|
||||
if output, err := clone.CombinedOutput(); err != nil {
|
||||
@@ -51,13 +68,27 @@ func TestReleaseWrapperPreservesNativeExitStatuses(t *testing.T) {
|
||||
if err := os.WriteFile(filepath.Join(repository, "cmd/releasekit/main.go"), controller, 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for path, contents := range updatedSources {
|
||||
if err := os.WriteFile(filepath.Join(repository, filepath.FromSlash(path)), contents, 0600); err != nil {
|
||||
t.Fatalf("write current source %s: %v", path, err)
|
||||
}
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Join(repository, "docs/releases"), 0700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(repository, "docs/releases/v1.2.3.md"), []byte("# ReleaseKit v1.2.3\n"), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
profile := map[string]any{"product": "ReleaseKit", "checks": []map[string]any{{"args": []string{"sh", "-c", "true"}}}}
|
||||
profile := map[string]any{
|
||||
"product": "ReleaseKit",
|
||||
"checks": []map[string]any{{"args": []string{"sh", "-c", "if [ -n \"$RELEASEKIT_TEST_ARM_GIT_SHIM\" ]; then : > \"$RELEASEKIT_TEST_ARM_GIT_SHIM\"; fi"}}},
|
||||
"delivery": map[string]any{
|
||||
"base_url": "https://gitea.maximumdirect.net",
|
||||
"owner": "eric",
|
||||
"repository": "ReleaseKit",
|
||||
"token_env": "RELEASEKIT_GITEA_TOKEN",
|
||||
},
|
||||
}
|
||||
content, _ := json.Marshal(profile)
|
||||
if err := os.WriteFile(filepath.Join(repository, "releasekit.json"), content, 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -80,7 +111,9 @@ func TestReleaseWrapperPreservesNativeExitStatuses(t *testing.T) {
|
||||
if mode.name == "unknown" {
|
||||
bin := t.TempDir()
|
||||
marker := filepath.Join(bin, "push-started")
|
||||
armMarker := filepath.Join(bin, "arm-git-shim")
|
||||
shim := `#!/bin/sh
|
||||
if [ -f "$RELEASEKIT_TEST_ARM_GIT_SHIM" ]; then
|
||||
for arg do
|
||||
if [ "$arg" = push ]; then
|
||||
"$RELEASEKIT_TEST_REAL_GIT" "$@" || exit 1
|
||||
@@ -89,7 +122,8 @@ for arg do
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
if [ -f "$RELEASEKIT_TEST_PUSH_MARKER" ]; then
|
||||
fi
|
||||
if [ -f "$RELEASEKIT_TEST_ARM_GIT_SHIM" ] && [ -f "$RELEASEKIT_TEST_PUSH_MARKER" ]; then
|
||||
for arg do if [ "$arg" = ls-remote ]; then exit 128; fi; done
|
||||
fi
|
||||
exec "$RELEASEKIT_TEST_REAL_GIT" "$@"
|
||||
@@ -101,6 +135,8 @@ exec "$RELEASEKIT_TEST_REAL_GIT" "$@"
|
||||
t.Setenv("RELEASEKIT_TEST_REAL_GIT", realGit)
|
||||
t.Setenv("RELEASEKIT_TEST_PUSH_MARKER", marker)
|
||||
t.Setenv("RELEASEKIT_TEST_MOVED_ENDPOINT", fetch)
|
||||
t.Setenv("RELEASEKIT_TEST_ARM_GIT_SHIM", armMarker)
|
||||
t.Setenv("RELEASEKIT_SKIP_WRAPPER_TEST", "1")
|
||||
}
|
||||
command := exec.Command("./scripts/release", mode.version)
|
||||
command.Dir = repository
|
||||
|
||||
Reference in New Issue
Block a user