Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 18 additions & 32 deletions .github/workflows/claude-doc-sync.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,6 @@
name: Sync docs on merged PRs

# Runs after a PR merges into master and asks Claude to check whether any
# documentation (root README, package READMEs, /docs) needs updating to
# reflect the change, opening a follow-up PR only if it finds something to
# update.
#
# Gated to keep run volume (and cost) down: only master-targeted merges
# (branches: [master] below) that also carry an approving review
# (reviewDecision == APPROVED, checked in the gate step) trigger a Claude run.
# master requires 1 approval by branch protection, but enforce_admins is off,
# so an admin can still merge without one - this gate closes that gap rather
# than assuming protection alone guarantees a review happened.
#
# Uses pull_request_target (not pull_request) so the workflow runs with this
# repo's own permissions even when the merged PR came from a fork - this repo
# takes plenty of external contributions and a plain `pull_request` trigger
# gets a read-only token for fork-authored PRs, which would make `gh pr
# create` fail below. This is safe here because we only ever check out
# base.ref (the already-reviewed, already-merged default branch), never the
# PR's own head ref - we never build or execute the contributor's code.
#
# Installs the Claude Code CLI directly via npm rather than using
# `uses: anthropics/claude-code-action` - this repo's Actions policy is
# allowed_actions: selected with an empty patterns_allowed list (only
# GitHub-owned actions are permitted), so a third-party `uses:` reference
# fails at startup before any job runs. Installing and invoking the CLI
# ourselves only needs actions/checkout and actions/setup-node, both
# GitHub-owned and already allowed, so it sidesteps that policy without
# requiring an org/repo policy change.
# pull_request_target (not pull_request) for write access on fork-authored PRs too; safe since we only check out the already-merged base branch, never the PR's own head.
on:
pull_request_target:
types: [closed]
Expand All @@ -42,6 +15,7 @@ jobs:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest-large
steps:
# Gates on approval since master's review requirement can be bypassed by admins.
- name: Require an approved review
id: gate
env:
Expand Down Expand Up @@ -69,6 +43,7 @@ jobs:
with:
node-version: 22

# Installed directly rather than via a third-party action, since this repo's Actions policy only allows GitHub-owned actions.
- name: Install Claude Code CLI
if: steps.gate.outputs.approved == 'true'
run: npm install -g @anthropic-ai/claude-code
Expand All @@ -89,11 +64,13 @@ jobs:
cat > "$RUNNER_TEMP/claude-prompt.txt" <<EOF
Pull request #$PR_NUMBER ("$PR_TITLE") was just merged into $BASE_REF.

Your job is only to keep EXISTING documentation accurate - never create new documentation files, new README sections, or any other docs that didn't already exist before this PR.

1. Run \`gh pr diff $PR_NUMBER\` to see exactly what changed.
2. Search this repository's documentation (root README.md, each package's README.md, and any /docs content) for anything describing the behavior, API, configuration, or usage that this PR changed.
3. If you find documentation that's now inaccurate, incomplete, or missing details because of this change, update it to match. Do not treat CHANGELOG.md files as documentation - they're generated by release tooling, leave them alone.
4. If no documentation needs updating, stop here: do not create a branch, commit, or pull request.
5. If you did update documentation, create a new branch off $BASE_REF named \`docs/sync-pr-$PR_NUMBER\`, commit the changes, push it, and open a pull request against $BASE_REF with \`gh pr create\`. Title it "docs: sync with #$PR_NUMBER" and explain in the body which doc(s) you updated, why, and link back to #$PR_NUMBER.
2. Search this repository's EXISTING documentation (root README.md, each package's README.md, and any existing /docs content) for anything describing the behavior, API, configuration, or usage that this PR changed. Do not treat CHANGELOG.md files as documentation - they're generated by release tooling, leave them alone.
3. If you find existing documentation that's now inaccurate, incomplete, or missing details because of this change, update it in place to match. Only edit files that already exist - do not add new documentation files or new sections covering something that had no prior documentation at all.
4. If no existing documentation is relevant to this change, do not touch the repo: no branch, no commit, no pull request. Instead, write one or two sentences explaining that decision to doc-sync-decision.md in the repository root (e.g. "No existing docs reference the changed behavior in packages/core/src/foo.ts; nothing to update.") and stop.
5. If you did update existing documentation, create a new branch off $BASE_REF named \`docs/sync-pr-$PR_NUMBER\`, commit the changes, push it, and open a pull request against $BASE_REF with \`gh pr create\`. Title it "docs: sync with #$PR_NUMBER" and explain in the body which doc(s) you updated, why, and link back to #$PR_NUMBER.
EOF

- name: Sync docs with Claude
Expand All @@ -104,3 +81,12 @@ jobs:
run: |
claude -p "$(cat "$RUNNER_TEMP/claude-prompt.txt")" \
--allowedTools "Edit,MultiEdit,Write,Read,Glob,Grep,Bash(git:*),Bash(gh:*)"

# Only exists if Claude decided nothing needed updating; ignored otherwise.
- name: Upload no-op decision artifact
if: always() && steps.gate.outputs.approved == 'true'
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: doc-sync-decision-${{ github.event.pull_request.number }}
path: doc-sync-decision.md
if-no-files-found: ignore
3 changes: 3 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Agent instructions

- In-code comments must be a single line, placed next to the specific line it explains. Don't stack several one-line comments back to back - that's a multi-line comment in practice, not several 1-line ones.
Loading