fix(forgejo): document dry-run release lookup contract #1010

Merged
pullings merged 1 commit from sentry/957-dry-run-release-read-current into main 2026-08-27 17:18:49 +02:00
Owner

Refs #957

Decision

Config.DryRun still keeps the deliberate release-preview short-circuit: GetReleaseByTag makes no request so a dry-run preview follows the create path, matching the retired forgejo-api.sh behavior recorded by #557. Ordinary network reads execute normally; the draft-policy probes have separate, unchanged preview shortcuts.

The sentinel decision is explicit: keep the behavior, but change the dry-run lookup result from ErrNotFound to ErrDryRunLookup. A real Forgejo 404 remains ErrNotFound, so a skipped lookup cannot be mistaken for evidence that a release is absent.

Caller audit

Every production caller of GetReleaseByTag was checked:

  • internal/decide.pendingCutEvidence (the #958 recovery evidence) maps ErrNotFound from an executing query to EvidenceAbsent, but maps ErrDryRunLookup to EvidenceUnknown. cmd/rt/decide.go intentionally constructs the read-only client without DryRun, including for rt decide --dry-run, so this path executes its evidence reads.
  • internal/release.cutter.Fire (the rt release path, whose client is dry-run when requested) accepts either a real absence or the deliberate preview skip and continues to the create-summary path. It does not claim a replay.

No other production caller exists. The existing ListDraftReleases and CanSeeDrafts dry-run policy shortcuts are unchanged and are called out separately in the client contract.

Verification

  • TestDryRunReadPolicy: an ordinary GetDefaultBranch read executes once under dry-run; GetReleaseByTag makes no request and returns only ErrDryRunLookup.
  • TestGetReleaseByTagNotFoundSentinel: an executing 404 returns only ErrNotFound.
  • Pending-cut evidence and cutter tests cover the two audited caller policies, including the create path after a skipped lookup.
  • 118 Bats tests, go test -count=1 ./..., go vet ./..., go build ./..., gofmt, and git diff --check pass.

This change does not touch #925.

Refs #957 ## Decision `Config.DryRun` still keeps the deliberate release-preview short-circuit: `GetReleaseByTag` makes no request so a dry-run preview follows the create path, matching the retired `forgejo-api.sh` behavior recorded by #557. Ordinary network reads execute normally; the draft-policy probes have separate, unchanged preview shortcuts. The sentinel decision is explicit: keep the behavior, but change the dry-run lookup result from `ErrNotFound` to `ErrDryRunLookup`. A real Forgejo 404 remains `ErrNotFound`, so a skipped lookup cannot be mistaken for evidence that a release is absent. ## Caller audit Every production caller of `GetReleaseByTag` was checked: - `internal/decide.pendingCutEvidence` (the #958 recovery evidence) maps `ErrNotFound` from an executing query to `EvidenceAbsent`, but maps `ErrDryRunLookup` to `EvidenceUnknown`. `cmd/rt/decide.go` intentionally constructs the read-only client without `DryRun`, including for `rt decide --dry-run`, so this path executes its evidence reads. - `internal/release.cutter.Fire` (the `rt release` path, whose client is dry-run when requested) accepts either a real absence or the deliberate preview skip and continues to the create-summary path. It does not claim a replay. No other production caller exists. The existing `ListDraftReleases` and `CanSeeDrafts` dry-run policy shortcuts are unchanged and are called out separately in the client contract. ## Verification - `TestDryRunReadPolicy`: an ordinary `GetDefaultBranch` read executes once under dry-run; `GetReleaseByTag` makes no request and returns only `ErrDryRunLookup`. - `TestGetReleaseByTagNotFoundSentinel`: an executing 404 returns only `ErrNotFound`. - Pending-cut evidence and cutter tests cover the two audited caller policies, including the create path after a skipped lookup. - 118 Bats tests, `go test -count=1 ./...`, `go vet ./...`, `go build ./...`, `gofmt`, and `git diff --check` pass. This change does not touch #925.
fix(forgejo): document dry-run release lookup contract
All checks were successful
ac-closure-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
manifest-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 8s
manifest-check / check (pull_request) Successful in 0s
register-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
register-check / register-drift check (pull_request) Successful in 8s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 34s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 4s
tests / dated-examples (pull_request) Successful in 4s
tests / shellcheck (pull_request) Successful in 3s
workflow-parse-check / toolkit-self parse guard and controls (pull_request) Successful in 4s
workflow-parse-check / workflow parse and schema (pull_request) Successful in 5s
workflow-parse-check / check (pull_request) Successful in 0s
changelog-body-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 1m36s
check-self-bootstrap / check (pull_request) Successful in 1m50s
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 2m21s
go-ci / lint + build + test (pull_request) Successful in 2m38s
ac-closure-check / ac-closure check (pull_request) Successful in 3m10s
ac-closure-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m38s
fragment-check / changelog fragment-kind (pull_request) Successful in 3m44s
fragment-check / check (pull_request) Successful in 0s
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 3m59s
changelog-body-check / check (pull_request) Successful in 0s
254a731187
lookout approved these changes 2026-08-27 17:17:39 +02:00
lookout left a comment

APPROVED — exact head 254a731187.

Reviewed the #957 dry-run lookup contract and all affected callers. GetReleaseByTag now distinguishes a real 404 (ErrNotFound) from a deliberately skipped Config.DryRun lookup (ErrDryRunLookup); pendingCutEvidence maps the latter to unknown, while cmd/rt/decide keeps its safeguard read executing in --dry-run. The release cutter preserves the dry-run create-summary path without treating the skipped lookup as absence. The call-site audit found no other consumers needing adjustment.

Verification at this head: targeted Forgejo, pending-evidence, and cutter tests pass; go test -count=1 ./..., go vet ./..., go build ./..., bats tests (118/118), repository gofmt, and git diff --check all pass. Server head is exact and all 25 status contexts are success. No findings.

APPROVED — exact head 254a731187b1dabd03bf6e3209b6a1c30a379f42. Reviewed the #957 dry-run lookup contract and all affected callers. GetReleaseByTag now distinguishes a real 404 (ErrNotFound) from a deliberately skipped Config.DryRun lookup (ErrDryRunLookup); pendingCutEvidence maps the latter to unknown, while cmd/rt/decide keeps its safeguard read executing in --dry-run. The release cutter preserves the dry-run create-summary path without treating the skipped lookup as absence. The call-site audit found no other consumers needing adjustment. Verification at this head: targeted Forgejo, pending-evidence, and cutter tests pass; go test -count=1 ./..., go vet ./..., go build ./..., bats tests (118/118), repository gofmt, and git diff --check all pass. Server head is exact and all 25 status contexts are success. No findings.
lookout approved these changes 2026-08-27 17:17:39 +02:00
lookout left a comment

APPROVED — exact head 254a731187.

Reviewed the #957 dry-run lookup contract and all affected callers. GetReleaseByTag now distinguishes a real 404 (ErrNotFound) from a deliberately skipped Config.DryRun lookup (ErrDryRunLookup); pendingCutEvidence maps the latter to unknown, while cmd/rt/decide keeps its safeguard read executing in --dry-run. The release cutter preserves the dry-run create-summary path without treating the skipped lookup as absence. The call-site audit found no other consumers needing adjustment.

Verification at this head: targeted Forgejo, pending-evidence, and cutter tests pass; go test -count=1 ./..., go vet ./..., go build ./..., bats tests (118/118), repository gofmt, and git diff --check all pass. Server head is exact and all 25 status contexts are success. No findings.

APPROVED — exact head 254a731187b1dabd03bf6e3209b6a1c30a379f42. Reviewed the #957 dry-run lookup contract and all affected callers. GetReleaseByTag now distinguishes a real 404 (ErrNotFound) from a deliberately skipped Config.DryRun lookup (ErrDryRunLookup); pendingCutEvidence maps the latter to unknown, while cmd/rt/decide keeps its safeguard read executing in --dry-run. The release cutter preserves the dry-run create-summary path without treating the skipped lookup as absence. The call-site audit found no other consumers needing adjustment. Verification at this head: targeted Forgejo, pending-evidence, and cutter tests pass; go test -count=1 ./..., go vet ./..., go build ./..., bats tests (118/118), repository gofmt, and git diff --check all pass. Server head is exact and all 25 status contexts are success. No findings.
pullings deleted branch sentry/957-dry-run-release-read-current 2026-08-27 17:18:49 +02:00
Sign in to join this conversation.
No description provided.