fix(ci): keep operator release tags authoritative in Forgejo #3

Merged
morten-olsen merged 3 commits from fix/aed0777d-forgejo-release-tags into main 2026-10-29 19:44:01 +01:00
Owner

Summary

Forgejo push mirrors prune downstream-only operator tags. Move release ownership to approved Forgejo tags; main merges validate without publishing.

approved Forgejo vX.Y.Z → mirror → exact source/SHA + unused-artifact gate → existing GHCR + Helm publication

The gate rejects versions at or below published charts/source reservations, existing images or releases, wrong/missing source tags, commits outside main and lookup failures. Tag builds cannot bypass it. Each publisher rechecks immediately before its mutation, and image → release assets → Pages run in order. Publication serializes; historical chart downloads fail closed. A default-branch workflow_run follows successful tag image/releases for Pages, preserving the live main-only environment. Its read-only job executes trusted main code and verifies event origin, exact Forgejo tag/SHA, main ancestry and existing artifacts before exporting any release checkout SHA. No workflow artifacts or upstream executable output are consumed. No credentials, image sources, environment policies or publishing token scopes are added. Same-commit release runbook covers approval, verification and partial-publication recovery.

Evidence

  • Before: blank-filter mirror + downstream tag creation; recorded Postgres/Authentik deletions and published Authentik/DNS versions without tags (HOMEIT-434).
  • After: 20 isolated Python regressions pass, including local mirror deletion/retention, source provenance, chart version reuse and partial artifacts and individual failed-job retries. All four release workflows pass actionlint v1.7.7. Live read-only preflight rejects consumed versions and untagged publication; plans for the next unused versions pass.
  • Commit: 928270429c6aaa44dcca87d543f1fae4c6707391. Remote mirror CI passed at both the reviewed head and merged main; no new tag/release was created. Postgres/Nuclei have no Woodpecker registration; Authentik/DNS have Renovate-only Woodpecker config. GitHub mirror push checks run this safety suite and existing Go checks.

Merge danger

Door: two-way for code; reverting the workflow restores automatic main publication and therefore needs release approval.

Blast radius: pipeline

This merge publishes no image/chart/release and changes no live deployment. New stable tags require explicit Morten approval. Old missing-tag recovery can execute the old commit's workflow and overwrite an image; do not restore tags as part of merge.

Rollback and verification

  • Roll back: keep the tag-only trigger while fixing/reverting a gate defect; never reuse an artifact version. Published tags/artifacts persist after a revert.
  • Verify after rollout: source/mirror main match, Release Safety Tests and existing checks green, all publisher jobs skipped for main, authoritative tags retained and live workload digests unchanged. An approved tag publication remains an acceptance check before claiming release-path end-to-end verification.
  • Reviewers: Security Engineer HOMEIT-476 completed with no code blocker; owner retains implementation and rollout. No new credential/token scope is added. HOMEIT-434 retains all four operator changes and Homelab documentation.

Final verification

Merged as c19f58bc3592d60f8f852b3a8432dc9dd3d156b5. Main checks: Publish Helm Repository 40933617020 skipped, Tests 40933592194 success, Lint 40933592197 success, E2E Tests 40933592156 success, Release 40933592288 success. Release runs only safety tests; all tag publishers skip main, and the subsequent Helm workflow skips. Source/mirror refs match, mirror reports no error, chart history and actual live operator digests are unchanged. No new release/tag was created; positive publication awaits explicit approval.

