From 38139c62eb6f3659dbebbf6dcc9ca7245b8100c6 Mon Sep 17 00:00:00 2001 From: jth-nw Date: Wed, 11 Mar 2026 11:45:23 -0500 Subject: [PATCH] fix: post Vale issues as inline PR review comments Vale issues now appear as inline comments on the exact lines in the diff, posted via the GitHub PR review API. Claude's task is reduced to just the editorial review + posting the summary comment. Changes: - Vale step parses line output and builds JSON for inline comments - Posts a PR review with inline comments via gh api pulls/reviews - Dismisses previous bot reviews on re-runs to avoid piling up - Claude prompt simplified to editorial review only - Vale count passed to Claude for the summary line Co-Authored-By: Claude Opus 4.6 --- .github/workflows/claude-doc-pr.yml | 71 +++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/.github/workflows/claude-doc-pr.yml b/.github/workflows/claude-doc-pr.yml index 43a7b3bdbd..1d7e096f8c 100644 --- a/.github/workflows/claude-doc-pr.yml +++ b/.github/workflows/claude-doc-pr.yml @@ -48,17 +48,25 @@ jobs: echo "count=$(echo "$CHANGED_MD_FILES" | wc -l | tr -d ' ')" >> "$GITHUB_OUTPUT" fi - - name: Delete previous bot review comments + - name: Delete previous bot comments if: steps.changed-files.outputs.count > 0 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | PR_NUMBER=${{ github.event.pull_request.number }} + # Delete previous review comments COMMENT_IDS=$(gh api repos/${{ github.repository }}/issues/${PR_NUMBER}/comments \ --jq '[.[] | select(.user.login == "github-actions[bot]" and (.body | contains("Documentation PR Review"))) | .id] | .[]' 2>/dev/null || true) for ID in $COMMENT_IDS; do gh api repos/${{ github.repository }}/issues/comments/${ID} -X DELETE 2>/dev/null || true done + # Dismiss previous Vale reviews so they don't pile up + REVIEW_IDS=$(gh api repos/${{ github.repository }}/pulls/${PR_NUMBER}/reviews \ + --jq '[.[] | select(.user.login == "github-actions[bot]" and .state == "COMMENTED") | .id] | .[]' 2>/dev/null || true) + for ID in $REVIEW_IDS; do + gh api repos/${{ github.repository }}/pulls/${PR_NUMBER}/reviews/${ID}/dismissals \ + -f message="Superseded by new review" -f event="DISMISS" 2>/dev/null || true + done - name: Install Vale if: steps.changed-files.outputs.count > 0 @@ -67,26 +75,53 @@ jobs: curl -sfL "https://github.com/errata-ai/vale/releases/download/${VERSION}/vale_${VERSION#v}_Linux_64-bit.tar.gz" \ | sudo tar -xz -C /usr/local/bin vale - - name: Run Vale on changed files + - name: Run Vale and post inline comments id: vale if: steps.changed-files.outputs.count > 0 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | IFS=',' read -ra FILES <<< "${{ steps.changed-files.outputs.files }}" - VALE_OUTPUT="" + VALE_COUNT=0 + COMMENTS_JSON="[]" + for FILE in "${FILES[@]}"; do if [ -f "$FILE" ]; then RESULT=$(vale --output=line "$FILE" 2>&1 || true) if [ -n "$RESULT" ]; then - VALE_OUTPUT+="**${FILE}**"$'\n\n'"${RESULT}"$'\n\n' - else - VALE_OUTPUT+="**${FILE}** — No issues found."$'\n\n' + while IFS= read -r LINE; do + # Format: file:line:col:rule:message + LINE_NUM=$(echo "$LINE" | cut -d: -f2) + RULE=$(echo "$LINE" | cut -d: -f4) + MESSAGE=$(echo "$LINE" | cut -d: -f5-) + if [ -n "$LINE_NUM" ] && [ -n "$MESSAGE" ]; then + BODY="**Vale** (\`${RULE}\`): ${MESSAGE}" + COMMENTS_JSON=$(echo "$COMMENTS_JSON" | jq \ + --arg path "$FILE" \ + --argjson line "$LINE_NUM" \ + --arg body "$BODY" \ + '. += [{"path": $path, "line": $line, "body": $body}]') + VALE_COUNT=$((VALE_COUNT + 1)) + fi + done <<< "$RESULT" fi fi done - # Save to file for Claude to read - echo "$VALE_OUTPUT" > /tmp/vale-results.txt - echo "Vale results saved to /tmp/vale-results.txt" - cat /tmp/vale-results.txt + + echo "vale_count=$VALE_COUNT" >> "$GITHUB_OUTPUT" + + if [ "$VALE_COUNT" -gt 0 ]; then + echo "Posting $VALE_COUNT Vale inline comments" + # Post as a PR review with inline comments + jq -n \ + --arg body "**Vale found ${VALE_COUNT} issue(s).** See inline comments below." \ + --argjson comments "$COMMENTS_JSON" \ + '{"body": $body, "event": "COMMENT", "comments": $comments}' \ + | gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews \ + --input - 2>&1 + else + echo "No Vale issues found" + fi - name: Get PR diff id: diff @@ -98,7 +133,7 @@ jobs: echo "Diff saved to /tmp/pr-diff.txt" wc -l /tmp/pr-diff.txt - - name: Run doc-pr review + - name: Run editorial review if: steps.changed-files.outputs.count > 0 uses: anthropics/claude-code-action@v1 env: @@ -109,7 +144,7 @@ jobs: show_full_output: true prompt: | You are a documentation reviewer. Your ONLY job is to: - 1. Read pre-computed Vale results and PR diff + 1. Read the PR diff and changed files 2. Do a brief editorial review 3. Post a formatted review comment to the PR @@ -117,14 +152,14 @@ jobs: - Repository: ${{ github.repository }} - PR number: ${{ github.event.pull_request.number }} - Changed files: ${{ steps.changed-files.outputs.files }} - - Vale results are at: /tmp/vale-results.txt + - Vale issues: ${{ steps.vale.outputs.vale_count }} (already posted as inline comments) - PR diff is at: /tmp/pr-diff.txt INSTRUCTIONS: - Step 1: Read /tmp/vale-results.txt to get the Vale linting results. + Step 1: Read /tmp/pr-diff.txt to see what changed. Then read each changed file to understand context. - Step 2: Read /tmp/pr-diff.txt to see what changed. Then read each changed file to understand context. Do a brief editorial review focusing on: + Step 2: Do a brief editorial review of ONLY added/modified lines, focusing on: - Voice: passive voice, first person, impersonal phrases - Clarity: hard-to-parse sentences, ambiguous references - Surface: wordiness, redundancy @@ -133,14 +168,12 @@ jobs: ## Documentation PR Review - ### Vale Linting - (list Vale issues as bullet points: **Line N**: Message. Suggested fix: "...") - ### Editorial Review (list editorial issues as bullet points: **Category** — Line N: description. Suggested fix: "...") + (if no issues found, write "No editorial issues found.") ### Summary - N Vale issues, N editorial suggestions across N files. + N Vale issues (see inline comments), N editorial suggestions across N files. --- **What to do next:**