chore: import upstream snapshot with attribution
CI / E2E Cloudflare (4/8) (push) Failing after 0s
CI / E2E Cloudflare (8/8) (push) Failing after 1s
CI / Lint (push) Failing after 1s
Auto Extract / Extract (push) Failing after 4s
CI / Version Check (push) Failing after 9s
CI / Integration Tests (push) Failing after 1s
CI / E2E tests (1/8) (push) Failing after 1s
CI / E2E tests (2/8) (push) Failing after 2s
CI / E2E tests (3/8) (push) Failing after 2s
CI / Browser Tests (push) Failing after 1s
CI / E2E tests (5/8) (push) Failing after 1s
CI / E2E Cloudflare (2/8) (push) Failing after 2s
CI / Typecheck (push) Failing after 1s
CI / Changeset Validation (push) Failing after 2s
CI / E2E Cloudflare (5/8) (push) Failing after 1s
CI / E2E Cloudflare (6/8) (push) Failing after 1s
CI / E2E Cloudflare (7/8) (push) Failing after 1s
CodeQL / Analyze (javascript-typescript) (push) Failing after 1s
Format / Format (push) Failing after 0s
CodeQL / Analyze (actions) (push) Failing after 4s
CI / E2E tests (4/8) (push) Failing after 1s
CI / E2E tests (6/8) (push) Failing after 1s
CI / E2E tests (7/8) (push) Failing after 2s
CI / E2E tests (8/8) (push) Failing after 1s
CI / E2E Cloudflare (1/8) (push) Failing after 1s
CI / E2E Cloudflare (3/8) (push) Failing after 2s
Preview Releases / Publish Preview (push) Failing after 0s
zizmor / Run zizmor (push) Failing after 1s
Release / Release (push) Failing after 2s
CI / Smoke Tests (push) Failing after 5m36s
CI / Tests (push) Failing after 6m36s
Release / Sync Templates (push) Has been skipped
CI / E2E Tests (push) Has been cancelled
CI / E2E Cloudflare (4/8) (push) Failing after 0s
CI / E2E Cloudflare (8/8) (push) Failing after 1s
CI / Lint (push) Failing after 1s
Auto Extract / Extract (push) Failing after 4s
CI / Version Check (push) Failing after 9s
CI / Integration Tests (push) Failing after 1s
CI / E2E tests (1/8) (push) Failing after 1s
CI / E2E tests (2/8) (push) Failing after 2s
CI / E2E tests (3/8) (push) Failing after 2s
CI / Browser Tests (push) Failing after 1s
CI / E2E tests (5/8) (push) Failing after 1s
CI / E2E Cloudflare (2/8) (push) Failing after 2s
CI / Typecheck (push) Failing after 1s
CI / Changeset Validation (push) Failing after 2s
CI / E2E Cloudflare (5/8) (push) Failing after 1s
CI / E2E Cloudflare (6/8) (push) Failing after 1s
CI / E2E Cloudflare (7/8) (push) Failing after 1s
CodeQL / Analyze (javascript-typescript) (push) Failing after 1s
Format / Format (push) Failing after 0s
CodeQL / Analyze (actions) (push) Failing after 4s
CI / E2E tests (4/8) (push) Failing after 1s
CI / E2E tests (6/8) (push) Failing after 1s
CI / E2E tests (7/8) (push) Failing after 2s
CI / E2E tests (8/8) (push) Failing after 1s
CI / E2E Cloudflare (1/8) (push) Failing after 1s
CI / E2E Cloudflare (3/8) (push) Failing after 2s
Preview Releases / Publish Preview (push) Failing after 0s
zizmor / Run zizmor (push) Failing after 1s
Release / Release (push) Failing after 2s
CI / Smoke Tests (push) Failing after 5m36s
CI / Tests (push) Failing after 6m36s
Release / Sync Templates (push) Has been skipped
CI / E2E Tests (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
name: Review PR
|
||||
|
||||
# /review triggers this workflow. The first word after the trigger picks a
|
||||
# model alias from .github/bonk-models.json. Currently registered aliases
|
||||
# (see that file for the source of truth):
|
||||
#
|
||||
# /review -> default model (currently opus)
|
||||
# /review opus -> Claude Opus 4.7 (default)
|
||||
# /review kimi -> Kimi K2.7 Code (cheap pass for tiny PRs)
|
||||
#
|
||||
# Add new aliases by editing .github/bonk-models.json.
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
pull_request_review_comment:
|
||||
types: [created]
|
||||
|
||||
# Concurrency is at job level (below) rather than workflow level so it's only
|
||||
# evaluated when the `if:` filter passes.
|
||||
|
||||
jobs:
|
||||
review:
|
||||
# mentions in this check must match the `mentions` input below.
|
||||
# For issue_comment events, require the comment to be on a PR (not an issue).
|
||||
if: >-
|
||||
github.event.sender.type != 'Bot'
|
||||
&& contains(github.event.comment.body, '/review')
|
||||
&& contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)
|
||||
&& (github.event_name != 'issue_comment' || github.event.issue.pull_request != null)
|
||||
# Per-workflow group key so /review and /bonk have independent queues
|
||||
# per target.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.issue.number || github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: false
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Get PR number
|
||||
id: pr-number
|
||||
env:
|
||||
# issue_comment on a PR exposes the number via github.event.issue.number;
|
||||
# pull_request_review_comment exposes it via github.event.pull_request.number.
|
||||
PR_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }}
|
||||
run: |
|
||||
echo "number=${PR_NUMBER}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Verify PR exists
|
||||
id: verify-pr
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
PR_NUMBER: ${{ steps.pr-number.outputs.number }}
|
||||
run: |
|
||||
if gh api "/repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}" > /dev/null 2>&1; then
|
||||
echo "exists=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "exists=false" >> "$GITHUB_OUTPUT"
|
||||
echo "::warning::PR #${PR_NUMBER} not found, skipping review"
|
||||
fi
|
||||
|
||||
- name: Checkout repository
|
||||
if: steps.verify-pr.outputs.exists == 'true'
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
with:
|
||||
fetch-depth: 1
|
||||
persist-credentials: false
|
||||
|
||||
- name: Resolve model from comment
|
||||
if: steps.verify-pr.outputs.exists == 'true'
|
||||
id: model
|
||||
env:
|
||||
BODY: ${{ github.event.comment.body }}
|
||||
run: node .github/scripts/resolve-bonk-model.mjs
|
||||
|
||||
- name: Setup pnpm
|
||||
if: steps.verify-pr.outputs.exists == 'true'
|
||||
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
|
||||
- name: Setup Node.js
|
||||
if: steps.verify-pr.outputs.exists == 'true'
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
with:
|
||||
node-version-file: "package.json"
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.verify-pr.outputs.exists == 'true'
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Get PR details
|
||||
if: steps.verify-pr.outputs.exists == 'true'
|
||||
id: pr-details
|
||||
run: |
|
||||
gh api "/repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}" > /tmp/pr_data.json
|
||||
# Use heredoc form for every field — PR titles and bodies can contain
|
||||
# newlines that would otherwise corrupt $GITHUB_OUTPUT and let a PR
|
||||
# author smuggle arbitrary step outputs via their title/body.
|
||||
{
|
||||
echo 'title<<PR_TITLE_EOF'
|
||||
jq -r .title /tmp/pr_data.json
|
||||
echo PR_TITLE_EOF
|
||||
echo "sha=$(jq -r .head.sha /tmp/pr_data.json)"
|
||||
echo 'body<<PR_BODY_EOF'
|
||||
jq -r .body /tmp/pr_data.json
|
||||
echo PR_BODY_EOF
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
PR_NUMBER: ${{ steps.pr-number.outputs.number }}
|
||||
|
||||
- name: Run Review (${{ steps.model.outputs.alias }})
|
||||
if: steps.verify-pr.outputs.exists == 'true'
|
||||
uses: ask-bonk/ask-bonk/github@bfd92f4d0abb62d98558b35432534f7b9992f3eb # main as of 2026-04-24
|
||||
env:
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_AI_GATEWAY_ACCOUNT_ID }}
|
||||
CLOUDFLARE_GATEWAY_ID: ${{ secrets.CF_AI_GATEWAY_NAME }}
|
||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CF_AI_GATEWAY_TOKEN }}
|
||||
OPENCODE_CONFIG_CONTENT: ${{ steps.model.outputs.opencode_config }}
|
||||
with:
|
||||
model: ${{ steps.model.outputs.model }}
|
||||
mentions: "/review"
|
||||
opencode_version: "1.4.11"
|
||||
permissions: write
|
||||
# NO_PUSH scopes the installation token to contents:read so the
|
||||
# reviewer cannot push, even if it tries to commit. Write tools
|
||||
# remain enabled in the agent definition so it can scaffold fixes
|
||||
# locally to verify reasoning.
|
||||
token_permissions: NO_PUSH
|
||||
# Custom agent defined in .opencode/agents/auto-reviewer.md.
|
||||
# Holds the review philosophy, investigation protocol, and posting
|
||||
# protocol so workflows stay small.
|
||||
agent: auto-reviewer
|
||||
prompt: |
|
||||
Review pull request #${{ steps.pr-number.outputs.number }} ("${{ steps.pr-details.outputs.title }}").
|
||||
|
||||
Follow your agent instructions for investigation, severity calibration, and posting. Post a single review with line-anchored comments via the gh CLI; the summary will be posted as a separate workflow comment.
|
||||
|
||||
<pr_number>${{ steps.pr-number.outputs.number }}</pr_number>
|
||||
<pr_description>
|
||||
${{ steps.pr-details.outputs.body }}
|
||||
</pr_description>
|
||||
|
||||
If the PR looks good, respond with only "LGTM!" and skip posting a review.
|
||||
Reference in New Issue
Block a user