Skip to content

Commit 9f5aa55

Browse files
authored
[fix] .github/workflows/docs-ai-review.yml (#3579)
1 parent d24277d commit 9f5aa55

1 file changed

Lines changed: 55 additions & 7 deletions

File tree

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

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@ on:
1010
required: true
1111
type: string
1212

13+
# Same trust model as opencode-review.yml:
14+
# - triggered by a trusted maintainer/collaborator comment
15+
# - comments directly from this workflow
16+
# - does not rely on pull_request -> artifact -> workflow_run
1317
permissions:
1418
contents: read
1519
issues: write
16-
pull-requests: read
20+
pull-requests: write
1721

1822
jobs:
1923
docs-ai-review:
@@ -32,33 +36,66 @@ jobs:
3236
)
3337
3438
steps:
39+
- name: Validate trigger command
40+
if: github.event_name == 'issue_comment'
41+
run: |
42+
body=$(jq -r '.comment.body' "$GITHUB_EVENT_PATH")
43+
44+
# Require /review-docs as a standalone command on its own line.
45+
# This avoids accidental triggers from prose and keeps it distinct from /review.
46+
if ! printf '%s\n' "$body" | grep -Eq '^/review-docs([[:space:]]|$)'; then
47+
echo "No standalone /review-docs command found; skipping."
48+
exit 78
49+
fi
50+
3551
- name: Get PR info
3652
id: pr
3753
env:
38-
GH_TOKEN: ${{ github.token }}
54+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3955
EVENT_NAME: ${{ github.event_name }}
4056
DISPATCH_PR_NUMBER: ${{ inputs.pr_number }}
4157
run: |
58+
set -euo pipefail
59+
4260
if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
4361
PR_NUMBER="$DISPATCH_PR_NUMBER"
4462
else
4563
PR_NUMBER=$(jq -r '.issue.number' "$GITHUB_EVENT_PATH")
4664
fi
4765
4866
PR_JSON=$(gh api repos/${{ github.repository }}/pulls/${PR_NUMBER})
67+
4968
HEAD_SHA=$(echo "$PR_JSON" | jq -r '.head.sha')
5069
BASE_SHA=$(echo "$PR_JSON" | jq -r '.base.sha')
70+
HEAD_REF=$(echo "$PR_JSON" | jq -r '.head.ref')
71+
BASE_REF=$(echo "$PR_JSON" | jq -r '.base.ref')
72+
HEAD_REPO=$(echo "$PR_JSON" | jq -r '.head.repo.full_name')
73+
BASE_REPO=$(echo "$PR_JSON" | jq -r '.base.repo.full_name')
5174
5275
echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
5376
echo "head_sha=$HEAD_SHA" >> "$GITHUB_OUTPUT"
5477
echo "base_sha=$BASE_SHA" >> "$GITHUB_OUTPUT"
78+
echo "head_ref=$HEAD_REF" >> "$GITHUB_OUTPUT"
79+
echo "base_ref=$BASE_REF" >> "$GITHUB_OUTPUT"
80+
echo "head_repo=$HEAD_REPO" >> "$GITHUB_OUTPUT"
81+
echo "base_repo=$BASE_REPO" >> "$GITHUB_OUTPUT"
5582
5683
- name: Checkout PR head
5784
uses: actions/checkout@v4
5885
with:
86+
repository: ${{ steps.pr.outputs.head_repo }}
5987
ref: ${{ steps.pr.outputs.head_sha }}
6088
fetch-depth: 0
6189

90+
- name: Fetch base commit
91+
env:
92+
BASE_REPO: ${{ steps.pr.outputs.base_repo }}
93+
BASE_SHA: ${{ steps.pr.outputs.base_sha }}
94+
run: |
95+
set -euo pipefail
96+
git remote add base "https://github.com/${BASE_REPO}.git" || true
97+
git fetch --no-tags --depth=1 base "$BASE_SHA"
98+
6299
- name: Setup Node
63100
uses: actions/setup-node@v4
64101
with:
@@ -73,7 +110,10 @@ jobs:
73110
BASE_SHA: ${{ steps.pr.outputs.base_sha }}
74111
HEAD_SHA: ${{ steps.pr.outputs.head_sha }}
75112
run: |
113+
set -euo pipefail
114+
76115
mkdir -p website-quality-governance/generated
116+
77117
changed_files=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" | paste -sd, -)
78118
79119
yarn docs:ai-review:prepare \
@@ -86,31 +126,37 @@ jobs:
86126
87127
- name: Upsert advisory PR comment
88128
env:
89-
GH_TOKEN: ${{ github.token }}
129+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
90130
PR_NUMBER: ${{ steps.pr.outputs.number }}
91131
HEAD_SHA: ${{ steps.pr.outputs.head_sha }}
92132
BASE_SHA: ${{ steps.pr.outputs.base_sha }}
93133
run: |
94-
packet=website-quality-governance/generated/ai-review-packet.json
134+
set -euo pipefail
95135
136+
packet=website-quality-governance/generated/ai-review-packet.json
96137
marker='<!-- docs-ai-review:packet -->'
138+
97139
changed_count=$(jq '.changed_files | length' "$packet")
98-
high_risk=$(jq -r '.high_risk.required' "$packet")
140+
high_risk=$(jq -r '.high_risk.required // false' "$packet")
99141
agent_count=$(jq '.review_agents | length' "$packet")
142+
sync_group_count=$(jq '.sync_groups | length' "$packet")
100143
101-
cat > /tmp/docs-ai-review-comment.md <<EOF
144+
cat > /tmp/docs-ai-review-comment.md <<EOF_COMMENT
102145
$marker
146+
## Docs AI Review
147+
103148
Docs AI review packet prepared for this PR.
104149
105150
- Trigger: \`/review-docs\`
106151
- Changed files in packet: \`$changed_count\`
107152
- High-risk docs path matched: \`$high_risk\`
108153
- Review agents included: \`$agent_count\`
154+
- Sync groups included: \`$sync_group_count\`
109155
- Base SHA: \`$BASE_SHA\`
110156
- Head SHA: \`$HEAD_SHA\`
111157
112158
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
159+
EOF_COMMENT
114160
115161
existing_comment_id=$(
116162
gh api "repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \
@@ -125,6 +171,8 @@ jobs:
125171
"repos/${{ github.repository }}/issues/comments/${existing_comment_id}" \
126172
-f body="$(cat /tmp/docs-ai-review-comment.md)"
127173
else
174+
# Same effective behavior as: gh pr comment "$PR_NUMBER" --body-file /tmp/docs-ai-review-comment.md
175+
# Use REST API so we can preserve the upsert-by-marker behavior above.
128176
gh api \
129177
--method POST \
130178
"repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \

0 commit comments

Comments
 (0)