Skip to content

FTS5 integrity-check corrupts D1 shadow tables — publish fails with SQLITE_CORRUPT_VTAB on all collections #5183

FTS5 integrity-check corrupts D1 shadow tables — publish fails with SQLITE_CORRUPT_VTAB on all collections

FTS5 integrity-check corrupts D1 shadow tables — publish fails with SQLITE_CORRUPT_VTAB on all collections #5183

Workflow file for this run

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.6 (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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
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@a8c6cac8726d0d5ab887bc159aae77e2bfb2cf18 # 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: "/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 }}