ci: add automated PR review bot workflow - #1505
Conversation
Adds parameterized workflow for @hyperswitch-web-review-bot - Syncs skill from juspay/hyperswitch-specs - Supports review, feedback, answer, and update intents
Restrict the review-bot workflow to comments from OWNER/MEMBER/COLLABORATOR so external users can't drive-by trigger a self-hosted runner by commenting the bot mention on a fork PR. Closes the public drive-by attack path until we migrate the bot to a webhook-based service. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Brings this workflow to parity with the hardening already being landed on juspay/hyperswitch-control-center#4741 and present in juspay/hyperswitch-prism#1145. - concurrency group keyed on PR number (cancel-in-progress: false) — two mentions on the same PR no longer race on the shared $SOURCE_REPO_LOCAL checkout. - job + step-level timeout-minutes: 30 — kills runaway opencode sessions instead of pinning the self-hosted runner indefinitely. - defaults.run.shell: bash — explicit shell instead of the default. - set -euo pipefail on every script step — propagates failures instead of masking them. - skill source directory existence check before cp — fails loud if hyperswitch-specs is missing the skill rather than producing an empty install. - empty-branch guard around `git checkout` — avoids `git checkout ""` when `gh pr view` returns nothing. - unique session title `review-$TEAM-$PR-$GITHUB_RUN_ID` + stale session retry — the prior `head -1` on session list could return the wrong session if titles collided across runs; each run now creates a uniquely titled session and falls back to a fresh one if resume fails. - new Acknowledge trigger with eye reaction step — posts an 👀 reaction on the triggering comment as soon as the job starts executing, giving the user who mentioned @hyperswitch-web-review-bot immediate feedback that the bot received the trigger rather than waiting 1-3 minutes for the review itself. Non-fatal on failure. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| exit 1 | ||
| fi | ||
| git checkout "$BRANCH" | ||
| git pull origin "$BRANCH" |
There was a problem hiding this comment.
How will this work for PRs using fork?
There was a problem hiding this comment.
The workflow yaml always runs from juspay/hyperswitch's main and never from the fork.
| concurrency: | ||
| group: hyperswitch-web-review-${{ github.event.issue.number || github.event.pull_request.number }} | ||
| cancel-in-progress: false |
There was a problem hiding this comment.
how does this handle two different PR review at the same time?
There was a problem hiding this comment.
it keeps the other in queue. runner picks one job at a time.
There was a problem hiding this comment.
concurrency group is scoped per PR number, so different PRs can still run simultaneously, right?
There was a problem hiding this comment.
No, because we currently have only one self-hosted runner, so effectively workflows across PRs also end up running one at a time.
Right now the concurrency config only serializes runs within the same PR.
| SKILL_NAME : $SKILL_NAME | ||
| SOURCE_REPO : $SOURCE_REPO | ||
| SOURCE_REPO_LOCAL : $SOURCE_REPO_LOCAL | ||
|
|
||
| TRIGGER CONTEXT: | ||
| Event : $EVENT_NAME | ||
| PR : #$PR_NUMBER | ||
| Comment : $COMMENT_BODY | ||
| In reply to : $IN_REPLY_TO" | ||
|
|
||
| if [ -f "$SESSION_FILE" ]; then | ||
| SAVED_ID=$(cat "$SESSION_FILE") | ||
| echo "Resuming session $SAVED_ID for review #$PR_NUMBER" | ||
| if opencode run \ | ||
| --session "$SAVED_ID" \ | ||
| --dir "$SOURCE_REPO_LOCAL" \ | ||
| "$PROMPT"; then | ||
| echo "Resumed session $SAVED_ID successfully" | ||
| exit 0 | ||
| else | ||
| echo "Session $SAVED_ID failed, creating new session" | ||
| rm -f "$SESSION_FILE" | ||
| fi | ||
| fi | ||
|
|
||
| UNIQUE_TITLE="review-$TEAM_NAME-$PR_NUMBER-$GITHUB_RUN_ID" | ||
| echo "Creating new session for review #$PR_NUMBER" | ||
| opencode run \ |
There was a problem hiding this comment.
Do we need to expose file paths, agent commands, and prompts directly in the workflow? Instead, why not encapsulate the business logic in a .sh script on the host machine and use GitHub Actions only to trigger that script? This would keep the workflow cleaner, reduce exposure of internal implementation details, and make the logic easier to maintain.
There was a problem hiding this comment.
The workflow is doing exactly one thing, in a fixed way, and putting it all in one file makes that thing legible.
These agent commands are deterministic code. Nothing in the current design is exploitable because paths and prompts are public.
Type of Change
Description
Adds a GitHub Actions workflow that wires this repo up to the shared OpenCode review bot infrastructure.
When someone comments `@hyperswitch-web-review-bot` on a PR, a self-hosted runner:
The workflow is parameterized via a top-level `env:` block (team name, skill name, repo, runner-local paths), so reusing it for another team only requires changing those values. Same template is already live on `juspay/hyperswitch-control-center` (#4708).
How did you test it?
Checklist