Repository navigation
ci(governance): harden pull_request_target governance workflows - #84
Conversation
ptiper
left a comment
There was a problem hiding this comment.
Two small edge cases worth considering before merging (reviewed with Antigravity):
| uses: actions/checkout@v7 | ||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| repository: ${{ github.repository_owner }}/.github |
There was a problem hiding this comment.
To match the PR description (always checking out .github from main), should we add ref: main explicitly here?
actions/checkout only defaults to a repository's default branch when checking out a different repository. When called from .github itself, omitting ref makes it check out the triggering workflow's github.ref instead (for example a release branch, or untrusted PR code if any future workflow in .github ever calls this from a standard pull_request trigger). Setting ref: main keeps live main rule updates working across all repos without that same-repo quirk.
There was a problem hiding this comment.
Great catch, thank you! Added ref: main explicitly in a80bd05 so runs inside .github itself always check out main rather than falling back to github.ref.
| ) | ||
| return 0 | ||
|
|
||
| if eval_exit_code != 0 and not summary_path.is_file(): |
There was a problem hiding this comment.
Right now this crash handler only triggers when summary.txt is missing (for example if uv fails to start). When pr_validator.py hits a runtime exception (like an expired token, a GitHub API 5xx, or a missing rules file), its top-level exception handler still writes ERROR: ... into summary.txt and exits with code 1, so the gate treats it as normal missing approvals ("Pending required approvals" with a green workflow job) instead of posting an error status.
Could we handle that in this PR too (for example by exiting with code 2 on unexpected exceptions in pr_validator.py or checking for an ERROR: prefix here, while still writing the summary to the job summary so the failure reason stays easy to see)?
There was a problem hiding this comment.
Good call — updated in a80bd05:
pr_validator.pynow exits with code2on unexpected exceptions inmain()(leaving exit code1strictly for unsatisfied governance rules).run_governance_gate.pytreats exit codesnot in (0, 1), missing/emptysummary.txt, orERROR:-prefixed summaries as validator execution errors, appends the failure details to$GITHUB_STEP_SUMMARY, posts an"error"commit status, and fails the workflow job.
…me errors - Explicitly set `ref: main` when checking out `.github-central` in `reusable-governance.yml` so same-repo runs inside `.github` evaluate against `main` rather than `github.ref`. - Exit with code 2 on unexpected runtime exceptions in `pr_validator.py` and treat exit codes `!= 1` or `ERROR:`-prefixed summaries in `run_governance_gate.py` as execution errors, writing failure details to `GITHUB_STEP_SUMMARY` and posting an `error` commit status.
|
LGTM thanks! 2 follow-up actions would be to update meeting-minutes/.github/workflows/governance.yml SHA pin and update the Actions Event policy to match. |
Hardens .github/workflows/governance.yml for pull_request_target security best practices and pins the central reusable governance workflow to the hardened revision merged in Universal-Commerce-Protocol/.github#84 (97682ca4ad40b4321d60bb58c869e12f19a8bcae):
Hardens .github/workflows/governance.yml for pull_request_target security best practices and pins the central reusable governance workflow to the hardened revision merged in Universal-Commerce-Protocol/.github#84 (97682ca4ad40b4321d60bb58c869e12f19a8bcae):
Hardens .github/workflows/governance.yml for pull_request_target security best practices and pins the central reusable governance workflow to the hardened revision merged in Universal-Commerce-Protocol/.github#84 (97682ca4ad40b4321d60bb58c869e12f19a8bcae)
Hardens .github/workflows/governance.yml for pull_request_target security best practices and pins the central reusable governance workflow to the hardened revision merged in Universal-Commerce-Protocol/.github#84 (97682ca4ad40b4321d60bb58c869e12f19a8bcae)
Hardens .github/workflows/governance.yml for pull_request_target security best practices and pins the central reusable governance workflow to the hardened revision merged in Universal-Commerce-Protocol/.github#84 (97682ca4ad40b4321d60bb58c869e12f19a8bcae)
Description
Hardens
.github/workflows/reusable-governance.ymland.github/workflows/governance.ymlforpull_request_targetsecurity best practices:Check out PR codestep fromreusable-governance.ymlso only trusted central governance scripts fromUniversal-Commerce-Protocol/.github(ref: main) are checked out into.github-centralwithpersist-credentials: false.pr_validator.pyexecution, workflow summary/annotation publishing, andGovernance / Approvalscommit status posting into a dedicated, unit-tested Python stdlib helper (org-tools/governance/scripts/run_governance_gate.py) receiving all inputs strictly viaenv:variables.workflow_runviaworkflow_run.pull_requests[0].number(same-repo PRs) and paginated/repos/{repo}/pulls?state=open&sort=updated&direction=descmatchinghead.sha(fork and same-repo PRs with zero search index lag, falling back to/commits/{sha}/pullsand/search/issuespreferring open PRs), and verifiespr.head.sha == commit_shaboth before and after runningpr_validator.pyso superseded commits never receive a newer head's status. Also surfaces unexpectedpr_validator.pycrashes or runtime exceptions (exit code2, missing/emptysummary.txt, orERROR:-prefixed summary) in$GITHUB_STEP_SUMMARY, commit status"error", and non-zero step exit.permissions: {}, restricts job permissions strictly tostatuses: writewithtimeout-minutes: 5, disablessetup-uvcache writes (enable-cache: "false",python-version: "3.12"), scopespull_request_targettomainandrelease/**base branches, and pinsactions/checkout(v7.0.1) andastral-sh/setup-uv(v8.1.0) to full 40-character commit SHAs.Category (Required)
Please select one or more categories that apply to this change.
ucp-schematool (resolver, linter, validator). (Requires Maintainer approval)Related Issues
N/A
Checklist
!for breaking changes).Screenshots / Logs (if applicable)
Verified locally with
unittest discover -s org-tools/governance/tests(74/74 tests passing),pre-commit --all-files,check_copyright.py, and GitHub Actionszizmorscan.