ci(gate): add pull_request_review fallback trigger for qa/security review workflows #2153

Closed
core-be wants to merge 2 commits from fix/internal-760-review-event-trigger into main
2 changed files with 46 additions and 25 deletions
+22 -14
View File
@@ -10,19 +10,17 @@
# - `pull_request_target`: opened, synchronize, reopened
# → initial status posts when PR opens / re-pushes
# - `pull_request_review` types: [submitted]
# → re-evaluate when a team member submits an APPROVE review so
# the gate flips immediately (no wait for the next push or
# slash-command). Verified live: sop-tier-check.yml uses this
# same event and provably fires (produces
# `sop-tier-check / tier-check (pull_request_review)` contexts).
# The job-level `if:` guard checks
# `github.event.review.state == 'APPROVED' || 'approved'` so
# only APPROVE reviews run the evaluator; COMMENT and
# → defensive fallback. Empirical evidence (live status audit)
# `pull_request_review_approved` does not always fire on this
# Gitea instance, while `pull_request_review` does (verified
# by sop-tier-check live status context). The job guard checks
# both `github.event.review.type` and `github.event.review.state`
# so only APPROVE reviews run the evaluator; COMMENT and
# REQUEST_CHANGES are skipped at the job level.
# Branch-protection requires the `(pull_request_target)`
# context variant, so the review-event path EXPLICITLY POSTS
# the required context via the API. Trust boundary preserved
# (BASE ref, no PR-head).
# - `pull_request_review_approved`
# → retained as a forward-compatible trigger in case a future
# Gitea version fires it reliably. The same job guard covers
# both events.
# - comment refires are handled by `sop-checklist.yml` review-refire job
# → `/qa-recheck` slash-command re-evaluates this gate.
# Workflow name = `qa-review` ; job name = `approved`.
@@ -99,6 +97,7 @@ on:
types: [opened, synchronize, reopened]
pull_request_review:
types: [submitted]
pull_request_review_approved:
permissions:
contents: read
@@ -115,8 +114,11 @@ jobs:
# Comment-triggered refires live in sop-checklist.yml review-refire job.
if: |
github.event_name == 'pull_request_target' ||
github.event_name == 'pull_request_review_approved' ||
(github.event_name == 'pull_request_review' &&
(github.event.review.state == 'APPROVED' || github.event.review.state == 'approved'))
(github.event.review.type == 'pull_request_review_approved' ||
github.event.review.state == 'APPROVED' ||
github.event.review.state == 'approved'))
runs-on: ubuntu-latest
steps:
- name: Privilege check (A1.1 — INFORMATIONAL log only, NOT a gate)
@@ -187,7 +189,13 @@ jobs:
# for the explicit status POST. Evaluator step stays on
# SOP_TIER_CHECK_TOKEN (read-only) per deliberate security
# separation: eval computes, POST writes, never the same cred.
if: github.event_name == 'pull_request_review' && always()
if: |
(github.event_name == 'pull_request_review_approved' ||
(github.event_name == 'pull_request_review' &&
(github.event.review.type == 'pull_request_review_approved' ||
github.event.review.state == 'APPROVED' ||
github.event.review.state == 'approved')))
&& always()
env:
GITEA_TOKEN: ${{ secrets.STATUS_POST_TOKEN }}
GITEA_HOST: git.moleculesai.app
+24 -11
View File
@@ -9,15 +9,18 @@
#
# A1-α addendum (internal#760): review-event trigger added so the security
# gate flips immediately when a team member submits an APPROVE review.
# Uses `pull_request_review` types: [submitted] — verified live via
# sop-tier-check.yml which provably fires this event (produces
# `sop-tier-check / tier-check (pull_request_review)` contexts).
# The job-level `if:` guard checks
# `github.event.review.state == 'APPROVED' || 'approved'` so only APPROVE
# reviews run the evaluator; COMMENT and REQUEST_CHANGES are skipped at
# the job level. Branch-protection requires the `(pull_request_target)`
# context variant, so the review-event path EXPLICITLY POSTS the required
# context via the API. Trust boundary preserved (BASE ref, no PR-head).
# We listen to BOTH `pull_request_review` (types: [submitted]) and
# `pull_request_review_approved`. Empirical evidence (live status audit)
# `pull_request_review_approved` does not always fire on this Gitea
# instance, while `pull_request_review` does (verified by sop-tier-check
# live status context). The job guard checks both
# `github.event.review.type` and `github.event.review.state` so only
# APPROVE reviews run the evaluator; COMMENT and REQUEST_CHANGES are
# skipped at the job level. `pull_request_review_approved` is retained
# as a forward-compatible trigger. Branch-protection requires the
# `(pull_request_target)` context variant, so the review-event path
# EXPLICITLY POSTS the required context via the API. Trust boundary
# preserved (BASE ref, no PR-head).
name: security-review
@@ -26,6 +29,7 @@ on:
types: [opened, synchronize, reopened]
pull_request_review:
types: [submitted]
pull_request_review_approved:
permissions:
contents: read
@@ -42,8 +46,11 @@ jobs:
# Comment-triggered refires live in sop-checklist.yml review-refire job.
if: |
github.event_name == 'pull_request_target' ||
github.event_name == 'pull_request_review_approved' ||
(github.event_name == 'pull_request_review' &&
(github.event.review.state == 'APPROVED' || github.event.review.state == 'approved'))
(github.event.review.type == 'pull_request_review_approved' ||
github.event.review.state == 'APPROVED' ||
github.event.review.state == 'approved'))
runs-on: ubuntu-latest
steps:
- name: Privilege check (A1.1 — INFORMATIONAL log only, NOT a gate)
@@ -100,7 +107,13 @@ jobs:
# for the explicit status POST. Evaluator step stays on
# SOP_TIER_CHECK_TOKEN (read-only) per deliberate security
# separation: eval computes, POST writes, never the same cred.
if: github.event_name == 'pull_request_review' && always()
if: |
(github.event_name == 'pull_request_review_approved' ||
(github.event_name == 'pull_request_review' &&
(github.event.review.type == 'pull_request_review_approved' ||
github.event.review.state == 'APPROVED' ||
github.event.review.state == 'approved')))
&& always()
env:
GITEA_TOKEN: ${{ secrets.STATUS_POST_TOKEN }}
GITEA_HOST: git.moleculesai.app