mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2026-11-05 15:19:12 +01:00
Anyone could open a fork PR with the What's New title and inject a prompt via a comment into a Claude run with repository write access. - Run only for OWNER/MEMBER/COLLABORATOR comments, and verify the PR head is JetBrains/ideavim:whatsnew-tbr and the commenter has write access. - Claude can only edit whatsnew-tbr.html and CHANGES.md and has no commit/push access; the push token is not persisted in .git/config. - A separate step pushes the edits only if no other files changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
134 lines
6.4 KiB
YAML
134 lines
6.4 KiB
YAML
name: Update What's New with Claude
|
|
|
|
# Reacts to comments on the "What's New" PR opened by prepareWhatsNewClaude.yml.
|
|
# That PR always lives on the `whatsnew-tbr` branch and is titled
|
|
# "Prepare What's New for the upcoming release". When a maintainer leaves a
|
|
# comment there, Claude reads it and updates the page / changelog accordingly.
|
|
# Claude itself can't commit or push: a separate step pushes its edits back to
|
|
# the same branch, and only if they touch the What's New page or the changelog.
|
|
on:
|
|
issue_comment:
|
|
types: [created]
|
|
|
|
jobs:
|
|
update-whats-new:
|
|
runs-on: ubuntu-latest
|
|
# Only on the What's New PR, only for comments from maintainers, and never on
|
|
# comments left by bots (the preview bot and Claude itself comment here —
|
|
# reacting to those would loop). The title alone is not trusted: anyone can
|
|
# open a fork PR with the same title, so the PR branch and the commenter's
|
|
# write access are verified in the first step.
|
|
if: |
|
|
github.repository == 'JetBrains/ideavim' &&
|
|
github.event.issue.pull_request &&
|
|
contains(github.event.issue.title, 'Prepare What''s New for the upcoming release') &&
|
|
github.event.comment.user.type != 'Bot' &&
|
|
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)
|
|
|
|
permissions:
|
|
contents: write
|
|
pull-requests: write
|
|
id-token: write
|
|
issues: read
|
|
actions: read
|
|
|
|
steps:
|
|
- name: Verify the PR and the commenter
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
REPO: ${{ github.repository }}
|
|
PR_NUMBER: ${{ github.event.issue.number }}
|
|
COMMENTER: ${{ github.event.comment.user.login }}
|
|
run: |
|
|
head=$(gh api "repos/$REPO/pulls/$PR_NUMBER" --jq '.head.repo.full_name + ":" + .head.ref')
|
|
if [ "$head" != "$REPO:whatsnew-tbr" ]; then
|
|
echo "::error::PR #$PR_NUMBER head is '$head', expected '$REPO:whatsnew-tbr'"
|
|
exit 1
|
|
fi
|
|
permission=$(gh api "repos/$REPO/collaborators/$COMMENTER/permission" --jq '.permission')
|
|
if [ "$permission" != "admin" ] && [ "$permission" != "write" ]; then
|
|
echo "::error::$COMMENTER has '$permission' permission, write access is required"
|
|
exit 1
|
|
fi
|
|
|
|
- name: Checkout the What's New PR branch
|
|
uses: actions/checkout@v4
|
|
with:
|
|
ref: whatsnew-tbr
|
|
fetch-depth: 0 # Full history for the changelog skill
|
|
# Keep the push token out of .git/config so Claude can't use it
|
|
persist-credentials: false
|
|
|
|
- name: Run Claude Code to apply the requested changes
|
|
id: claude
|
|
uses: anthropics/claude-code-action@v1
|
|
env:
|
|
ANTHROPIC_BASE_URL: ${{ secrets.PROXY_URL }}
|
|
ANTHROPIC_CUSTOM_HEADERS: |
|
|
Grazie-Agent: {"name":"ideavim-claude-code-action","version":"github-actions"}
|
|
Grazie-Authenticate-JWT: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
with:
|
|
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
|
|
additional_permissions: |
|
|
actions: read
|
|
|
|
prompt: |
|
|
A maintainer left a comment on the "What's New" pull request (branch
|
|
`whatsnew-tbr`). Read the comment below and apply exactly what it asks
|
|
by editing the files in the working tree. Do NOT commit or push — the
|
|
workflow does that after you finish.
|
|
|
|
## The maintainer's comment
|
|
${{ github.event.comment.body }}
|
|
|
|
## What you can change
|
|
- The What's New page: `src/main/resources/whatsnew-tbr.html`.
|
|
- The changelog `## [To Be Released]` section of `CHANGES.md`, if the
|
|
comment asks for changelog changes (use the `changelog` skill for its rules).
|
|
Changes to any other file are rejected and nothing gets pushed.
|
|
Make the smallest change that satisfies the comment — do NOT rewrite or
|
|
restyle anything that wasn't asked about.
|
|
|
|
## Hard rules for the page (keep the existing look intact)
|
|
- Keep the entire `<head>`/`<style>` block, every CSS class, the
|
|
`data-theme="__THEME__"` attribute and the `__VERSION__` token unchanged.
|
|
- Never hard-code a version; leave `__VERSION__` exactly as-is.
|
|
- Keep the `<!-- whatsnew-release-commit: ... -->` line at the top unchanged.
|
|
- Escape HTML correctly inside `code`/`kbd`/`pre` (`<` `>` `&`).
|
|
- Keep the friendly, user-facing tone; no `VIM-####` ids or raw issue URLs.
|
|
|
|
## Finish
|
|
- Leave your edits uncommitted in the working tree.
|
|
- If the comment doesn't request any actionable change to the page or
|
|
changelog, make no changes and briefly explain why.
|
|
|
|
# Edits limited to the two files + changelog skill + read-only git/gh.
|
|
claude_args: '--allowed-tools "Skill,Read,Glob,Grep,Edit(src/main/resources/whatsnew-tbr.html),Write(src/main/resources/whatsnew-tbr.html),Edit(CHANGES.md),Write(CHANGES.md),Bash(git log:*),Bash(git show:*),Bash(git diff:*),Bash(git tag --list:*),Bash(gh pr view:*),Bash(gh pr list:*),WebSearch,WebFetch(domain:plugins.jetbrains.com),WebFetch(domain:youtrack.jetbrains.com),WebFetch(domain:github.com)"'
|
|
|
|
- name: Push the allowed changes to whatsnew-tbr
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
REPO: ${{ github.repository }}
|
|
run: |
|
|
changed=$(git status --porcelain --untracked-files=all | cut -c4-)
|
|
if [ -z "$changed" ]; then
|
|
echo "No changes to push"
|
|
exit 0
|
|
fi
|
|
disallowed=$(echo "$changed" | grep -vxE 'src/main/resources/whatsnew-tbr\.html|CHANGES\.md' || true)
|
|
if [ -n "$disallowed" ]; then
|
|
echo "::error::Claude changed files outside the allowed set:"
|
|
echo "$disallowed"
|
|
exit 1
|
|
fi
|
|
if [ "$(git rev-parse HEAD)" != "$(git rev-parse origin/whatsnew-tbr)" ]; then
|
|
echo "::error::HEAD moved away from origin/whatsnew-tbr, refusing to push"
|
|
exit 1
|
|
fi
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
git add src/main/resources/whatsnew-tbr.html CHANGES.md
|
|
git commit -m "Update What's New based on review comment"
|
|
git push "https://x-access-token:${GH_TOKEN}@github.com/${REPO}.git" HEAD:whatsnew-tbr
|