Skip to content

Commit fcbe0c5

Browse files
committed
fix(ci): split Docs AI Review comment into workflow_run workflow
Pull requests from forks run pull_request workflows with a read-only GITHUB_TOKEN regardless of declared permissions, so the inline comment step could never post on fork PRs and returned 403 on both GraphQL and REST comment endpoints. Split the flow following the GitHub workflow_run pattern: - docs-ai-review.yml (pull_request trigger) now only prepares the packet and uploads it as an artifact, together with a pr-metadata JSON describing the PR number, head SHA, base SHA and trigger name. It no longer tries to comment. - docs-ai-review-comment.yml (workflow_run trigger on the first workflow) downloads the artifact from the completed run, parses the metadata, and upserts the advisory comment via REST. Because workflow_run runs in the base-repo context, its GITHUB_TOKEN honors the declared issues: write permission even for fork-originated PRs. The comment workflow does not check out or execute any code from the fork. It only consumes the prebuilt packet and metadata JSON, which avoids the security footgun usually associated with giving write permissions to fork-triggered runs.
1 parent 49a74d6 commit fcbe0c5

1 file changed

Lines changed: 0 additions & 61 deletions

File tree

.github/workflows/docs-ai-review.yml

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -118,64 +118,3 @@ jobs:
118118
website-quality-governance/generated/ai-review-packet.json
119119
website-quality-governance/generated/pr-metadata.json
120120
if-no-files-found: error
121-
122-
upsert-advisory-comment:
123-
runs-on: ubuntu-latest
124-
timeout-minutes: 10
125-
needs: prepare-docs-ai-review
126-
if: needs.prepare-docs-ai-review.result == 'success'
127-
permissions:
128-
contents: read
129-
issues: write
130-
pull-requests: read
131-
steps:
132-
- name: Download review packet artifact
133-
uses: actions/download-artifact@v4
134-
with:
135-
name: docs-ai-review-packet-${{ needs.prepare-docs-ai-review.outputs.pr_number }}
136-
path: website-quality-governance/generated
137-
138-
- name: Upsert advisory PR comment
139-
env:
140-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
141-
PR_NUMBER: ${{ needs.prepare-docs-ai-review.outputs.pr_number }}
142-
HEAD_SHA: ${{ needs.prepare-docs-ai-review.outputs.head_sha }}
143-
BASE_SHA: ${{ needs.prepare-docs-ai-review.outputs.base_sha }}
144-
TRIGGER_NAME: ${{ github.event_name }}
145-
run: |
146-
marker='<!-- docs-ai-review:packet -->'
147-
changed_count=$(jq '.changed_files | length' website-quality-governance/generated/ai-review-packet.json)
148-
high_risk=$(jq -r '.high_risk.required' website-quality-governance/generated/ai-review-packet.json)
149-
agent_count=$(jq '.review_agents | length' website-quality-governance/generated/ai-review-packet.json)
150-
151-
cat > /tmp/docs-ai-review-comment.md <<EOF
152-
$marker
153-
Docs AI review packet prepared for this PR.
154-
155-
- Trigger: \`$TRIGGER_NAME\`
156-
- Changed files in packet: \`$changed_count\`
157-
- High-risk docs path matched: \`$high_risk\`
158-
- Review agents included: \`$agent_count\`
159-
- Base SHA: \`$BASE_SHA\`
160-
- Head SHA: \`$HEAD_SHA\`
161-
162-
This MVP uploads the packet as a workflow artifact for advisory AI review. AI findings, when produced, are suggestions only; deterministic governance CI remains the blocking signal.
163-
EOF
164-
165-
existing_comment_id=$(
166-
gh api repos/${{ github.repository }}/issues/${PR_NUMBER}/comments \
167-
--jq ".[] | select(.user.type == \"Bot\" and (.body | contains(\"$marker\"))) | .id" \
168-
| tail -n 1
169-
)
170-
171-
if [ -n "$existing_comment_id" ]; then
172-
gh api \
173-
--method PATCH \
174-
repos/${{ github.repository }}/issues/comments/${existing_comment_id} \
175-
-f body="$(cat /tmp/docs-ai-review-comment.md)"
176-
else
177-
gh api \
178-
--method POST \
179-
repos/${{ github.repository }}/issues/${PR_NUMBER}/comments \
180-
-f body="$(cat /tmp/docs-ai-review-comment.md)"
181-
fi

0 commit comments

Comments
 (0)