Skip to content

Commit 9d69892

Browse files
committed
Enable AI code review for test scripts
1 parent 9a401d5 commit 9d69892

9 files changed

Lines changed: 1336 additions & 0 deletions

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ make update
4343
make verify # Runs verify-yaml and verify-update
4444
make verify-yaml # Validates YAML manifests
4545
make verify-update # Ensures generated files are up-to-date
46+
make review-changes # Code review for the changes
4647
```
4748

4849
## Architecture

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ verify-update: update
4545
git diff --exit-code HEAD
4646
.PHONY: verify-update
4747

48+
review-changes:
49+
hack/review.sh
50+
.PHONY: review-changes
51+
4852
clean:
4953
rm -rf _output/
5054
.PHONY: clean

hack/review.sh

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Helper script to run code review using Claude Code's Task tool
4+
#
5+
# Usage:
6+
# ./hack/review.sh # Review current branch vs origin/main
7+
# ./hack/review.sh --pr 1234 # Review specific PR
8+
# ./hack/review.sh --range HEAD~3 # Review last 3 commits
9+
# ./hack/review.sh --files file1.go file2.go # Review specific files
10+
11+
set -euo pipefail
12+
13+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
14+
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
15+
16+
# Default values
17+
DIFF_RANGE="origin/main...HEAD"
18+
PR_NUMBER=""
19+
PR_REMOTE="${PR_REMOTE:-origin}" # Can be overridden via env var (e.g., PR_REMOTE=upstream)
20+
FILES=()
21+
OUTPUT_FILE="${REPO_ROOT}/review-output.json"
22+
23+
function usage() {
24+
cat <<EOF
25+
Usage: $0 [OPTIONS]
26+
27+
Run automated code review using Claude Code agent.
28+
29+
Options:
30+
--pr NUMBER Review a specific pull request number
31+
--range RANGE Git diff range (default: origin/main...HEAD)
32+
--files FILE... Review only specific files
33+
--output FILE Output file for review results (default: ${REPO_ROOT}/review-output.json)
34+
-h, --help Show this help message
35+
36+
Environment Variables:
37+
PR_REMOTE Git remote to use for fetching PRs (default: origin)
38+
Set to 'upstream' if working from a fork
39+
40+
Examples:
41+
$0 # Review current changes vs main
42+
$0 --pr 1234 # Review PR #1234 (uses gh CLI if available)
43+
PR_REMOTE=upstream $0 --pr 1234 # Review PR from upstream remote
44+
$0 --range HEAD~5..HEAD # Review last 5 commits
45+
$0 --files pkg/cvo/cvo.go # Review specific file
46+
47+
Notes:
48+
- PR reviews work best with 'gh' CLI installed: https://cli.github.com/
49+
- Without 'gh', falls back to git fetch (requires proper remote configuration)
50+
- When working from a fork, use PR_REMOTE=upstream to fetch from main repository
51+
EOF
52+
}
53+
54+
# Parse arguments
55+
while [[ $# -gt 0 ]]; do
56+
case $1 in
57+
--pr)
58+
PR_NUMBER="$2"
59+
shift 2
60+
;;
61+
--range)
62+
DIFF_RANGE="$2"
63+
shift 2
64+
;;
65+
--files)
66+
shift
67+
while [[ $# -gt 0 ]] && [[ ! $1 =~ ^-- ]]; do
68+
FILES+=("$1")
69+
shift
70+
done
71+
;;
72+
--output)
73+
OUTPUT_FILE="$2"
74+
shift 2
75+
;;
76+
-h|--help)
77+
usage
78+
exit 0
79+
;;
80+
*)
81+
echo "Unknown option: $1"
82+
usage
83+
exit 1
84+
;;
85+
esac
86+
done
87+
88+
cd "$REPO_ROOT"
89+
90+
# Get diff based on input
91+
if [[ -n "$PR_NUMBER" ]]; then
92+
echo "Fetching PR #${PR_NUMBER}..."
93+
94+
if command -v gh &> /dev/null; then
95+
# Use gh CLI (preferred - shows PR metadata and handles authentication)
96+
echo "Using 'gh' CLI to fetch PR..."
97+
DIFF=$(gh pr diff "$PR_NUMBER" 2>/tmp/gh_err_$$) || {
98+
echo "Error: Failed to fetch PR #${PR_NUMBER} using 'gh' CLI"
99+
echo "Output: $(cat /tmp/gh_err_$$)"
100+
rm -f /tmp/gh_err_$$
101+
exit 1
102+
}
103+
rm -f /tmp/gh_err_$$
104+
FILES_CHANGED=$(gh pr view "$PR_NUMBER" --json files -q '.files[].path') || {
105+
echo "Error: Failed to get PR file list"
106+
exit 1
107+
}
108+
else
109+
# Fallback to git fetch (no gh CLI required)
110+
# Note: This requires 'origin' to be the upstream GitHub repo, not a fork
111+
echo "Note: 'gh' CLI not found. Using git fetch as fallback."
112+
echo "Install 'gh' for better PR integration: https://cli.github.com/"
113+
echo ""
114+
115+
PR_REF="pull/${PR_NUMBER}/head"
116+
echo "Fetching ${PR_REF} from remote '${PR_REMOTE}'..."
117+
118+
if ! git fetch "$PR_REMOTE" "$PR_REF" 2>/dev/null; then
119+
echo ""
120+
echo "Error: Could not fetch PR #${PR_NUMBER} from remote '${PR_REMOTE}'"
121+
echo ""
122+
echo "This can happen if:"
123+
echo " - Your '${PR_REMOTE}' remote is a fork (not the upstream repo)"
124+
echo " - The PR doesn't exist or is closed"
125+
echo " - You don't have network access to the repository"
126+
echo ""
127+
echo "Possible solutions:"
128+
echo " 1. Install 'gh' CLI (recommended): https://cli.github.com/manual/installation"
129+
echo " 2. Add upstream remote: git remote add upstream https://github.com/openshift/cluster-version-operator.git"
130+
echo " Then use: PR_REMOTE=upstream ./hack/review.sh --pr ${PR_NUMBER}"
131+
echo " 3. Manually fetch: git fetch origin pull/${PR_NUMBER}/head:pr-${PR_NUMBER}"
132+
echo " 4. Use git range instead: ./hack/review.sh --range origin/main...HEAD"
133+
exit 1
134+
fi
135+
136+
# Get the base branch (usually main)
137+
BASE_BRANCH=$(git remote show "$PR_REMOTE" 2>/dev/null | grep 'HEAD branch' | cut -d' ' -f5)
138+
BASE_BRANCH=${BASE_BRANCH:-main}
139+
140+
DIFF=$(git diff "${PR_REMOTE}/${BASE_BRANCH}...FETCH_HEAD")
141+
FILES_CHANGED=$(git diff --name-only "${PR_REMOTE}/${BASE_BRANCH}...FETCH_HEAD")
142+
143+
echo "Successfully fetched PR #${PR_NUMBER}"
144+
fi
145+
elif [[ ${#FILES[@]} -gt 0 ]]; then
146+
echo "Reviewing specified files: ${FILES[*]}"
147+
DIFF=$(git diff "$DIFF_RANGE" -- "${FILES[@]}")
148+
FILES_CHANGED=$(printf '%s\n' "${FILES[@]}")
149+
else
150+
echo "Reviewing changes in range: $DIFF_RANGE"
151+
DIFF=$(git diff "$DIFF_RANGE")
152+
FILES_CHANGED=$(git diff --name-only "$DIFF_RANGE")
153+
fi
154+
155+
if [[ -z "$DIFF" ]]; then
156+
echo "No changes found to review."
157+
exit 0
158+
fi
159+
160+
echo "Files changed:"
161+
echo "$FILES_CHANGED"
162+
echo ""
163+
echo "Generating code review..."
164+
echo ""
165+
166+
# Create prompt for the agent
167+
REPO_NAME=$(git remote get-url origin | sed -e 's/.*[:/]\([^/]*\/[^/]*\)\.git$/\1/' -e 's/.*[:/]\([^/]*\/[^/]*\)$/\1/')
168+
169+
REVIEW_PROMPT=$(cat <<REVIEW_PROMPT_EOF
170+
Please perform a code review for the following changes in the ${REPO_NAME} repository.
171+
172+
Files changed:
173+
${FILES_CHANGED}
174+
175+
Git diff:
176+
\`\`\`diff
177+
${DIFF}
178+
\`\`\`
179+
180+
Analyze these changes according to the code review checklist and provide your findings in JSON format as specified in your instructions.
181+
REVIEW_PROMPT_EOF
182+
)
183+
184+
# Save prompt to temp file for claude CLI
185+
PROMPT_FILE=$(mktemp)
186+
echo "$REVIEW_PROMPT" > "$PROMPT_FILE"
187+
188+
echo "=== CODE REVIEW RESULTS ==="
189+
echo ""
190+
191+
# Check if claude CLI is available
192+
if command -v claude &> /dev/null; then
193+
# Use Claude Code CLI if available
194+
claude task --type general-purpose --prompt "@${PROMPT_FILE}" --output "$OUTPUT_FILE"
195+
echo ""
196+
echo "Review saved to: $OUTPUT_FILE"
197+
198+
# Pretty print if jq is available
199+
if command -v jq &> /dev/null && [[ -f "$OUTPUT_FILE" ]]; then
200+
echo ""
201+
echo "=== SUMMARY ==="
202+
jq -r '.summary // "No summary available"' "$OUTPUT_FILE"
203+
echo ""
204+
echo "Verdict: $(jq -r '.verdict // "Unknown"' "$OUTPUT_FILE")"
205+
echo ""
206+
echo "Top Risks:"
207+
jq -r '.top_risks[]? // "None identified"' "$OUTPUT_FILE" | sed 's/^/ - /'
208+
fi
209+
else
210+
# Fallback: Print instructions for manual review
211+
echo "Claude Code CLI not found."
212+
echo ""
213+
echo "To perform the review, copy the following prompt to Claude Code:"
214+
echo "---------------------------------------------------------------"
215+
cat "$PROMPT_FILE"
216+
echo "---------------------------------------------------------------"
217+
fi
218+
219+
rm -f "$PROMPT_FILE"

0 commit comments

Comments
 (0)