@@ -3,62 +3,43 @@ name: Docs AI Review
33on :
44 issue_comment :
55 types : [created]
6- pull_request :
7- types : [labeled, synchronize, reopened]
86 workflow_dispatch :
97 inputs :
108 pr_number :
11- description : Pull request number to prepare a docs AI review packet for
9+ description : Pull request number to run docs AI review for
1210 required : true
1311 type : string
1412
1513permissions :
1614 contents : read
15+ issues : write
16+ pull-requests : read
1717
1818jobs :
19- prepare- docs-ai-review :
19+ docs-ai-review :
2020 runs-on : ubuntu-latest
2121 timeout-minutes : 20
22- permissions :
23- contents : read
24- pull-requests : read
25- outputs :
26- pr_number : ${{ steps.pr.outputs.number }}
27- head_sha : ${{ steps.pr.outputs.head_sha }}
28- base_sha : ${{ steps.pr.outputs.base_sha }}
2922 if : >-
3023 github.event_name == 'workflow_dispatch' ||
3124 (
32- github.event_name == 'issue_comment' &&
3325 github.event.issue.pull_request &&
3426 contains(github.event.comment.body, '/review-docs') &&
3527 (
3628 github.event.comment.author_association == 'MEMBER' ||
3729 github.event.comment.author_association == 'OWNER' ||
3830 github.event.comment.author_association == 'COLLABORATOR'
3931 )
40- ) ||
41- (
42- github.event_name == 'pull_request' &&
43- github.event.action == 'labeled' &&
44- github.event.label.name == 'ai-review-docs'
45- ) ||
46- (
47- github.event_name == 'pull_request' &&
48- (github.event.action == 'synchronize' || github.event.action == 'reopened') &&
49- contains(github.event.pull_request.labels.*.name, 'ai-review-docs')
5032 )
33+
5134 steps :
5235 - name : Get PR info
5336 id : pr
5437 env :
55- GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
38+ GH_TOKEN : ${{ github.token }}
5639 EVENT_NAME : ${{ github.event_name }}
5740 DISPATCH_PR_NUMBER : ${{ inputs.pr_number }}
5841 run : |
59- if [ "$EVENT_NAME" = "pull_request" ]; then
60- PR_NUMBER=$(jq -r '.pull_request.number' "$GITHUB_EVENT_PATH")
61- elif [ "$EVENT_NAME" = "workflow_dispatch" ]; then
42+ if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
6243 PR_NUMBER="$DISPATCH_PR_NUMBER"
6344 else
6445 PR_NUMBER=$(jq -r '.issue.number' "$GITHUB_EVENT_PATH")
@@ -91,30 +72,61 @@ jobs:
9172 env :
9273 BASE_SHA : ${{ steps.pr.outputs.base_sha }}
9374 HEAD_SHA : ${{ steps.pr.outputs.head_sha }}
94- PR_NUMBER : ${{ steps.pr.outputs.number }}
95- TRIGGER_NAME : ${{ github.event_name }}
9675 run : |
9776 mkdir -p website-quality-governance/generated
98- changed_files=$(git diff --name-only "$BASE_SHA" HEAD | paste -sd, -)
77+ changed_files=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" | paste -sd, -)
78+
9979 yarn docs:ai-review:prepare \
10080 --files "$changed_files" \
10181 --base "$BASE_SHA" \
10282 --output website-quality-governance/generated/ai-review-packet.json
83+
10384 jq '{schema_version, changed_files, high_risk, review_agents: [.review_agents[].id], sync_groups: [.sync_groups[].sync_group_id]}' \
10485 website-quality-governance/generated/ai-review-packet.json
105- jq -n \
106- --arg pr_number "$PR_NUMBER" \
107- --arg head_sha "$HEAD_SHA" \
108- --arg base_sha "$BASE_SHA" \
109- --arg trigger "$TRIGGER_NAME" \
110- '{pr_number: $pr_number, head_sha: $head_sha, base_sha: $base_sha, trigger: $trigger}' \
111- > website-quality-governance/generated/pr-metadata.json
112-
113- - name : Upload review packet artifact
114- uses : actions/upload-artifact@v4
115- with :
116- name : docs-ai-review-packet-${{ steps.pr.outputs.number }}
117- path : |
118- website-quality-governance/generated/ai-review-packet.json
119- website-quality-governance/generated/pr-metadata.json
120- if-no-files-found : error
86+
87+ - name : Upsert advisory PR comment
88+ env :
89+ GH_TOKEN : ${{ github.token }}
90+ PR_NUMBER : ${{ steps.pr.outputs.number }}
91+ HEAD_SHA : ${{ steps.pr.outputs.head_sha }}
92+ BASE_SHA : ${{ steps.pr.outputs.base_sha }}
93+ run : |
94+ packet=website-quality-governance/generated/ai-review-packet.json
95+
96+ marker='<!-- docs-ai-review:packet -->'
97+ changed_count=$(jq '.changed_files | length' "$packet")
98+ high_risk=$(jq -r '.high_risk.required' "$packet")
99+ agent_count=$(jq '.review_agents | length' "$packet")
100+
101+ cat > /tmp/docs-ai-review-comment.md <<EOF
102+ $marker
103+ Docs AI review packet prepared for this PR.
104+
105+ - Trigger: \`/review-docs\`
106+ - Changed files in packet: \`$changed_count\`
107+ - High-risk docs path matched: \`$high_risk\`
108+ - Review agents included: \`$agent_count\`
109+ - Base SHA: \`$BASE_SHA\`
110+ - Head SHA: \`$HEAD_SHA\`
111+
112+ This MVP prepares the packet for advisory AI review. AI findings, when produced, are suggestions only; deterministic governance CI remains the blocking signal.
113+ EOF
114+
115+ existing_comment_id=$(
116+ gh api "repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \
117+ --paginate \
118+ --jq ".[] | select(.user.type == \"Bot\" and (.body | contains(\"$marker\"))) | .id" \
119+ | tail -n 1
120+ )
121+
122+ if [ -n "$existing_comment_id" ]; then
123+ gh api \
124+ --method PATCH \
125+ "repos/${{ github.repository }}/issues/comments/${existing_comment_id}" \
126+ -f body="$(cat /tmp/docs-ai-review-comment.md)"
127+ else
128+ gh api \
129+ --method POST \
130+ "repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \
131+ -f body="$(cat /tmp/docs-ai-review-comment.md)"
132+ fi
0 commit comments