Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions .github/workflows/policy-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,6 @@ jobs:
with:
ref: ${{ github.ref }}

- name: Require repository immutable-release enforcement
env:
GH_TOKEN: ${{ github.token }}
run: |
enabled="$(gh api "repos/${GITHUB_REPOSITORY}/immutable-releases" --jq '.enabled')"
[[ "$enabled" == "true" ]] || { echo "Immutable releases must be enabled before publication." >&2; exit 1; }

- name: Enforce upgrade gate and release evidence
env:
GH_TOKEN: ${{ github.token }}
Expand Down
2 changes: 1 addition & 1 deletion docs/policy-release-and-upgrades.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ The standalone published verifier runs without a repository checkout:
python3 verify_policy_release.py --output . --verify-only
```

Publish by enabling GitHub immutable releases, creating an exact tag, and dispatching `Publish Policy Release` against that tag with the governing issue and previous version. Minor releases require the number of an approved, merged PR whose merge commit is the tagged commit and whose approval is from a non-author reviewer. Major releases also require existing repository-relative ADR and migration-guide files at that commit. The workflow confirms the previous release, derives and enforces the upgrade gate, runs the full policy suite, notifies the issue and repository-dispatch channel, refuses overwrite, publishes all assets, downloads them into a clean directory, runs the standalone verifier, verifies GitHub reports the release immutable, and records postpublication evidence. GitHub's repository endpoint is the authoritative preflight check for immutable-release enforcement. [GitHub REST API](https://docs.github.com/en/rest/repos/repos#check-if-immutable-releases-are-enabled-for-a-repository)
Publish by enabling GitHub immutable releases, verifying that setting with an administrator-capable token, creating an exact tag, and dispatching `Publish Policy Release` against that tag with the governing issue and previous version. Minor releases require the number of an approved, merged PR whose merge commit is the tagged commit and whose approval is from a non-author reviewer. Major releases also require existing repository-relative ADR and migration-guide files at that commit. The workflow confirms the previous release, derives and enforces the upgrade gate, runs the full policy suite, notifies the issue and repository-dispatch channel, refuses overwrite, publishes all assets, downloads them into a clean directory, runs the standalone verifier, verifies GitHub reports the release immutable, and records postpublication evidence. GitHub's repository endpoint is the authoritative preflight check, but it requires repository Administration permission and therefore cannot be queried by the workflow's built-in `GITHUB_TOKEN`; the dispatcher must perform that check before creating the tag. [GitHub REST API](https://docs.github.com/en/rest/repos/repos#check-if-immutable-releases-are-enabled-for-a-repository)

Release publication is a material action. Notify through the governing release issue and configured mechanism, then continue when gates pass unless a defined human hard stop applies.
3 changes: 3 additions & 0 deletions tests/test_policy_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ def test_malformed_manifests_fail_deterministically(self) -> None:
def test_publication_workflow_authenticates_release_evidence(self) -> None:
workflow = (ROOT / ".github" / "workflows" / "policy-release.yml").read_text()
self.assertIn("pull-requests: read", workflow)
self.assertNotIn('repos/${GITHUB_REPOSITORY}/immutable-releases', workflow)
self.assertIn("releases/tags/${TAG}", workflow)
self.assertIn('[[ "$immutable" == "true" ]]', workflow)
self.assertIn('gh pr view "$REVIEW" --json author,mergeCommit,reviewDecision,state', workflow)
self.assertIn('.mergeCommit.oid', workflow)
self.assertIn('.user.login != $author', workflow)
Expand Down
Loading