Stop recovery when endpoint resolution changes

This commit is contained in:
2026-10-06 01:11:32 +00:00
parent f4d9cf20ec
commit bb5a8288e6
3 changed files with 21 additions and 5 deletions

View File

@@ -17,6 +17,7 @@ func TestReleaseWrapperPreservesNativeExitStatuses(t *testing.T) {
} }
_, source, _, _ := runtime.Caller(0) _, source, _, _ := runtime.Caller(0)
root := filepath.Clean(filepath.Join(filepath.Dir(source), "../..")) root := filepath.Clean(filepath.Join(filepath.Dir(source), "../.."))
originalPath := os.Getenv("PATH")
realGit, err := exec.LookPath("git") realGit, err := exec.LookPath("git")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@@ -119,15 +120,28 @@ exec "$RELEASEKIT_TEST_REAL_GIT" "$@"
if !strings.Contains(string(output), fmt.Sprintf("endpoint=%q", remote)) { if !strings.Contains(string(output), fmt.Sprintf("endpoint=%q", remote)) {
t.Fatalf("captured endpoint missing: %s", output) t.Fatalf("captured endpoint missing: %s", output)
} }
query := exec.Command(realGit, "ls-remote", "--refs", "--", remote, "refs/tags/v1.2.3") t.Setenv("PATH", originalPath)
// Execute the runbook's guarded recovery commands verbatim.
recovery := `test "$(git ls-remote --get-url -- "$releasekit_endpoint")" = "$releasekit_endpoint" &&
git ls-remote --refs -- "$releasekit_endpoint" "refs/tags/$releasekit_version"`
query := exec.Command("sh", "-c", recovery)
query.Dir = repository query.Dir = repository
query.Env = append(os.Environ(), "releasekit_endpoint="+remote, "releasekit_version=v1.2.3")
found, err := query.Output() found, err := query.Output()
if err != nil || len(found) == 0 { if err != nil || len(found) == 0 {
t.Fatalf("captured endpoint lost published tag: %q %v", found, err) t.Fatalf("captured endpoint recovery failed: %q %v", found, err)
} }
if !strings.Contains(string(found), cliGitOutput(t, repository, "rev-parse", "refs/tags/v1.2.3")) { if !strings.Contains(string(found), cliGitOutput(t, repository, "rev-parse", "refs/tags/v1.2.3")) {
t.Fatalf("wrong recovered tag: %s", found) t.Fatalf("wrong recovered tag: %s", found)
} }
cliGitRun(t, repository, "config", "url."+fetch+".insteadOf", remote)
blocked := exec.Command("sh", "-c", recovery)
blocked.Dir = repository
blocked.Env = query.Env
if output, err := blocked.Output(); err == nil || len(output) != 0 {
t.Fatalf("rewritten endpoint should block query: %q %v", output, err)
}
fetchQuery := exec.Command(realGit, "ls-remote", "--refs", "origin", "refs/tags/v1.2.3") fetchQuery := exec.Command(realGit, "ls-remote", "--refs", "origin", "refs/tags/v1.2.3")
fetchQuery.Dir = repository fetchQuery.Dir = repository
stale, err := fetchQuery.Output() stale, err := fetchQuery.Output()

View File

@@ -86,8 +86,8 @@ Check that Git URL rewriting still resolves this value to itself before querying
```sh ```sh
releasekit_endpoint='COPY_CAPTURED_ENDPOINT' releasekit_endpoint='COPY_CAPTURED_ENDPOINT'
releasekit_version='vX.Y.Z' releasekit_version='vX.Y.Z'
test "$(git ls-remote --get-url -- "$releasekit_endpoint")" = "$releasekit_endpoint" test "$(git ls-remote --get-url -- "$releasekit_endpoint")" = "$releasekit_endpoint" &&
git ls-remote --refs -- "$releasekit_endpoint" "refs/tags/$releasekit_version" git ls-remote --refs -- "$releasekit_endpoint" "refs/tags/$releasekit_version"
``` ```
A failed URL-equality check or remote query leaves the outcome unresolved. A failed URL-equality check or remote query leaves the outcome unresolved.

View File

@@ -356,7 +356,9 @@ runbook checks URL resolution and queries that exact endpoint, retaining tags
on failed or unresolved checks. Local wrapper fixtures use separate fetch and on failed or unresolved checks. Local wrapper fixtures use separate fetch and
push repositories; a lost acknowledgment changes the configured push URL, and push repositories; a lost acknowledgment changes the configured push URL, and
recovery still finds the intended object at the captured endpoint while the recovery still finds the intended object at the captured endpoint while the
fetch endpoint reports absence. Focused publication/wrapper tests pass. fetch endpoint reports absence. The guarded runbook commands are exercised
verbatim, including refusing a query after URL rewriting changes the endpoint.
Focused publication/wrapper tests pass.
### R10 — Medium: The boundary checker bans valid command-internal composition ### R10 — Medium: The boundary checker bans valid command-internal composition