-
Notifications
You must be signed in to change notification settings - Fork 1.2k
160 lines (145 loc) · 6.62 KB
/
Copy pathbonk.yml
File metadata and controls
160 lines (145 loc) · 6.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
name: Bonk
# /bonk and @ask-bonk both trigger 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):
#
# /bonk <task> -> default model (currently opus)
# /bonk opus <task> -> Claude Opus 4.7 (default)
# /bonk kimi <task> -> Kimi K2.7 Code (cheap pass for tiny tasks)
# @ask-bonk opus how would you do X? -> Claude Opus 4.7
#
# Add new aliases by editing .github/bonk-models.json -- the resolver script
# only registers the selected alias in OPENCODE_CONFIG_CONTENT at runtime.
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
pull_request_review:
types: [submitted]
# Concurrency is at job level (below) rather than workflow level so it's only
# evaluated when the `if:` filter passes. Otherwise every issue_comment event
# in the repo would enter the group and could evict in-flight runs from
# unrelated, non-matching comments.
jobs:
bonk:
if: >-
github.event.sender.type != 'Bot'
&& contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association || github.event.review.author_association)
&& (
((github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment')
&& (contains(github.event.comment.body, '/bonk') || contains(github.event.comment.body, '@ask-bonk')))
|| (github.event_name == 'pull_request_review'
&& (contains(github.event.review.body, '/bonk') || contains(github.event.review.body, '@ask-bonk')))
)
# Per-workflow group key so /bonk and /review have independent queues per
# target. Spamming /bonk on the same issue/PR serializes; different actions
# on the same target run in parallel.
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: 45
permissions:
id-token: write
contents: write
issues: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 1
persist-credentials: false
- name: Resolve model from comment
id: model
env:
BODY: ${{ github.event.comment.body || github.event.review.body }}
run: node .github/scripts/resolve-bonk-model.mjs
- name: Setup pnpm
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: "package.json"
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Resolve trigger context
id: trigger
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
EVENT_NAME: ${{ github.event_name }}
# issue_comment fires on both issues and PRs. github.event.issue.pull_request
# is non-null when the issue is actually a PR.
IS_PR_COMMENT: ${{ github.event.issue.pull_request != null }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
set -euo pipefail
# Decide trigger_kind ("issue" or "pr") and target_number.
if [[ "$EVENT_NAME" == "issue_comment" ]]; then
if [[ "$IS_PR_COMMENT" == "true" ]]; then
KIND=pr
NUM="$ISSUE_NUMBER" # issue.number is the PR number for PR comments
else
KIND=issue
NUM="$ISSUE_NUMBER"
fi
else
KIND=pr
NUM="$PR_NUMBER"
fi
# Fetch title/body (heredoc-quoted to prevent newlines in titles or
# bodies from corrupting $GITHUB_OUTPUT or smuggling step outputs).
if [[ "$KIND" == "pr" ]]; then
gh api "/repos/${GITHUB_REPOSITORY}/pulls/${NUM}" > /tmp/target.json
SHA="$(jq -r .head.sha /tmp/target.json)"
BASE="$(jq -r .base.sha /tmp/target.json)"
else
gh api "/repos/${GITHUB_REPOSITORY}/issues/${NUM}" > /tmp/target.json
SHA=""
BASE=""
fi
{
echo "kind=${KIND}"
echo "number=${NUM}"
echo "head_sha=${SHA}"
echo "base_sha=${BASE}"
echo 'title<<TARGET_TITLE_EOF'
jq -r '.title // ""' /tmp/target.json
echo TARGET_TITLE_EOF
echo 'body<<TARGET_BODY_EOF'
jq -r '.body // ""' /tmp/target.json
echo TARGET_BODY_EOF
} >> "$GITHUB_OUTPUT"
- name: Run Bonk (${{ steps.model.outputs.alias }})
uses: ask-bonk/ask-bonk/github@22f7cea9896b0ae77d92b8dcbcf81798a9165633 # 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:
oidc_base_url: https://ask-bonk.cloudflare-exponent.workers.dev/auth
model: ${{ steps.model.outputs.model }}
mentions: "/bonk,@ask-bonk"
opencode_version: "1.4.11"
permissions: write
# Custom agent defined in .opencode/agents/auto-implementer.md.
# Holds the investigation/reproduction protocol, scope discipline,
# and PR body conventions so this workflow stays small.
agent: auto-implementer
prompt: |
A maintainer has invoked /bonk on the emdash-cms/emdash repository. Follow your agent instructions for mode classification, investigation, reproduction, and posting.
<trigger_kind>${{ steps.trigger.outputs.kind }}</trigger_kind>
<target_number>${{ steps.trigger.outputs.number }}</target_number>
<target_title>${{ steps.trigger.outputs.title }}</target_title>
<target_body>
${{ steps.trigger.outputs.body }}
</target_body>
<head_sha>${{ steps.trigger.outputs.head_sha }}</head_sha>
<base_sha>${{ steps.trigger.outputs.base_sha }}</base_sha>
The maintainer's request:
${{ github.event.comment.body || github.event.review.body }}