## Summary Forgejo push mirrors prune downstream-only operator tags. Move release ownership to approved Forgejo tags; main merges validate without publishing. ```text approved Forgejo vX.Y.Z → mirror → exact source/SHA + unused-artifact gate → existing GHCR + Helm publication ``` The gate rejects versions at or below published charts/source reservations, existing images or releases, wrong/missing source tags, commits outside main and lookup failures. Tag builds cannot bypass it. Each publisher rechecks immediately before its mutation, and image → release assets → Pages run in order. Publication serializes; historical chart downloads fail closed. A default-branch `workflow_run` follows successful tag image/releases for Pages, preserving the live main-only environment. Its read-only job executes trusted main code and verifies event origin, exact Forgejo tag/SHA, main ancestry and existing artifacts before exporting any release checkout SHA. No workflow artifacts or upstream executable output are consumed. No credentials, image sources, environment policies or publishing token scopes are added. Same-commit [release runbook](https://code.olsen.cloud/homelab/postgres-operator/src/branch/fix/aed0777d-forgejo-release-tags/docs/releases.md) covers approval, verification and partial-publication recovery. ## Evidence - **Before:** blank-filter mirror + downstream tag creation; recorded Postgres/Authentik deletions and published Authentik/DNS versions without tags (HOMEIT-434). - **After:** 20 isolated Python regressions pass, including local mirror deletion/retention, source provenance, chart version reuse and partial artifacts and individual failed-job retries. All four release workflows pass actionlint v1.7.7. Live read-only preflight rejects consumed versions and untagged publication; plans for the next unused versions pass. - Commit: `928270429c6aaa44dcca87d543f1fae4c6707391`. Remote mirror CI passed at both the reviewed head and merged main; no new tag/release was created. Postgres/Nuclei have no Woodpecker registration; Authentik/DNS have Renovate-only Woodpecker config. GitHub mirror push checks run this safety suite and existing Go checks. ## Merge danger **Door:** two-way for code; reverting the workflow restores automatic main publication and therefore needs release approval. **Blast radius:** pipeline This merge publishes no image/chart/release and changes no live deployment. New stable tags require explicit Morten approval. Old missing-tag recovery can execute the old commit's workflow and overwrite an image; do not restore tags as part of merge. ## Rollback and verification - **Roll back:** keep the tag-only trigger while fixing/reverting a gate defect; never reuse an artifact version. Published tags/artifacts persist after a revert. - **Verify after rollout:** source/mirror main match, Release Safety Tests and existing checks green, all publisher jobs skipped for main, authoritative tags retained and live workload digests unchanged. An approved tag publication remains an acceptance check before claiming release-path end-to-end verification. - **Reviewers:** Security Engineer HOMEIT-476 completed with no code blocker; owner retains implementation and rollout. No new credential/token scope is added. HOMEIT-434 retains all four operator changes and Homelab documentation. ## Final verification Merged as `c19f58bc3592d60f8f852b3a8432dc9dd3d156b5`. Main checks: [Publish Helm Repository 40933617020](https://github.com/morten-olsen/homelab-postgres-operator/actions/runs/40933617020) skipped, [Tests 40933592194](https://github.com/morten-olsen/homelab-postgres-operator/actions/runs/40933592194) success, [Lint 40933592197](https://github.com/morten-olsen/homelab-postgres-operator/actions/runs/40933592197) success, [E2E Tests 40933592156](https://github.com/morten-olsen/homelab-postgres-operator/actions/runs/40933592156) success, [Release 40933592288](https://github.com/morten-olsen/homelab-postgres-operator/actions/runs/40933592288) success. Release runs only safety tests; all tag publishers skip main, and the subsequent Helm workflow skips. Source/mirror refs match, mirror reports no error, chart history and actual live operator digests are unchanged. No new release/tag was created; positive publication awaits explicit approval.
morten-olsen left a comment

Security review HOMEIT-476 at 928270429c. Standards: no blocking finding; existing image/chart destinations and publisher scopes retained, version job contents:read, all checkouts persist-credentials:false, no credential wiring or secret payload added. Live anonymous GitHub environment + deployment-branch-policies GET confirms custom main-only policy. Exact-head Release 40931760780 / Tests 40931760802 / Lint 40931761011 / E2E 40931760861 all success; Release jobs show safety success and all publishers skipped. Spec: no blocking finding. Reviewed full workflow diff and shared verifier: trusted default-branch verifier consumes event file, validates same-repo successful push/path/name/canonical tag/SHA, authoritative Forgejo tag/ancestry/history and predecessor artifacts before exporting strict outputs. Pages separately checks out validated SHA; no upstream artifact/cache consumption. Fresh stage checks refuse overwrite on job retry; HTTP failures and failed historical downloads fail closed. Ran 20/20 Python regressions locally; identical script/tests across all four. Non-blocking UNKNOWN: positive approved tag-to-image/release/Pages acceptance remains unverified; owner must verify SHA/digests/chart history and main-only deployment on first explicitly Morten-approved release. actionlint unavailable locally; author's v1.7.7 evidence not independently rerun. Recovery: preserve tag-only gate; reverting restores automatic publication and needs release approval; never reuse tags/artifacts. This comment authorizes no tag/release/policy/credential change. Findings per axis: Standards 0; Spec 1 non-blocking UNKNOWN acceptance limitation.

Security review HOMEIT-476 at 928270429c6aaa44dcca87d543f1fae4c6707391. Standards: no blocking finding; existing image/chart destinations and publisher scopes retained, version job contents:read, all checkouts persist-credentials:false, no credential wiring or secret payload added. Live anonymous GitHub environment + deployment-branch-policies GET confirms custom main-only policy. Exact-head Release 40931760780 / Tests 40931760802 / Lint 40931761011 / E2E 40931760861 all success; Release jobs show safety success and all publishers skipped. Spec: no blocking finding. Reviewed full workflow diff and shared verifier: trusted default-branch verifier consumes event file, validates same-repo successful push/path/name/canonical tag/SHA, authoritative Forgejo tag/ancestry/history and predecessor artifacts before exporting strict outputs. Pages separately checks out validated SHA; no upstream artifact/cache consumption. Fresh stage checks refuse overwrite on job retry; HTTP failures and failed historical downloads fail closed. Ran 20/20 Python regressions locally; identical script/tests across all four. Non-blocking UNKNOWN: positive approved tag-to-image/release/Pages acceptance remains unverified; owner must verify SHA/digests/chart history and main-only deployment on first explicitly Morten-approved release. actionlint unavailable locally; author's v1.7.7 evidence not independently rerun. Recovery: preserve tag-only gate; reverting restores automatic publication and needs release approval; never reuse tags/artifacts. This comment authorizes no tag/release/policy/credential change. Findings per axis: Standards 0; Spec 1 non-blocking UNKNOWN acceptance limitation.
Sign in to join this conversation.
No description provided.