Add grumpy-reviewer agentic PR-review workflow - #16616
Conversation
Add a gh-aw agentic workflow that automatically runs a grumpy senior code reviewer on every pull request (opened/reopened/synchronize) plus manual dispatch, leaving grumpy-but-constructive inline review comments on the PR's changed lines. - .github/agents/grumpy-reviewer.agent.md: the reviewer persona (imported verbatim from github/gh-aw). - .github/workflows/grumpy-reviewer.md: pull_request_target + workflow_dispatch, guarded to ohcnetwork/care_fe, permissions read-all, imports the agent, github default toolset, and create-pull-request-review-comment / submit-pull-request-review safe-outputs. Uses roles: all so community/fork PRs are reviewed, with checkout disabled to avoid pwn-request exposure. - .github/workflows/grumpy-reviewer.lock.yml: compiled output (gh aw compile). - .github/aw/actions-lock.json: additive pin for the setup action the lock uses. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Entire-Checkpoint: 346b2c0e0bcc
|
WalkthroughAdds a grumpy reviewer agent, its pull-request workflow declaration, and a generated execution workflow. The workflow validates activation, runs sandboxed Copilot review, processes bounded outputs, tracks usage, and detects threats. ChangesGrumpy reviewer automation
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🎭 Playwright Test ResultsStatus: ⏭️ Skipped No test-related files were changed in this PR. Tests are skipped when changes don't affect:
Run: #10549 |
Deploying care-preview with
|
| Latest commit: |
282d2f8
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://8a99a559.care-preview-a7w.pages.dev |
| Branch Preview URL: | https://amjithtitus09-grumpy-reviewe.care-preview-a7w.pages.dev |
There was a problem hiding this comment.
Pull request overview
Adds a new GitHub Agentic Workflows (gh-aw) PR-review automation that runs on pull_request_target and posts inline review comments via safe-outputs, using an imported “grumpy reviewer” persona.
Changes:
- Introduces a new agentic workflow definition to review only changed lines and emit safe, structured PR review comments.
- Adds the compiled gh-aw lock workflow for the new reviewer workflow.
- Updates the gh-aw actions lockfile to pin the setup action referenced by the compiled workflow.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
.github/workflows/grumpy-reviewer.md |
New gh-aw workflow source defining triggers, scope, tools, and safe-outputs for grumpy PR reviews. |
.github/workflows/grumpy-reviewer.lock.yml |
Compiled gh-aw workflow output (generated by gh aw compile) that implements the reviewer pipeline. |
.github/aw/actions-lock.json |
Adds a pinned entry for github/gh-aw-actions/setup@v0.80.9 used by the compiled workflow. |
.github/agents/grumpy-reviewer.agent.md |
Adds the imported reviewer persona prompt (verbatim) for tone/standards. |
| description: > | ||
| Grumpy senior code reviewer that automatically reviews the changed lines of | ||
| every pull request (including community/fork PRs) and leaves grumpy-but- | ||
| constructive inline review comments. Tone and reviewing standards are | ||
| delegated to the imported grumpy-reviewer agent. |
| # No local clone is needed: the agent reads the PR diff and changed files through | ||
| # the GitHub API. Disabling checkout removes the "pwn request" attack surface that | ||
| # comes from checking out untrusted fork code under pull_request_target. | ||
| checkout: false |
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/grumpy-reviewer.lock.yml:
- Line 1517: Update the safe_outputs job condition in grumpy-reviewer.lock.yml
to gate on needs.detection.outputs.detection_success == 'true' instead of
needs.detection.result == 'success'. Preserve the existing cancellation and
agent-result checks so warning or failure verdicts block safe outputs.
- Around line 1036-1039: Update the concurrency configuration for the
grumpy-reviewer workflow by removing cancel-in-progress while retaining queue:
max, so the settings are accepted together. Keep the existing concurrency group
unchanged.
In @.github/workflows/grumpy-reviewer.md:
- Around line 46-47: Add issues: write to the conclusion job’s permissions in
the workflow configuration, preserving the existing contents and pull-requests
permissions so issue-report handlers can create issues when using GITHUB_TOKEN.
- Around line 30-33: Update the workflow compiler/output associated with
checkout: false so the generated grumpy-reviewer.lock.yml no longer performs
GitHub-script checkouts during activation or before Copilot runs. Regenerate the
lockfile and verify it contains no checkout steps, keeping the documented
no-local-clone behavior consistent with the generated workflow.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 5ad58972-f83c-40a4-bcc4-db9640fbac7a
📒 Files selected for processing (4)
.github/agents/grumpy-reviewer.agent.md.github/aw/actions-lock.json.github/workflows/grumpy-reviewer.lock.yml.github/workflows/grumpy-reviewer.md
| concurrency: | ||
| group: "gh-aw-conclusion-grumpy-reviewer" | ||
| cancel-in-progress: false | ||
| queue: max |
There was a problem hiding this comment.
🩺 Stability & Availability | 🔴 Critical
🧩 Analysis chain
🌐 Web query:
GitHub Actions concurrency queue key supported workflow syntax
💡 Result:
In GitHub Actions, the concurrency key is used to define a concurrency group that limits the number of concurrent executions for a workflow or a specific job [1][2]. Workflow Syntax You can define concurrency at the workflow level or the job level [2]. The syntax supports two main configurations: Simple Syntax If you only need to define the concurrency group name, you can use the following format: concurrency: <group_name> Detailed Syntax For more control, such as enabling cancel-in-progress or managing queueing, use the object-based syntax: concurrency: group: <group_name> cancel-in-progress: <boolean_or_expression> queue: <single | max> Key Configuration Options group: A string or expression that defines the concurrency group. It can include context variables like github, inputs, and vars [1][3]. cancel-in-progress: A boolean (default false) that determines whether to cancel currently running jobs or workflows in the same group when a new one is triggered [4][3]. It also accepts expressions to conditionally cancel runs [4]. queue: Controls how pending jobs are handled [1][4]. single (default): At most one job or workflow run can be pending in the group [1][4]. max: Allows up to 100 pending jobs or workflows in the group [1][2]. When the queue is full, any additional runs are canceled [1][4]. Important Considerations Expression Contexts: When using expressions for the concurrency group, you are limited to the github, inputs, and vars contexts [1][3]. Fallback Values: If your group name relies on event-specific properties (e.g., github.head_ref, which is only available for pull_request events), use a fallback value (e.g., ${{ github.head_ref || github.run_id }}) to avoid syntax errors when the workflow is triggered by other events [5].
Citations:
- 1: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax?use_case=
- 2: https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency
- 3: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax
- 4: https://docs.github.com/en/enterprise-cloud@latest/actions/reference/workflows-and-actions/workflow-syntax
- 5: https://stackoverflow.com/questions/75499942/github-action-with-concurrency
🌐 Web query:
"concurrency.queue" "GitHub Actions"
💡 Result:
In GitHub Actions, the concurrency.queue key is an optional configuration property used to manage how pending workflow runs or jobs behave when they are part of a concurrency group [1][2]. It was introduced to allow multiple runs to queue sequentially rather than being limited to the default behavior of having only one pending run [1][2]. Key details regarding concurrency.queue include: Allowed Values: - single: The default behavior, where only one pending run is allowed per concurrency group [1][2]. - max: Enables the queuing of multiple pending runs (up to 100) per concurrency group [1]. Constraints: - Conflict with cancel-in-progress: You cannot set queue: max while also having cancel-in-progress: true [3][2]. This combination is invalid because a concurrency group cannot simultaneously queue waiting runs and cancel ones in progress [2]. Usage: The queue property can be defined at both the workflow and job levels within the concurrency block [2]. By enabling queue: max, you can ensure that workflows or jobs execute in order against shared resources or environments, rather than having newer runs cancel existing pending ones [1].
Citations:
- 1: https://github.blog/changelog/2026-05-07-github-actions-concurrency-groups-now-allow-larger-queues/
- 2: Add concurrency queue support actions/languageservices#355
- 3: concurrency: Add support for
queuekey rhysd/actionlint#654
Remove cancel-in-progress when using queue: max.
concurrency.queue is supported, but GitHub Actions rejects queue: max when cancel-in-progress is also set. If this workflow needs queued runs, keep queue: max and remove cancel-in-progress: false; otherwise set queue: single or omit queue.
[low_effort_and_high_reward
🧰 Tools
🪛 actionlint (1.7.12)
[error] 1039-1039: unexpected key "queue" for "concurrency" section. expected one of "cancel-in-progress", "group"
(syntax-check)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/grumpy-reviewer.lock.yml around lines 1036 - 1039, Update
the concurrency configuration for the grumpy-reviewer workflow by removing
cancel-in-progress while retaining queue: max, so the settings are accepted
together. Keep the existing concurrency group unchanged.
Source: Linters/SAST tools
| - activation | ||
| - agent | ||
| - detection | ||
| if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success' |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Compare safe_outputs gating conditions across generated gh-aw workflows.
fd -g '*.lock.yml' .github/workflows --exec rg -n -B 4 -A 4 'detection.outputs.success|detection.result' {} \;Repository: ohcnetwork/care_fe
Length of output: 4950
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== lock files =="
git ls-files '.github/workflows/*.lock.yml' '.github/workflows/*.yml' | sed -n '1,120p'
echo
echo "== grumpy review detection section =="
sed -n '1368,1528p' .github/workflows/grumpy-reviewer.lock.yml | cat -n | sed 's/^/grumpy-reviewer.lock.yml:/'
echo
echo "== parsed detection outputs setting occurrences =="
rg -n "parse_results|GH_AW_DETECTION|DETECTION_|detection_success|safe_outputs|Parse threat detection results|safe-outputs|safe outputs" .github/workflows -g '*.lock.yml' -g '*.yml' | sed -n '1,220p'Repository: ohcnetwork/care_fe
Length of output: 27156
Use the detection verdict output for safe outputs.
In grumpy-reviewer.lock.yml, the detection steps can fail but keep continue-on-error: true, so the detection job can report success while steps.detection_conclusion.outputs.success is false. Gate safe_outputs on needs.detection.outputs.detection_success == 'true' like the other generated workflows, so warning/failure verdicts block safe outputs.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/grumpy-reviewer.lock.yml at line 1517, Update the
safe_outputs job condition in grumpy-reviewer.lock.yml to gate on
needs.detection.outputs.detection_success == 'true' instead of
needs.detection.result == 'success'. Preserve the existing cancellation and
agent-result checks so warning or failure verdicts block safe outputs.
Declare `copilot-requests: write` and narrow the agent job to read-only scopes (contents/pull-requests/issues: read). This makes the Copilot engine run on the built-in Actions GITHUB_TOKEN via centralized org billing, so no COPILOT_GITHUB_TOKEN personal access token secret is needed. Requires the org to have centralized Copilot billing enabled. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Entire-Checkpoint: fa13e0e45481
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (3)
.github/workflows/grumpy-reviewer.md:57
missing-tool.create-issue: trueimplies the workflow will open issues when a tool is missing, but this workflow only grantsissues: read(and relies onGITHUB_TOKENper the PR description). In that configuration, issue creation will fail unless a separate PAT secret (e.g.GH_AW_GITHUB_TOKEN) is configured, which contradicts the “no PAT required” claim.
allowed-events: [COMMENT]
missing-tool:
create-issue: true
.github/workflows/grumpy-reviewer.md:43
- The comment above
checkout: falseclaims untrusted fork code is never checked out, but the compiled workflow does fetch the PR branch (seegrumpy-reviewer.lock.ymlstep “Checkout PR branch”). This is misleading for threat modeling; please reword to reflect the actual behavior (fetching PR content/branch without executing it).
# No local clone is needed: the agent reads the PR diff and changed files through
# the GitHub API. Disabling checkout removes the "pwn request" attack surface that
# comes from checking out untrusted fork code under pull_request_target.
checkout: false
.github/agents/grumpy-reviewer.agent.md:21
- This persona says it will “point out every issue, no matter how small”, which directly conflicts with the workflow’s instructions to prioritize and avoid nitpicks (and with the 10-comment cap). That contradiction can lead to worse review signal; align the persona with the workflow’s prioritization guidance.
- **Sarcastic and grumpy** - You're not mean, but you're definitely not cheerful
- **Experienced** - You've seen it all and have strong opinions based on decades of experience
- **Thorough** - You point out every issue, no matter how small
- **Specific** - You explain exactly what's wrong and why
- **Begrudging** - Even when code is good, you acknowledge it reluctantly
- **Concise** - Say the minimum words needed to make your point
Drop `copilot-requests: write` and restore `permissions: read-all` so the Copilot engine authenticates inference with the COPILOT_GITHUB_TOKEN repo secret (a fine-grained PAT with "Copilot Requests: Read"). Reading the PR and posting review comments still run on the built-in Actions GITHUB_TOKEN via the safe-output jobs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Entire-Checkpoint: fc1cded0f41f
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (2)
.github/workflows/grumpy-reviewer.md:39
- The comment above
checkout: falseimplies fork PR code is never checked out underpull_request_target, but the compiled workflow still has a “Checkout PR branch” step ingrumpy-reviewer.lock.yml. That’s an important security detail—this wording can lead maintainers to assume the pwn-request surface is eliminated when it isn’t. Please update the comment to match the compiled behavior (or change the workflow config if you truly need zero checkouts).
# No local clone is needed: the agent reads the PR diff and changed files through
# the GitHub API. Disabling checkout removes the "pwn request" attack surface that
# comes from checking out untrusted fork code under pull_request_target.
checkout: false
.github/workflows/grumpy-reviewer.md:53
- With this running on every PR open/sync,
missing-tool.create-issue: truecan spam the repo with issues if the model requests a tool outside the allowlist (even once per PR). Consider disabling automatic issue creation here and relying on workflow logs / a single consolidated review comment instead.
missing-tool:
create-issue: true
What this does
Adds a GitHub Agentic Workflow (gh-aw) that runs a grumpy senior code reviewer on pull requests and leaves grumpy-but-constructive inline review comments on the PR's changed lines. Tone and reviewing standards are delegated to the imported
grumpy-revieweragent (taken verbatim fromgithub/gh-aw).When it runs
opened,reopened, andsynchronize(new commits pushed).workflow_dispatch.if: ${{ github.repository == 'ohcnetwork/care_fe' }}so it only runs on the upstream repo (likedaily-playwright-improver.md).Community / fork PR support
Uses
pull_request_target(matchingthank-you-note.md) so the Copilot engine credentials are available even for fork PRs — a plainpull_requesttrigger from a fork does not expose secrets/the Copilot token.roles: allis set so external contributors' PRs are actually reviewed (the default role gate would otherwise skip non-write contributors).This is safe because of gh-aw's safe-outputs model: the agent job runs read-only (
permissions: read-all) and can only emit structured review comments that separate, permission-scoped jobs apply. The base repo and the PR head are checked out (the importedgrumpy-revieweragent usesread/searchlocal-file tools, so the changed files must be on disk), but the agent never executes untrusted PR code — it only reads files and calls the GitHub MCP + Copilot inference inside gh-aw's network-firewalled sandbox. Because it's apull_request_targetworkflow that checks out PR content, the compiler emits an advisory "pwn request" warning; it's accepted here because no untrusted code is run and every write is confined to the isolated safe-output jobs. All repo/PR content is treated as untrusted input in the prompt.Authentication (PAT)
The Copilot engine authenticates inference with a
COPILOT_GITHUB_TOKENrepository Actions secret. This must be a fine-grained PAT with:Reading the PR diff and posting review comments do not use this PAT — those run on the built-in Actions
GITHUB_TOKEN; gh-aw injects the needed write scopes (pull-requests: write) into the separate safe-output jobs while the agent job stays read-only (permissions: read-all).Configuration
permissions: read-allimports: [ .github/agents/grumpy-reviewer.agent.md ]tools.github.toolsets: [default]safe-outputs:create-pull-request-review-comment(max 10, focused on changed lines)submit-pull-request-review(max 1,COMMENTevent — non-blocking consolidated summary)missing-tool: create-issue: trueengine:omitted, matching the other workflows.Files
.github/agents/grumpy-reviewer.agent.md— reviewer persona (imported verbatim)..github/workflows/grumpy-reviewer.md— the workflow source..github/workflows/grumpy-reviewer.lock.yml— compiled output (gh aw compile, v0.80.9)..github/aw/actions-lock.json— additive pin for thesetupaction the new lock references (does not touch existing pins).Validated via
gh aw compile(0 errors; 1 advisorypull_request_target+checkout "pwn request" warning, addressed above). No app build/test run — this is workflow config only.Testing
Exercised with
gh aw trialagainst a temporary private host repo (simulatinggithub.repository = ohcnetwork/care_fe, triggered with a real PR context). Verified:agentjob, the base repo is checked out first (actions/checkout,persist-credentials: false) and the PR head is fetched after, so the PR-branchgit fetchruns inside a valid git repo. This fixes an earlierfatal: not a git repositoryfailure that was caused bycheckout: false.The only step that can't be exercised without credentials is Copilot inference: gh-aw validates
COPILOT_GITHUB_TOKENup front and stops the run if it's unset (Error: None of the following secrets are set: COPILOT_GITHUB_TOKEN). A full end-to-end trial — where the agent posts grumpy review comments, captured as safe-outputs without touching the real PR — just needs that secret set on the trial/host repo.Follow-up / requirement
Set the
COPILOT_GITHUB_TOKENrepo secret (fine-grained PAT, Copilot Requests: Read, Copilot-licensed owner) onohcnetwork/care_febefore this can post reviews. If it isn't configured yet, add it as a follow-up.