diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index cdeebc1..d219b17 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -38,6 +38,13 @@ on: description: Run the Codex reviewer. type: boolean default: true + block_on_severity: + description: >- + Fail the review job when a reviewer reports a [CRITICAL] or [HIGH] + finding, turning review into a merge gate. Off by default: reviews + are advisory unless a repo opts in. + type: boolean + default: false secrets: CLAUDE_CODE_OAUTH_TOKEN: required: false @@ -267,6 +274,21 @@ jobs: gh pr comment "$PR_NUMBER" --repo "$REPO" --body-file /tmp/review-formatted.txt > /dev/null fi + # Opt-in merge gate. The review comment is upserted by the step above + # regardless, so a blocking finding still gets posted before the job + # goes red. Runs on always() so it also fires when an earlier step + # failed — a review that produced no output cannot match, so it will + # not block. + - name: Fail on blocking findings + if: always() && inputs.block_on_severity + run: | + if [ -s /tmp/review.txt ] && grep -qE '\[(CRITICAL|HIGH)\]' /tmp/review.txt; then + echo "::error::Review reported CRITICAL or HIGH severity findings" + grep -nE '\[(CRITICAL|HIGH)\]' /tmp/review.txt + exit 1 + fi + echo "No blocking findings" + codex-review: needs: changes # Skip on forks — secrets aren't available to fork PRs. @@ -454,3 +476,18 @@ jobs: - name: Fail on Codex runtime error if: steps.codex-review.outputs.exit_code != '0' run: exit 1 + + # Opt-in merge gate. The review comment is upserted by the step above + # regardless, so a blocking finding still gets posted before the job + # goes red. Runs on always() so it also fires when an earlier step + # failed — a review that produced no output cannot match, so it will + # not block. + - name: Fail on blocking findings + if: always() && inputs.block_on_severity + run: | + if [ -s /tmp/review.txt ] && grep -qE '\[(CRITICAL|HIGH)\]' /tmp/review.txt; then + echo "::error::Review reported CRITICAL or HIGH severity findings" + grep -nE '\[(CRITICAL|HIGH)\]' /tmp/review.txt + exit 1 + fi + echo "No blocking findings" diff --git a/README.md b/README.md index cb57f83..78fb579 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,25 @@ review config and prompts. ``` Optional inputs: `config_path` (default `.github/review-agents.json`), - `enable_claude` / `enable_codex` (default `true`). + `enable_claude` / `enable_codex` (default `true`), and + `block_on_severity` (default `false`). + + **`block_on_severity`** turns review into a merge gate: the review job + fails when a reviewer reports a `[CRITICAL]` or `[HIGH]` finding. Off by + default — reviews are advisory unless a repo opts in: + + ```yaml + jobs: + review: + uses: Provable-Games/.github/.github/workflows/code-review.yml@v1 + with: + block_on_severity: true + secrets: inherit + ``` + + The review comment is posted either way, so a blocking finding is always + visible before the job goes red. A review that errored or produced no + output cannot match, so it never blocks on its own. 2. Add `.github/review-agents.json` describing what to review: