mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-16 17:11:04 -07:00
feat(skills): add async-pr-review skill
This commit is contained in:
36
.gemini/skills/async-pr-review/SKILL.md
Normal file
36
.gemini/skills/async-pr-review/SKILL.md
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
name: async-pr-review
|
||||
description: Trigger this skill when the user wants to start an asynchronous PR review, run background checks on a PR, or check the status of a previously started async PR review.
|
||||
---
|
||||
|
||||
# Async PR Review
|
||||
|
||||
This skill provides a set of tools to asynchronously review a Pull Request. It will create a background job to run the project's preflight checks, execute Gemini-powered test plans, and perform a comprehensive code review using custom prompts.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. **Determine Action**: Establish whether the user wants to start a new async review or check the status of an existing one.
|
||||
* If the user says "start an async review for PR #123" or similar, proceed to **Start Review**.
|
||||
* If the user says "check the status of my async review for PR #123" or similar, proceed to **Check Status**.
|
||||
|
||||
### Start Review
|
||||
|
||||
If the user wants to start a new async PR review:
|
||||
|
||||
1. Ask the user for the PR number if they haven't provided it.
|
||||
2. Execute the `async-review.sh` script, passing the PR number as the first argument:
|
||||
```bash
|
||||
.gemini/skills/async-pr-review/scripts/async-review.sh <PR_NUMBER>
|
||||
```
|
||||
3. The script will start the review tasks in the background and print out the paths to the logs. Inform the user that the tasks have started successfully.
|
||||
|
||||
### Check Status
|
||||
|
||||
If the user wants to check the status or view the final assessment of a previously started async review:
|
||||
|
||||
1. Ask the user for the PR number if they haven't provided it.
|
||||
2. Execute the `check-async-review.sh` script, passing the PR number as the first argument:
|
||||
```bash
|
||||
.gemini/skills/async-pr-review/scripts/check-async-review.sh <PR_NUMBER>
|
||||
```
|
||||
3. This script will launch a live status dashboard. Once all tasks are complete, it will automatically query a new instance of Gemini for a final assessment and provide a recommendation on whether to approve the PR. Let the script run in the user's terminal.
|
||||
54
.gemini/skills/async-pr-review/scripts/async-review.sh
Executable file
54
.gemini/skills/async-pr-review/scripts/async-review.sh
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/bash
|
||||
pr_number=$1
|
||||
if [[ -z "$pr_number" ]]; then
|
||||
echo "Usage: async-review <pr_number>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
base_dir="$HOME/dev/main"
|
||||
pr_dir="$HOME/dev/pr-$pr_number"
|
||||
target_dir="$pr_dir/worktree"
|
||||
log_dir="$pr_dir/logs"
|
||||
|
||||
if [[ ! -d "$base_dir" ]]; then
|
||||
echo "❌ Base directory $base_dir not found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$base_dir" || exit 1
|
||||
echo "📡 Fetching PR #$pr_number..."
|
||||
# Fetch the PR into a local branch to avoid detached head / namespace issues
|
||||
git fetch origin -f "pull/$pr_number/head:pr-$pr_number"
|
||||
|
||||
if [[ ! -d "$target_dir" ]]; then
|
||||
echo "🧹 Pruning missing worktrees..."
|
||||
git worktree prune
|
||||
echo "🌿 Creating worktree in $target_dir..."
|
||||
mkdir -p "$pr_dir"
|
||||
git worktree add "$target_dir" "pr-$pr_number"
|
||||
else
|
||||
echo "🌿 Worktree already exists."
|
||||
fi
|
||||
|
||||
cd "$target_dir" || exit 1
|
||||
mkdir -p "$log_dir"
|
||||
|
||||
echo "🚀 Launching background tasks. Logs saving to: $log_dir"
|
||||
|
||||
echo " ↳ [1/3] Starting npm run preflight..."
|
||||
rm -f "$log_dir/preflight.exit"
|
||||
{ npm run preflight > "$log_dir/preflight.log" 2>&1; echo $? > "$log_dir/preflight.exit"; } &
|
||||
|
||||
GEMINI_CMD="$HOME/.gcli/nightly/node_modules/.bin/gemini"
|
||||
|
||||
echo " ↳ [2/3] Starting Gemini code review..."
|
||||
rm -f "$log_dir/review.exit"
|
||||
{ "$GEMINI_CMD" --approval-mode=yolo /review-frontend "$pr_number" > "$log_dir/review.md" 2>&1; echo $? > "$log_dir/review.exit"; } &
|
||||
|
||||
echo " ↳ [3/3] Starting Gemini test execution..."
|
||||
rm -f "$log_dir/test-execution.exit"
|
||||
{ "$GEMINI_CMD" --approval-mode=yolo "Analyze the diff for PR $pr_number using 'gh pr diff $pr_number'. Formulate a test plan for the changes, and then autonomously execute the test commands in the terminal to verify the feature. Do not ask for user confirmation, just run the tests and log the results." > "$log_dir/test-execution.log" 2>&1; echo $? > "$log_dir/test-execution.exit"; } &
|
||||
|
||||
echo "✅ All tasks dispatched!"
|
||||
echo "You can monitor progress with: tail -f $log_dir/*.log"
|
||||
echo "Read your review later at: $log_dir/review.md"
|
||||
93
.gemini/skills/async-pr-review/scripts/check-async-review.sh
Executable file
93
.gemini/skills/async-pr-review/scripts/check-async-review.sh
Executable file
@@ -0,0 +1,93 @@
|
||||
#!/bin/bash
|
||||
pr_number=$1
|
||||
|
||||
if [[ -z "$pr_number" ]]; then
|
||||
echo "Usage: check-async-review <pr_number>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_dir="$HOME/dev/pr-$pr_number/logs"
|
||||
GEMINI_CMD="$HOME/.gcli/nightly/node_modules/.bin/gemini"
|
||||
|
||||
if [[ ! -d "$log_dir" ]]; then
|
||||
echo "❌ No logs found for PR #$pr_number in $log_dir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Define the tasks: name|log_file
|
||||
tasks=(
|
||||
"preflight|preflight.log"
|
||||
"review|review.md"
|
||||
"test-execution|test-execution.log"
|
||||
)
|
||||
|
||||
while true; do
|
||||
clear
|
||||
echo "📊 Status for PR #$pr_number in $log_dir"
|
||||
echo "================================================="
|
||||
|
||||
all_done=true
|
||||
|
||||
for task_info in "${tasks[@]}"; do
|
||||
IFS="|" read -r task_name log_file <<< "$task_info"
|
||||
|
||||
file_path="$log_dir/$log_file"
|
||||
exit_file="$log_dir/$task_name.exit"
|
||||
|
||||
if [[ -f "$exit_file" ]]; then
|
||||
# Task is done
|
||||
exit_code=$(cat "$exit_file")
|
||||
if [[ "$exit_code" == "0" ]]; then
|
||||
status="✅ SUCCESS"
|
||||
else
|
||||
status="❌ FAILED (exit code $exit_code)"
|
||||
fi
|
||||
elif [[ -f "$file_path" ]]; then
|
||||
status="⏳ RUNNING"
|
||||
all_done=false
|
||||
else
|
||||
status="➖ NOT STARTED"
|
||||
all_done=false
|
||||
fi
|
||||
|
||||
echo "$status - $task_name"
|
||||
|
||||
if [[ -f "$file_path" ]]; then
|
||||
if [[ "$status" == "⏳ RUNNING" ]]; then
|
||||
# Show what it's currently doing
|
||||
echo " Last output:"
|
||||
tail -n 3 "$file_path" | sed 's/^/ | /'
|
||||
elif [[ "$status" == *"FAILED"* ]]; then
|
||||
# Show the last lines of the error to help debug
|
||||
echo " Error snippet:"
|
||||
tail -n 5 "$file_path" | sed 's/^/ | /'
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
done
|
||||
|
||||
if $all_done; then
|
||||
break
|
||||
fi
|
||||
|
||||
echo "⏳ Waiting 5 seconds before checking again..."
|
||||
sleep 5
|
||||
done
|
||||
|
||||
echo "🎉 All tasks are complete!"
|
||||
echo "🤖 Asking Gemini for final PR assessment..."
|
||||
echo "================================================="
|
||||
|
||||
"$GEMINI_CMD" "I have just completed async tasks for PR $pr_number.
|
||||
|
||||
Here is the code review output:
|
||||
\`\`\`markdown
|
||||
$(cat "$log_dir/review.md" 2>/dev/null)
|
||||
\`\`\`
|
||||
|
||||
Here is the test execution log:
|
||||
\`\`\`
|
||||
$(cat "$log_dir/test-execution.log" 2>/dev/null)
|
||||
\`\`\`
|
||||
|
||||
Please evaluate the results. Tell me if the PR builds successfully, if it passes tests, and if you recommend I approve it based on the review. Keep your answer concise and actionable."
|
||||
Reference in New Issue
Block a user