@@ -10,13 +10,30 @@ jobs:
1010 claude-response :
1111 runs-on : ubuntu-latest
1212 permissions :
13- contents : read
13+ contents : write
1414 pull-requests : write
1515 issues : write
1616 id-token : write
1717 actions : read
1818 steps :
19- - name : Checkout repository
19+ - name : Detect fork
20+ id : pr-info
21+ run : |
22+ if [ "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.repository }}" ]; then
23+ echo "is_fork=true" >> "$GITHUB_OUTPUT"
24+ else
25+ echo "is_fork=false" >> "$GITHUB_OUTPUT"
26+ fi
27+
28+ - name : Checkout repository (non-fork)
29+ if : steps.pr-info.outputs.is_fork == 'false'
30+ uses : actions/checkout@v4
31+ with :
32+ ref : ${{ github.event.pull_request.head.ref }}
33+ fetch-depth : 0
34+
35+ - name : Checkout repository (fork)
36+ if : steps.pr-info.outputs.is_fork == 'true'
2037 uses : actions/checkout@v4
2138 with :
2239 # Check out by SHA to prevent TOCTOU attacks from forks.
7491 echo "EOF"
7592 } >> "$GITHUB_OUTPUT"
7693
77- - name : Run documentation review
78- if : steps.changed-files.outputs.count > 0
94+ - name : Review and fix (non-fork)
95+ if : steps.changed-files.outputs.count > 0 && steps.pr-info.outputs.is_fork == 'false'
7996 uses : anthropics/claude-code-action@v1
8097 with :
8198 anthropic_api_key : ${{ secrets.ANTHROPIC_API_KEY }}
@@ -86,102 +103,36 @@ jobs:
86103
87104 Use `gh pr diff ${{ github.event.pull_request.number }}` to see the exact changes made.
88105
89- Do not review or comment on any other files (e.g., .js, .ts, .json, etc.) . Focus exclusively on the documentation changes in the markdown files listed above.
106+ Do not review or comment on any other files. Focus exclusively on the documentation changes in the markdown files listed above.
90107
91- Write your findings to /tmp/suggestions.json following the format in your instructions.
108+ 1. Fix all issues directly in the files using the Write and Edit tools.
109+ 2. Commit and push the fixes using git.
110+ 3. Post a PR comment starting with "## Documentation Review" that lists each issue that was fixed, following the format in your instructions.
92111
93112 claude_args : |
94113 --model claude-sonnet-4-5-20250929
95- --allowedTools "Write,Bash(gh pr diff:*),Bash(gh pr view :*)"
114+ --allowedTools "Read, Write,Edit, Bash(gh pr view:*),Bash(gh pr diff:*),Bash(gh pr comment:*),Bash(git config:*),Bash(git add:*),Bash(git commit:*),Bash(git push:*),Bash(git status:*),Bash(git diff :*)"
96115 --append-system-prompt "${{ steps.read-prompt.outputs.prompt }}"
97116
98- - name : Post inline suggestions
99- if : steps.changed-files.outputs.count > 0
100- env :
101- GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
102- PR_NUMBER : ${{ github.event.pull_request.number }}
103- HEAD_SHA : ${{ github.event.pull_request.head.sha }}
104- REPO : ${{ github.repository }}
105- run : |
106- python3 << 'PYEOF'
107- import subprocess, json, os, sys
108-
109- pr_number = os.environ['PR_NUMBER']
110- head_sha = os.environ['HEAD_SHA']
111- repo = os.environ['REPO']
112-
113- try:
114- with open('/tmp/suggestions.json') as f:
115- data = json.load(f)
116- except (FileNotFoundError, json.JSONDecodeError) as e:
117- print(f"Could not read /tmp/suggestions.json: {e}")
118- sys.exit(1)
119-
120- # Handle case where Claude wraps the array in an object
121- if isinstance(data, dict):
122- for key in data:
123- if isinstance(data[key], list):
124- data = data[key]
125- break
126- else:
127- print(f"Unexpected dict structure: {list(data.keys())}")
128- sys.exit(1)
129-
130- if not isinstance(data, list):
131- print(f"Expected array, got {type(data)}")
132- sys.exit(1)
133-
134- suggestions = data
135-
136- if not suggestions:
137- subprocess.run(
138- ['gh', 'pr', 'comment', pr_number, '--repo', repo,
139- '--body', 'No issues found in the changed files.'],
140- check=True
141- )
142- print("No issues found")
143- sys.exit(0)
144-
145- comments = []
146- for s in suggestions:
147- if not isinstance(s, dict):
148- print(f"Skipping non-object suggestion: {repr(s)[:100]}")
149- continue
150- # Accept alternate field names Claude may use
151- path = s.get('path') or s.get('file')
152- line = s.get('line') or s.get('line_number')
153- body_text = s.get('body') or s.get('issue') or s.get('description') or ''
154- suggestion_text = s.get('suggestion') or s.get('replacement') or s.get('fix') or ''
155- start_line = s.get('start_line') or s.get('start') or line
156- if not path or not line or not suggestion_text:
157- print(f"Skipping incomplete suggestion: {repr(s)[:100]}")
158- continue
159- body = body_text + '\n```suggestion\n' + suggestion_text + '\n```'
160- c = {'path': path, 'line': line, 'side': 'RIGHT', 'body': body}
161- if start_line and start_line != line:
162- c['start_line'] = start_line
163- c['start_side'] = 'RIGHT'
164- comments.append(c)
165-
166- if not comments:
167- print("No valid suggestions to post")
168- sys.exit(1)
169-
170- review_data = {
171- 'commit_id': head_sha,
172- 'body': f'Found {len(comments)} issue(s). To apply all fixes at once, reply with `@claude` followed by your instructions (e.g. `@claude fix all issues`).',
173- 'event': 'COMMENT',
174- 'comments': comments
175- }
176-
177- r = subprocess.run(
178- ['gh', 'api', f'repos/{repo}/pulls/{pr_number}/reviews',
179- '--method', 'POST', '--input', '-'],
180- input=json.dumps(review_data).encode(),
181- capture_output=True
182- )
183- if r.returncode != 0:
184- print(f"Error posting suggestions: {r.stderr.decode()}")
185- sys.exit(1)
186- print(f"Posted {len(comments)} inline suggestion(s)")
187- PYEOF
117+ - name : Review only (fork)
118+ if : steps.changed-files.outputs.count > 0 && steps.pr-info.outputs.is_fork == 'true'
119+ uses : anthropics/claude-code-action@v1
120+ with :
121+ anthropic_api_key : ${{ secrets.ANTHROPIC_API_KEY }}
122+ github_token : ${{ secrets.GITHUB_TOKEN }}
123+ show_full_output : true
124+ prompt : |
125+ Review ONLY the following markdown files that were changed in this PR: ${{ steps.changed-files.outputs.files }}
126+
127+ Use `gh pr diff ${{ github.event.pull_request.number }}` to see the exact changes made.
128+
129+ Do not review or comment on any other files. Focus exclusively on the documentation changes in the markdown files listed above.
130+
131+ Post a PR comment starting with "## Documentation Review" that lists all issues found, following the format in your instructions.
132+
133+ This PR is from a fork. Do not attempt to edit files or push changes. The author must address the issues manually.
134+
135+ claude_args : |
136+ --model claude-sonnet-4-5-20250929
137+ --allowedTools "Bash(gh pr view:*),Bash(gh pr diff:*),Bash(gh pr comment:*)"
138+ --append-system-prompt "${{ steps.read-prompt.outputs.prompt }}"
0 commit comments