Align release publication policy and runbook
This commit is contained in:
@@ -48,6 +48,7 @@ func TestReleaseCommandRejectsUnpublishedOrExistingCandidates(t *testing.T) {
|
||||
fixture.extraEnv = append(fixture.extraEnv, "NARRATIO_RELEASE_CHECKER_MODE=fail")
|
||||
fixture.mustFail(t, "release candidate validation failed")
|
||||
fixture.requireNoTag(t)
|
||||
assertCheckerCalls(t, fixture, 1)
|
||||
})
|
||||
t.Run("local tag exists", func(t *testing.T) {
|
||||
fixture := newReleaseFixture(t)
|
||||
@@ -90,6 +91,8 @@ git push -q origin main
|
||||
|
||||
func TestReleaseCommandPushesOnlyTheRecordedLightweightTag(t *testing.T) {
|
||||
fixture := newReleaseFixture(t)
|
||||
writeReleaseFixtureFile(t, filepath.Join(fixture.worktree, ".git", "info", "exclude"), "ignored.tmp\n", 0o644)
|
||||
writeReleaseFixtureFile(t, filepath.Join(fixture.worktree, "ignored.tmp"), "local-only\n", 0o644)
|
||||
candidate := fixture.gitOutput("rev-parse", "HEAD^{commit}")
|
||||
output, err := fixture.run()
|
||||
if err != nil {
|
||||
@@ -113,13 +116,14 @@ func TestReleaseCommandPushesOnlyTheRecordedLightweightTag(t *testing.T) {
|
||||
if got := strings.Fields(fixture.gitOutput("--git-dir", fixture.origin, "for-each-ref", "--format=%(refname)", "refs/heads", "refs/tags")); !slicesEqual(got, []string{"refs/heads/main", "refs/tags/v1.2.3"}) {
|
||||
t.Fatalf("remote refs = %#v", got)
|
||||
}
|
||||
assertCheckerCalls(t, fixture, 1)
|
||||
}
|
||||
|
||||
func TestReleaseCommandKeepsUnpublishedLocalTagAfterPushFailure(t *testing.T) {
|
||||
func TestReleaseCommandRetainsLocalTagAfterUnconfirmedPush(t *testing.T) {
|
||||
fixture := newReleaseFixture(t)
|
||||
writeReleaseFixtureFile(t, filepath.Join(fixture.origin, "hooks", "pre-receive"), "#!/bin/sh\nexit 1\n", 0o755)
|
||||
output, err := fixture.run()
|
||||
if err == nil || !strings.Contains(output, "local tag v1.2.3 was created but not published") {
|
||||
if err == nil || !strings.Contains(output, "tag push for v1.2.3 failed or is unconfirmed") || strings.Contains(output, "release: published") || strings.Contains(output, "not published") {
|
||||
t.Fatalf("push failure = %v\n%s", err, output)
|
||||
}
|
||||
if got := fixture.gitOutput("cat-file", "-t", "refs/tags/v1.2.3"); got != "commit" {
|
||||
@@ -128,12 +132,25 @@ func TestReleaseCommandKeepsUnpublishedLocalTagAfterPushFailure(t *testing.T) {
|
||||
if output, err := runReleaseGit(fixture.worktree, "--git-dir", fixture.origin, "show-ref", "--verify", "refs/tags/v1.2.3"); err == nil {
|
||||
t.Fatalf("remote tag exists after failed push: %s", output)
|
||||
}
|
||||
assertCheckerCalls(t, fixture, 1)
|
||||
}
|
||||
|
||||
func assertCheckerCalls(t *testing.T, fixture *releaseFixture, want int) {
|
||||
t.Helper()
|
||||
data, err := os.ReadFile(fixture.checkerLog)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := len(strings.Fields(string(data))); got != want {
|
||||
t.Fatalf("candidate checker called %d times, want %d: %q", got, want, data)
|
||||
}
|
||||
}
|
||||
|
||||
type releaseFixture struct {
|
||||
worktree string
|
||||
origin string
|
||||
extraEnv []string
|
||||
worktree string
|
||||
origin string
|
||||
checkerLog string
|
||||
extraEnv []string
|
||||
}
|
||||
|
||||
func newReleaseFixture(t *testing.T) *releaseFixture {
|
||||
@@ -154,7 +171,7 @@ func newReleaseFixture(t *testing.T) *releaseFixture {
|
||||
writeReleaseFixtureFile(t, filepath.Join(worktree, "docs", "releases", "v1.2.3.md"), "# Narratio v1.2.3\n", 0o644)
|
||||
writeReleaseFixtureFile(t, filepath.Join(worktree, "README.md"), "fixture\n", 0o644)
|
||||
|
||||
fixture := &releaseFixture{worktree: worktree, origin: origin}
|
||||
fixture := &releaseFixture{worktree: worktree, origin: origin, checkerLog: filepath.Join(root, "checker.log")}
|
||||
fixture.git("init", "-qb", "main")
|
||||
fixture.git("config", "user.email", "releasecheck@example.test")
|
||||
fixture.git("config", "user.name", "Release Check")
|
||||
@@ -176,7 +193,8 @@ func (fixture *releaseFixture) runWith(args ...string) (string, error) {
|
||||
commandArgs := append([]string{filepath.Join(fixture.worktree, "scripts", "release.sh")}, args...)
|
||||
command := exec.Command("sh", commandArgs...)
|
||||
command.Dir = fixture.worktree
|
||||
command.Env = append(os.Environ(), fixture.extraEnv...)
|
||||
command.Env = append(os.Environ(), "NARRATIO_RELEASE_CHECKER_LOG="+fixture.checkerLog)
|
||||
command.Env = append(command.Env, fixture.extraEnv...)
|
||||
output, err := command.CombinedOutput()
|
||||
return string(output), err
|
||||
}
|
||||
@@ -238,6 +256,7 @@ func writeReleaseFixtureFile(t *testing.T, path, contents string, mode os.FileMo
|
||||
|
||||
const releaseCandidateStub = `#!/bin/sh
|
||||
set -eu
|
||||
printf 'called\n' >> "$NARRATIO_RELEASE_CHECKER_LOG"
|
||||
|
||||
case "${NARRATIO_RELEASE_CHECKER_MODE:-success}" in
|
||||
success) ;;
|
||||
|
||||
Reference in New Issue
Block a user