Preserve candidate failures when initializing publication records

This commit is contained in:
2026-11-02 22:17:29 +00:00
parent da1839c6d2
commit 0d19a5546f
3 changed files with 72 additions and 6 deletions

View File

@@ -19,6 +19,67 @@ import (
const releaseNote = "# Sample App v1.2.3\n\nA source release.\n\nUpgrade notes stay intact.\n"
func TestPublishStopsOnReleaseNoteCaptureFailure(t *testing.T) {
for _, missing := range []bool{false, true} {
t.Run(fmt.Sprintf("missing=%t", missing), func(t *testing.T) {
repo := newPublishFixture(t)
if missing {
gitRun(t, repo.work, "rm", "docs/releases/v1.2.3.md")
} else {
writeFile(t, repo.work, "docs/releases/v1.2.3.md", "# Wrong Product v1.2.3\n")
gitRun(t, repo.work, "add", ".")
}
gitRun(t, repo.work, "commit", "-m", "Invalid note")
called := false
result, err := releasekit.Publish(t.Context(), releasekit.ReleaseRequest{
RepositoryDir: repo.work, Product: "Sample App", Version: "v1.2.3",
AdditionalChecks: func(context.Context, releasekit.Candidate) error { called = true; return nil },
})
if err == nil || called || result.State != releasekit.PublicationNotAttempted {
t.Fatalf("rejected candidate = %#v, %v; callback=%t", result, err, called)
}
if missing {
var exitErr *exec.ExitError
if !errors.As(err, &exitErr) {
t.Fatalf("missing note lost Git cause: %v", err)
}
}
if result.RecordError != nil || result.RecordPath == "" || result.Evidence.CandidateCommit == "" {
t.Fatalf("partial evidence was not saved: %#v", result)
}
if tags := gitText(t, repo.work, "tag", "--list", "v1.2.3"); tags != "" {
t.Fatalf("created tag for rejected candidate: %s", tags)
}
if tags := gitText(t, repo.work, "ls-remote", "origin", "refs/tags/v1.2.3"); tags != "" {
t.Fatalf("pushed tag for rejected candidate: %s", tags)
}
})
}
}
func TestPublishStorageResolutionFailureIsNonfatal(t *testing.T) {
repo := newPublishFixture(t)
realGit := mustLookPath(t, "git")
bin := t.TempDir()
wrapper := "#!/bin/sh\nfor arg in \"$@\"; do\n [ \"$arg\" = --git-common-dir ] && exit 71\ndone\nexec " + shellQuote(realGit) + " \"$@\"\n"
if err := os.WriteFile(filepath.Join(bin, "git"), []byte(wrapper), 0o755); err != nil {
t.Fatal(err)
}
t.Setenv("PATH", bin+string(os.PathListSeparator)+os.Getenv("PATH"))
called := false
result, err := releasekit.Publish(t.Context(), releasekit.ReleaseRequest{
RepositoryDir: repo.work, Product: "Sample App", Version: "v1.2.3",
AdditionalChecks: func(context.Context, releasekit.Candidate) error { called = true; return nil },
})
var exitErr *exec.ExitError
if err != nil || !called || result.State != releasekit.PublicationPublished || result.RecordPath != "" || !errors.As(result.RecordError, &exitErr) || exitErr.ExitCode() != 71 {
t.Fatalf("publication with failed storage lookup = %#v, %v; callback=%t", result, err, called)
}
if got := gitText(t, repo.work, "ls-remote", "origin", "refs/tags/v1.2.3"); !strings.Contains(got, result.TagObject) {
t.Fatalf("published object missing: %s", got)
}
}
func TestPublishPreservesHookDirectoryEnvironment(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("directory-derived PWD is a POSIX behavior")