1313 pull-requests : write
1414 id-token : write
1515 steps :
16+ - name : Generate GitHub App token
17+ id : generate-token
18+ uses : actions/create-github-app-token@v1
19+ with :
20+ app-id : ${{ secrets.GH_APP_ID }}
21+ private-key : ${{ secrets.GH_APP_PRIVATE_KEY }}
22+ owner : cloudflare
23+
1624 - name : Checkout source repository
1725 uses : actions/checkout@v4
1826 with :
@@ -23,45 +31,25 @@ jobs:
2331 id : changed-files
2432 run : |
2533 git fetch origin ${{ github.event.pull_request.base.ref }}
26- git diff --name-only origin/${{ github.event.pull_request.base.ref }}...HEAD > changed_files.txt
27- echo "Changed files:"
28- cat changed_files.txt
29- grep '^docs/.*\.md$' changed_files.txt > docs_changed.txt || echo "No docs changed"
30-
31- - name : Get file contents and diffs
32- id : get-diffs
33- run : |
34- mkdir -p /tmp/diffs
35- touch /tmp/diffs/changes.txt
36-
37- # Capture all changed files and their diffs
38- while IFS= read -r file; do
39- echo "=== $file ===" >> /tmp/diffs/changes.txt
40- git diff origin/${{ github.event.pull_request.base.ref }}...HEAD -- "$file" >> /tmp/diffs/changes.txt
41- echo -e "\n\n" >> /tmp/diffs/changes.txt
42- done < changed_files.txt
43-
44- # Always run - let Claude decide if docs are needed
45- echo "skip=false" >> $GITHUB_OUTPUT
34+ CHANGED_FILES=$(git diff --name-only origin/${{ github.event.pull_request.base.ref }}...HEAD | tr '\n' ',' | sed 's/,$//')
35+ echo "changed_files=$CHANGED_FILES" >> $GITHUB_OUTPUT
36+ echo "Changed files: $CHANGED_FILES"
4637
4738 - name : Checkout cloudflare-docs repository
48- if : steps.get-diffs.outputs.skip != 'true'
4939 uses : actions/checkout@v4
5040 with :
5141 repository : cloudflare/cloudflare-docs
52- token : ${{ secrets.AGENTS_GITHUB_TOKEN }}
42+ token : ${{ steps.generate-token.outputs.token }}
5343 path : cloudflare-docs
5444
5545 - name : Create branch in cloudflare-docs
56- if : steps.get-diffs.outputs.skip != 'true'
5746 run : |
5847 cd cloudflare-docs
5948 git config user.name "github-actions[bot]"
6049 git config user.email "github-actions[bot]@users.noreply.github.com"
6150 git checkout -b sync-docs-pr-${{ github.event.pull_request.number }}
6251
6352 - name : Create prompt for Claude Code
64- if : steps.get-diffs.outputs.skip != 'true'
6553 id : create-prompt
6654 run : |
6755 # Store PR metadata in environment variables to avoid shell escaping issues
@@ -72,30 +60,32 @@ jobs:
7260 cat > /tmp/claude_prompt.md << EOF
7361 # Intelligent Documentation Sync Task
7462
75- ⚠️ **CRITICAL INSTRUCTION**: All PR metadata is provided in the Context section below.
76- DO NOT run \`gh pr view\`, \`gh api\`, or any other command to fetch PR information from GitHub.
77- The PR number, title, and URL below are the ONLY source of truth. Use them EXACTLY as written.
78-
7963 ## Context
8064 - **Source Repository:** ${{ github.repository }}
8165 - **Original PR Number:** ${PR_NUMBER}
8266 - **Original PR Title:** ${PR_TITLE}
8367 - **Original PR URL:** ${PR_URL}
68+ - **Changed Files:** ${{ steps.changed-files.outputs.changed_files }}
8469 - **PR Description:**
8570 ${{ github.event.pull_request.body }}
8671
87- ## Changed Files and Diffs
88- $(cat /tmp/diffs/changes.txt)
72+ ⚠️ **IMPORTANT**: All PR metadata above is the ONLY source of truth. Use these values EXACTLY as written.
73+ DO NOT fetch PR title/URL from GitHub APIs.
8974
9075 ## Your Task: Evaluate and Act
9176
77+ **First, gather the information you need:**
78+ 1. Review the list of changed files above
79+ 2. Use \`gh pr diff ${PR_NUMBER}\` to see the full diff for this PR
80+ 3. Use the Read tool to examine specific files if needed
81+
9282 You have access to two repositories:
9383 1. The current directory (our main repo at ${{ github.repository }})
9484 2. ./cloudflare-docs (already cloned with branch sync-docs-pr-${{ github.event.pull_request.number }} checked out)
9585
9686 **Step 1: Evaluate if Documentation Sync is Needed**
9787
98- Please review the changes in this PR and determine if they require documentation updates in cloudflare-docs:
88+ Review the changes and determine if they require documentation updates in cloudflare-docs:
9989
10090 - **ALWAYS sync if ANY of these are true:**
10191 - Documentation files in docs/ were directly changed (even if other non-doc files also changed)
@@ -130,20 +120,23 @@ jobs:
130120 Run exactly: `cd cloudflare-docs && git push origin sync-docs-pr-${PR_NUMBER}`
131121
132122 7. **CRITICAL - Create or update PR in cloudflare-docs:**
133- ⚠️ **CRITICAL**:
134- - DO NOT fetch PR data from GitHub API to get title/description
135- - DO NOT add your own description or summary
136- - Use ONLY the PR_NUMBER, PR_TITLE, and PR_URL from the Context section above
137-
138- First check if PR already exists, then create or update:
123+ ⚠️ **CRITICAL**: Use the exact PR_NUMBER, PR_TITLE, and PR_URL values from the Context section above.
124+
125+ Copy and run this EXACT script (replace PLACEHOLDER values with actual values from Context):
139126 ```bash
127+ # Set variables from Context section above
128+ PR_NUMBER="PLACEHOLDER_PR_NUMBER"
129+ PR_TITLE="PLACEHOLDER_PR_TITLE"
130+ PR_URL="PLACEHOLDER_PR_URL"
131+
140132 # Check if PR already exists
141133 EXISTING_PR=$(gh pr list --repo cloudflare/cloudflare-docs --head sync-docs-pr-${PR_NUMBER} --json number --jq '.[0].number')
142-
134+
135+ # Create PR title and body
143136 PR_TITLE_TEXT="📚 Sync docs from cloudflare/agents#${PR_NUMBER}: ${PR_TITLE}"
144137 PR_BODY_TEXT="Syncs documentation changes from [cloudflare/agents#${PR_NUMBER}](${PR_URL}): **${PR_TITLE}**"
145-
146- if [ -n "$EXISTING_PR" ]; then
138+
139+ if [ -n "$EXISTING_PR" ] && [ "$EXISTING_PR" != "null" ] ; then
147140 # Update existing PR
148141 echo "Updating existing PR #$EXISTING_PR"
149142 gh pr edit $EXISTING_PR --repo cloudflare/cloudflare-docs --title "$PR_TITLE_TEXT" --body "$PR_BODY_TEXT"
@@ -153,73 +146,8 @@ jobs:
153146 gh pr create --repo cloudflare/cloudflare-docs --base main --head sync-docs-pr-${PR_NUMBER} --title "$PR_TITLE_TEXT" --body "$PR_BODY_TEXT"
154147 fi
155148 ```
156-
157- DO NOT modify the PR_TITLE_TEXT or PR_BODY_TEXT variables.
158-
159- 8. **CRITICAL - Comment on original PR:**
160- ⚠️ **IMPORTANT**: Execute this ENTIRE script as ONE command. Do not split into multiple executions.
161-
162- Copy and run this complete bash script:
163- ```bash
164- #!/bin/bash
165- set -e
166-
167- echo "=== Step 8: Managing PR comment ==="
168-
169- # Get the docs PR URL
170- DOCS_PR_URL=$(gh pr list --repo cloudflare/cloudflare-docs --head sync-docs-pr-${PR_NUMBER} --json url --jq '.[0].url')
171- echo "Docs PR URL: $DOCS_PR_URL"
172-
173- # Find existing comment with our unique marker
174- EXISTING_COMMENT_ID=$(gh api "repos/cloudflare/agents/issues/${PR_NUMBER}/comments" \
175- --jq '.[] | select(.body | contains("<!-- DOCS-SYNC-AUTOMATION -->")) | .id' \
176- | head -n 1)
177-
178- # Prepare comment body (note the unique marker at the start)
179- COMMENT_BODY=\$(printf '%s\n\n%s\n\n%s' \\
180- '<!-- DOCS-SYNC-AUTOMATION -->' \\
181- "📚 **Documentation sync PR:** \$DOCS_PR_URL" \\
182- '_This comment is automatically updated when the PR changes._')
183-
184- # Update existing or create new comment
185- if [ -n "$EXISTING_COMMENT_ID" ] && [ "$EXISTING_COMMENT_ID" != "null" ]; then
186- echo "Found existing comment ID: $EXISTING_COMMENT_ID - updating it"
187- gh api --method PATCH \
188- "repos/cloudflare/agents/issues/comments/$EXISTING_COMMENT_ID" \
189- -f body="$COMMENT_BODY"
190- echo "✅ Updated existing comment"
191- else
192- echo "No existing comment found - creating new one"
193- gh pr comment ${PR_NUMBER} \
194- --repo cloudflare/agents \
195- --body "$COMMENT_BODY"
196- echo "✅ Created new comment"
197- fi
198-
199- # Cleanup any duplicate comments (keep only the newest)
200- ALL_COMMENT_IDS=$(gh api "repos/cloudflare/agents/issues/${PR_NUMBER}/comments" \
201- --jq '.[] | select(.body | contains("<!-- DOCS-SYNC-AUTOMATION -->")) | .id')
202-
203- COMMENT_COUNT=$(echo "$ALL_COMMENT_IDS" | wc -l | tr -d ' ')
204-
205- if [ "$COMMENT_COUNT" -gt 1 ]; then
206- echo "⚠️ Found $COMMENT_COUNT duplicate comments - cleaning up"
207- # Keep the last one (newest), delete others
208- echo "$ALL_COMMENT_IDS" | head -n -1 | while read -r OLD_ID; do
209- if [ -n "$OLD_ID" ]; then
210- echo "Deleting old comment ID: $OLD_ID"
211- gh api --method DELETE "repos/cloudflare/agents/issues/comments/$OLD_ID"
212- fi
213- done
214- echo "✅ Cleaned up duplicate comments"
215- else
216- echo "✅ Only one comment exists - no cleanup needed"
217- fi
218-
219- echo "=== Step 8 complete ==="
220- ```
221149
222- ⚠️ THE TASK IS NOT COMPLETE UNTIL ALL 8 STEPS ARE DONE. Do not stop after editing files.
150+ ⚠️ THE TASK IS NOT COMPLETE UNTIL ALL 7 STEPS ARE DONE. Do not stop after editing files.
223151
224152 ## Documentation Writing Guidelines (Diátaxis Framework)
225153
@@ -299,12 +227,11 @@ jobs:
299227 echo "PROMPT_EOF" >> $GITHUB_OUTPUT
300228
301229 - name : Run Claude Code to create adapted PR
302- if : steps.get-diffs.outputs.skip != 'true'
303230 uses : anthropics/claude-code-action@v1
304231 with :
305232 anthropic_api_key : ${{ secrets.ANTHROPIC_API_KEY }}
306- github_token : ${{ secrets.GITHUB_TOKEN }}
233+ github_token : ${{ steps.generate-token.outputs.token }}
307234 prompt : ${{ steps.create-prompt.outputs.prompt }}
308- claude_args : " --allowed-tools Bash ,Edit,Write"
235+ claude_args : ' --allowed-tools "Read ,Edit,Write,Bash" '
309236 env :
310- GH_TOKEN : ${{ secrets.AGENTS_GITHUB_TOKEN }}
237+ GH_TOKEN : ${{ steps.generate-token.outputs.token }}
0 commit comments