7474 curl -sfL "https://github.com/errata-ai/vale/releases/download/${VERSION}/vale_${VERSION#v}_Linux_64-bit.tar.gz" \
7575 | sudo tar -xz -C /usr/local/bin vale
7676
77+ - name : Record last comment ID
78+ id : pre-claude
79+ if : steps.pr-info.outputs.is_fork == 'false'
80+ env :
81+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
82+ run : |
83+ LAST_ID=$(gh api repos/${{ github.repository }}/issues/${{ steps.pr-info.outputs.number }}/comments \
84+ --jq 'if length > 0 then .[-1].id else 0 end' 2>/dev/null || echo "0")
85+ echo "last_comment_id=$LAST_ID" >> "$GITHUB_OUTPUT"
86+
7787 - name : Apply fixes
7888 if : steps.pr-info.outputs.is_fork == 'false'
7989 uses : anthropics/claude-code-action@v1
92102 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
93103 PR_NUMBER : ${{ steps.pr-info.outputs.number }}
94104 REPO : ${{ github.repository }}
105+ LAST_COMMENT_ID : ${{ steps.pre-claude.outputs.last_comment_id }}
95106 run : |
96107 python3 << 'PYTHON_EOF'
97108 import os
@@ -100,6 +111,7 @@ jobs:
100111
101112 pr_number = os.environ['PR_NUMBER']
102113 repo = os.environ['REPO']
114+ last_comment_id = int(os.environ.get('LAST_COMMENT_ID', '0'))
103115
104116 FOOTER = (
105117 "\n\n---\n\n"
@@ -108,8 +120,6 @@ jobs:
108120 "Note: Automated fixes are only available for branches in this repository, not forks."
109121 )
110122
111- FOOTER_MARKER = "Automated fixes are only available"
112-
113123 def normalize_body(body):
114124 """Keep only the expected structured content from the preexisting issues output."""
115125 idx = body.find('## Preexisting issues')
@@ -129,38 +139,38 @@ jobs:
129139 clean_lines.pop()
130140 return '\n'.join(clean_lines)
131141
132- def patch_comment(comment_id, new_body):
133- payload = {'body': new_body}
142+ # Only run for @claude detect preexisting issues
143+ summary_path = '/tmp/preexisting-issues.md'
144+ if not os.path.exists(summary_path):
145+ exit(0)
146+
147+ with open(summary_path) as f:
148+ clean_body = normalize_body(f.read()) + FOOTER
149+
150+ # Find all comments posted during this workflow run (ID > last recorded ID)
151+ result = subprocess.run(
152+ ['gh', 'api', f'repos/{repo}/issues/{pr_number}/comments'],
153+ capture_output=True, text=True, check=True,
154+ )
155+ comments = json.loads(result.stdout)
156+ new_comments = [c for c in comments
157+ if c['id'] > last_comment_id
158+ and c['user']['login'] == 'github-actions[bot]']
159+
160+ if new_comments:
161+ # Replace the most recent new comment (the action's auto-posted output)
162+ target_id = new_comments[-1]['id']
163+ payload = {'body': clean_body}
134164 subprocess.run(
135- ['gh', 'api', f'repos/{repo}/issues/comments/{comment_id }',
165+ ['gh', 'api', f'repos/{repo}/issues/comments/{target_id }',
136166 '-X', 'PATCH', '--input', '-'],
137167 input=json.dumps(payload),
138168 capture_output=True, text=True, check=True,
139169 )
140-
141- summary_path = '/tmp/preexisting-issues.md'
142- if os.path.exists(summary_path):
143- # Claude wrote to the file as instructed — post a new comment with footer
144- with open(summary_path) as f:
145- body = normalize_body(f.read())
170+ else:
171+ # No new comment found — post one directly
146172 subprocess.run(
147- ['gh', 'pr', 'comment', pr_number, '--repo', repo, '--body', body + FOOTER ],
173+ ['gh', 'pr', 'comment', pr_number, '--repo', repo, '--body', clean_body ],
148174 check=True,
149175 )
150- else:
151- # Claude posted directly — find that comment, strip any intro and notes,
152- # and add this exact footer:
153- # To apply the suggested fixes to preexisting issues, comment `@claude` on this PR followed by your instructions
154- # (`@claude fix all issues` or `@claude fix only the first issue`).
155- # Note: Automated fixes are only available for branches in this repository, not forks.
156- result = subprocess.run(
157- ['gh', 'api', f'repos/{repo}/issues/{pr_number}/comments'],
158- capture_output=True, text=True, check=True,
159- )
160- comments = json.loads(result.stdout)
161- for comment in reversed(comments):
162- body = comment['body']
163- if '## Preexisting issues' in body and FOOTER_MARKER not in body:
164- patch_comment(comment['id'], normalize_body(body) + FOOTER)
165- break
166176 PYTHON_EOF
0 commit comments