diff --git a/README.md b/README.md index dabb35c..b3df7a6 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ merge. 4. **Merge gate** — the job fails if any **P0/P1** is found; mark the check "required" in branch protection to block the merge. 5. **Per-commit loop** — `synchronize` re-reviews on every new push; comment - `/orcarouter-review` on a PR to re-run on demand. The comment re-run posts + `/orca-code-review` on a PR to re-run on demand. The comment re-run posts fresh review comments but does **not** update the required merge-gate check: an `issue_comment` run is tied to the default branch, not the PR head, so its pass/fail can't attach to the PR's commit. Push a new commit to refresh the @@ -95,13 +95,13 @@ merge. jobs: review: runs-on: ubuntu-latest - # PR events, or a `/orcarouter-review` command from a maintainer — + # PR events, or a `/orca-code-review` command from a maintainer — # otherwise any commenter could spend your quota. if: | github.event_name == 'pull_request_target' || (github.event_name == 'issue_comment' && github.event.issue.pull_request && - startsWith(github.event.comment.body, '/orcarouter-review') && + startsWith(github.event.comment.body, '/orca-code-review') && contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) steps: - uses: Continuum-AI-Corp/orca-code-review@v1 @@ -131,7 +131,7 @@ All optional — pass as `with:` inputs on the action: | `max-diff-files` | `300` | Skip the review (same notice + `on-oversized-diff` outcome) when the diff touches more than this many files | | `on-oversized-diff` | `fail` | What an oversized-diff skip does to the check: `fail` (default) fails it, so a diff padded past the limits can never bypass a required merge gate; `pass` makes skips advisory (notice + green check) | | `settings` | `true` | Fetch per-repo settings from the OrcaRouter dashboard on every run; set `"false"` to skip the fetch and make the workflow file authoritative (inputs/defaults apply as-is, no dashboard override) | -| `auto-review-authors` | `""` (everyone) | Comma-separated author-association allowlist for **automatic** reviews. Empty reviews every PR. On a **public** repo, set e.g. `OWNER,MEMBER,COLLABORATOR,CONTRIBUTOR` so anonymous fork PRs can't drain your wallet with paid cascades (they can still be reviewed on demand via `/orcarouter-review`). See [Public repos & spend](SECURITY.md#public-repos--spend). | +| `auto-review-authors` | `""` (everyone) | Comma-separated author-association allowlist for **automatic** reviews. Empty reviews every PR. On a **public** repo, set e.g. `OWNER,MEMBER,COLLABORATOR,CONTRIBUTOR` so anonymous fork PRs can't drain your wallet with paid cascades (they can still be reviewed on demand via `/orca-code-review`). See [Public repos & spend](SECURITY.md#public-repos--spend). | | `report` | `true` | Send a per-run summary (severity counts only — never code) to the OrcaRouter control plane; set `"false"` to disable — see [Run reporting](#run-reporting) | | `github-token` | `${{ github.token }}` | Token used to fetch the PR head, post review comments, and manage the tier label; override only if the default `GITHUB_TOKEN` lacks the needed scopes | | `engine-version` | `1.3.13` | Pinned `@alibaba-group/open-code-review` version (the review engine); bump deliberately after testing — later steps parse its JSON output shape | @@ -149,8 +149,8 @@ OrcaRouter dashboard without touching the workflow: | Setting | Values (default first) | Effect in the Action | |---|---|---| -| `auto_review` | `true` / `false` | `false`: automatic (`pull_request_target`) runs skip the engine, leave one small "automatic review is off" comment, and **pass** the check. `/orcarouter-review` comment commands still run. | -| `trigger` | `every_push` / `ready_for_review` / `on_demand` | `every_push`: review every push. `ready_for_review`: skip automatic runs **while the PR is a draft** (add `ready_for_review` to your workflow's `pull_request_target.types` so the review fires when the PR leaves draft). `on_demand`: skip all automatic runs — only `/orcarouter-review` comments review. All skips pass the check. | +| `auto_review` | `true` / `false` | `false`: automatic (`pull_request_target`) runs skip the engine, leave one small "automatic review is off" comment, and **pass** the check. `/orca-code-review` comment commands still run. | +| `trigger` | `every_push` / `ready_for_review` / `on_demand` | `every_push`: review every push. `ready_for_review`: skip automatic runs **while the PR is a draft** (add `ready_for_review` to your workflow's `pull_request_target.types` so the review fires when the PR leaves draft). `on_demand`: skip all automatic runs — only `/orca-code-review` comments review. All skips pass the check. | | `exhaustive` | `false` / `true` | Re-run the engine up to **2 extra times on the strong (enforced) tier**, deduplicating findings across passes (one review pass is not exhaustive; a re-run surfaces missed findings). The cheap screening pass never gets extras — its result is either superseded by the same-run strong review or held on fix-first findings anyway. The loop stops early once a pass adds nothing new **or a fix-first (P0/P1) finding is already in hand** (the gate blocks on it regardless of extra depth). **Cost cap: at most 3 engine passes total on the enforced tier.** The summary comment notes `exhaustive: N passes`. | | `quiet` | `false` / `true` | Advisory **P2 comments are not posted inline** — they are muted at the posting step only. The summary keeps the **true** P0/P1/P2 counts with a `quiet mode: P2 shown in summary only` note, and the gate/run report always see the unfiltered counts. | | `fix_first` | `"P0,P1"` | Same meaning as the `fix-first` input — see precedence below. | @@ -221,7 +221,7 @@ repo setting: 4. Save. Now a failing review disables the merge button until it goes green. Re-run the -gate by pushing a new commit (the `/orcarouter-review` comment posts a fresh +gate by pushing a new commit (the `/orca-code-review` comment posts a fresh read but can't flip the required check — see the per-commit loop note above). **Merge-gate note — oversized diffs.** An oversized-diff skip (`max-diff-kb` / diff --git a/SECURITY.md b/SECURITY.md index f88be98..89c3cd3 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -42,7 +42,7 @@ for public repos: - **Restrict auto-review authors** with the `auto-review-authors` input (e.g. `OWNER,MEMBER,COLLABORATOR,CONTRIBUTOR`) so anonymous/first-time PRs are not auto-reviewed. They can still be reviewed on demand by a maintainer's - `/orcarouter-review` comment, which is separately gated to + `/orca-code-review` comment, which is separately gated to OWNER/MEMBER/COLLABORATOR. ### `pull_request_target` and secrets @@ -54,7 +54,7 @@ to read. Consumers MUST NOT add build, test, or install steps that execute PR-controlled code to this workflow. If you need to run PR code, do it in a separate `pull_request`-triggered workflow with no secrets. -The comment trigger (`/orcarouter-review`) is gated to +The comment trigger (`/orca-code-review`) is gated to OWNER/MEMBER/COLLABORATOR in the shipped workflow so arbitrary commenters cannot spend your quota. diff --git a/action.yml b/action.yml index 5c11594..1b64b68 100644 --- a/action.yml +++ b/action.yml @@ -84,7 +84,7 @@ inputs: paid cascades by opening PRs — set e.g. "OWNER,MEMBER,COLLABORATOR,CONTRIBUTOR" to auto-review only known contributors (others can still be reviewed on demand via - /orcarouter-review). Also set a wallet budget + alert on the key. + /orca-code-review). Also set a wallet budget + alert on the key. Case-insensitive; values: OWNER, MEMBER, COLLABORATOR, CONTRIBUTOR, FIRST_TIME_CONTRIBUTOR, FIRST_TIMER, MANNEQUIN, NONE. required: false @@ -205,6 +205,37 @@ runs: core.setOutput('tier', promoted ? '1' : '0'); core.info(`PR #${num} review tier: ${promoted ? '1 (strong)' : '0 (cheap)'}`); + # Lightweight 👀 acknowledgement so the requester sees the bot noticed the + # trigger. Static one-shot (no update or removal). Fires early — before any + # skip gate — so even a skipped run still visibly acknowledges receipt. + # Reaction outages are non-fatal: the review must never be blocked by a + # UI-affordance failure. + - name: React 👀 to acknowledge review request + shell: bash + env: + GH_TOKEN: ${{ inputs.github-token }} + REPO: ${{ github.repository }} + PR_NUMBER: ${{ steps.pr.outputs.number }} + EVENT_NAME: ${{ github.event_name }} + COMMENT_ID: ${{ github.event.comment.id }} + run: | + react() { + if gh api -X POST "$1" -f content=eyes >/dev/null 2>&1; then + echo "reacted 👀 -> $1" + else + echo "warning: failed to react at $1 (non-fatal)" + fi + } + # Always react on the PR body (issue reactions endpoint — PRs are issues). + if [ -n "${PR_NUMBER:-}" ]; then + react "repos/$REPO/issues/$PR_NUMBER/reactions" + fi + # For a maintainer's /orca-code-review command, also react on that + # trigger comment so the operator sees direct feedback on THEIR comment. + if [ "$EVENT_NAME" = "issue_comment" ] && [ -n "${COMMENT_ID:-}" ]; then + react "repos/$REPO/issues/comments/$COMMENT_ID/reactions" + fi + # setup-node runs BEFORE checkout (it never reads the workspace) so the # settings fetch below has node available even on a bare self-hosted runner. - uses: actions/setup-node@v4 @@ -260,7 +291,7 @@ runs: # Auto-event gate -> sets DECISION/REASON. Only AUTO runs are gated — # any pull_request* event, so a hand-written plain `pull_request` # workflow honors gating exactly like the documented - # `pull_request_target` one. An explicit `/orcarouter-review` comment + # `pull_request_target` one. An explicit `/orca-code-review` comment # command (issue_comment) always proceeds — on-demand mode exists # precisely for those, and a human asking for a review of a # draft/disabled repo is deliberate. Shared by both settings paths so the @@ -390,7 +421,7 @@ runs: `${MARKER}\n## 🐳 ${brand}\n\n` + `⏸️ **Automatic review is off for this PR** (${process.env.REASON}).\n\n` + `The check **passes** — this never blocks your merge. A maintainer can still ` + - `run a review on demand by commenting \`/orcarouter-review\`, or change the ` + + `run a review on demand by commenting \`/orca-code-review\`, or change the ` + `repo's review settings in the OrcaRouter dashboard.` + footer; diff --git a/scripts/settings.test.mjs b/scripts/settings.test.mjs index c2b7f1f..ceb8a7c 100644 --- a/scripts/settings.test.mjs +++ b/scripts/settings.test.mjs @@ -571,7 +571,7 @@ describe("action.yml: gate_decision — shared auto-event gate (both settings pa }); test("a comment command (issue_comment) still proceeds even for a disallowed author", () => { - // On-demand /orcarouter-review is maintainer-gated in the workflow `if:`; + // On-demand /orca-code-review is maintainer-gated in the workflow `if:`; // the settings gate must NOT additionally skip it. assert.equal(disabled({ event: "issue_comment", list: "CONTRIBUTOR", assoc: "NONE" }).decision, "review"); }); diff --git a/workflows/orcarouter-code-review.yml b/workflows/orcarouter-code-review.yml index 54e9f50..40c3302 100644 --- a/workflows/orcarouter-code-review.yml +++ b/workflows/orcarouter-code-review.yml @@ -34,7 +34,7 @@ permissions: jobs: review: runs-on: ubuntu-latest - # Run on PR events, or when a trusted user comments `/orcarouter-review` on a + # Run on PR events, or when a trusted user comments `/orca-code-review` on a # PR. The command runs the privileged `pull_request_target` workflow with the # OrcaRouter secret, so only maintainers (owner/member/collaborator) may # trigger it — otherwise any participant could burn paid quota and spam @@ -43,7 +43,7 @@ jobs: github.event_name == 'pull_request_target' || (github.event_name == 'issue_comment' && github.event.issue.pull_request && - startsWith(github.event.comment.body, '/orcarouter-review') && + startsWith(github.event.comment.body, '/orca-code-review') && contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) steps: - uses: Continuum-AI-Corp/orca-code-review@v1