From 27d36e4f9e124ed03db877cd164f489078398da2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Mon, 25 May 2026 14:23:47 +0200 Subject: [PATCH] Add postCodeReviewResults.sh to claude-review-toolkit Centralises the violations post-processing loop currently duplicated across Expensify/App, Expensify/Auth, and Expensify/Web-Expensify's claude-review.yml workflows. The script reads STRUCTURED_OUTPUT from env, adds a +1 reaction when there are no violations, and otherwise posts one inline comment per violation via createInlineComment.sh. --- .../actions/claude-review-toolkit/README.md | 1 + .../scripts/postCodeReviewResults.sh | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100755 .github/actions/claude-review-toolkit/scripts/postCodeReviewResults.sh diff --git a/.github/actions/claude-review-toolkit/README.md b/.github/actions/claude-review-toolkit/README.md index 79ebe08..4e876e7 100644 --- a/.github/actions/claude-review-toolkit/README.md +++ b/.github/actions/claude-review-toolkit/README.md @@ -44,6 +44,7 @@ Caller repos must ship a `.claude/skills/coding-standards/rules/` directory with | `addPrReaction.sh` | ` ` | Adds a reaction (`+1`, `-1`, `laugh`, `confused`, `heart`, `hooray`, `rocket`, `eyes`) to the PR. | | `removePrReaction.sh` | ` ` | Removes the matching reaction authored by `` (typically `github-actions[bot]`). Idempotent. | | `createInlineComment.sh` | ` ` | Posts an inline review comment. Requires `GITHUB_REPOSITORY`, `GH_TOKEN`, and `ALLOWED_RULES_FILE` in env. The body must reference a rule tag matching `[A-Z]+(-[A-Z]+)*-[0-9]+` (e.g. `PERF-1`) that is present in the allowlist; otherwise the comment is rejected. | +| `postCodeReviewResults.sh` | `` | Posts the result of a Claude code review. With no violations, adds a `+1` reaction to the PR; with violations, posts one inline comment per violation. Reads the JSON output from env `STRUCTURED_OUTPUT`. Requires `GH_TOKEN`, `GITHUB_REPOSITORY`, and `ALLOWED_RULES_FILE` in env. Individual comment failures are swallowed so one rejected comment does not kill the loop. | | `extractAllowedRules.sh` | ` ` | Walks `` for `.md` rule files and writes their `ruleId:` tags to ``. Invoked automatically by the action; rarely called directly. | ## Schema extension diff --git a/.github/actions/claude-review-toolkit/scripts/postCodeReviewResults.sh b/.github/actions/claude-review-toolkit/scripts/postCodeReviewResults.sh new file mode 100755 index 0000000..4f97b17 --- /dev/null +++ b/.github/actions/claude-review-toolkit/scripts/postCodeReviewResults.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Post the result of a Claude code review. +# With no violations: adds a "+1" reaction to the PR. +# With violations: posts one inline comment per violation parsed from $STRUCTURED_OUTPUT. +# Usage: postCodeReviewResults.sh +# Env: STRUCTURED_OUTPUT (JSON from claude-code-action), GH_TOKEN, GITHUB_REPOSITORY, ALLOWED_RULES_FILE +set -eu + +if [[ $# -lt 1 ]]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +if ! [[ "$1" =~ ^[0-9]+$ ]]; then + echo "Error: PR_NUMBER must be a positive integer" >&2 + exit 1 +fi + +if [[ -z "${STRUCTURED_OUTPUT:-}" ]]; then + echo "::error::Claude Code Action returned empty structured output" >&2 + exit 1 +fi + +readonly PR_NUMBER="$1" + +COUNT=$(echo "$STRUCTURED_OUTPUT" | jq '.violations | length') +readonly COUNT + +if [[ "$COUNT" -eq 0 ]]; then + addPrReaction.sh "$PR_NUMBER" "+1" +else + echo "$STRUCTURED_OUTPUT" | jq -c '.violations[]' | while IFS= read -r violation; do + PATH_ARG=$(echo "$violation" | jq -r '.path') + BODY_ARG=$(echo "$violation" | jq -r '.body') + LINE_ARG=$(echo "$violation" | jq -r '.line') + createInlineComment.sh "$PR_NUMBER" "$PATH_ARG" "$BODY_ARG" "$LINE_ARG" || true + done +fi