-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathaction.yml
More file actions
221 lines (192 loc) · 11.6 KB
/
action.yml
File metadata and controls
221 lines (192 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
name: Factory Droid Review
description: Automated Code Review for GitHub Pull Requests.
author: Factory
inputs:
factory-api-key:
description: "The API key to run Droid Exec which powers the Review Droid (required)."
required: true
pr-number:
description: "The Pull Request number being reviewed."
required: true
pr-head-sha:
description: "The commit SHA of the Pull Request head branch for correct checkout."
required: true
runs:
using: "composite"
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ inputs.pr-head-sha }}
token: ${{ github.token }}
- name: Install Droid CLI
shell: bash
run: |
curl -fsSL https://app.factory.ai/cli | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
"$HOME/.local/bin/droid" --version
- name: Auto-generate PR description on '@droid fill'
shell: bash
env:
FACTORY_API_KEY: ${{ inputs.factory-api-key }}
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
echo "Checking PR description for @droid fill command..."
# Fetch current PR description
PR_BODY=$(gh pr view ${{ inputs.pr-number }} --repo ${{ github.repository }} --json body -q .body || echo "")
if ! echo "$PR_BODY" | grep -q "@droid fill"; then
echo "No '@droid fill' found in PR description. Skipping description generation."
exit 0
fi
echo "Found '@droid fill' in PR description. Generating detailed description..."
# Check for PR template in common locations
PR_TEMPLATE=""
for template_path in ".github/PULL_REQUEST_TEMPLATE.md" ".github/pull_request_template.md"; do
if [ -f "$template_path" ]; then
PR_TEMPLATE=$(cat "$template_path")
echo "Found PR template at $template_path"
break
fi
done
# Create the entire prompt in a single heredoc with inline variables
cat > pr_description_prompt.txt << EOF
Generate a comprehensive pull request description for PR #${{ inputs.pr-number }}.
Procedure:
- Get PR metadata (title & description): gh pr view ${{ inputs.pr-number }} --repo ${{ github.repository }} --json title,body
- Get existing comments: gh pr view --json comments
- Get diff: gh pr diff
- Get changed files with patches to compute inline positions: gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files --paginate --jq '.[] | {filename,patch}'
Use the PR metadata (title/body) as additional context:
- If the existing description includes notes/context, use it to inform your writeup
- Do not copy any placeholder tokens (e.g., "@droid fill") into the final output
This will help you understand the code changes in detail.
$(if [ -n "$PR_TEMPLATE" ]; then
echo "YOUR TASK: Fill out the following PR template based on the code changes."
echo ""
echo "--- PR TEMPLATE TO FILL ---"
echo "$PR_TEMPLATE"
echo "--- END OF TEMPLATE ---"
echo ""
echo "TEMPLATE INSTRUCTIONS:"
echo "- Fill sections you can verify from the code diff"
echo "- For checklists: only check items verifiable from the code"
echo "- For unverifiable sections: use '[To be filled by author]'"
else
echo "Generate a description with this structure:"
echo ""
echo "## Summary"
echo "A clear 2-3 sentence overview of what this PR accomplishes."
echo ""
echo "## Changes"
echo "- List the main changes made in this PR"
echo "- Group related changes together"
echo "- Reference specific files when relevant"
echo ""
echo "## Implementation Details"
echo "Describe key technical decisions or patterns used (if non-obvious)."
echo ""
echo "## Testing"
echo "- Note any test files added or modified (visible in the diff)"
echo "- Remind that tests should be run locally"
echo ""
echo "## Breaking Changes"
echo "Only include if there are actual breaking changes."
echo ""
echo "## Related Issues"
echo "Link any issues mentioned in the PR or commits (e.g., Fixes #123)."
fi)
IMPORTANT RULES:
1. Fill out the sections based *only* on the actual code diff.
2. Do not make up information. If a section isn't relevant, state that.
3. Be concise and factual.
4. DO NOT include "@droid fill" in the final generated description.
After generating the description, update the PR using:
gh pr edit ${{ inputs.pr-number }} --repo ${{ github.repository }} --body "[YOUR GENERATED DESCRIPTION]"
Make sure to properly escape the description for shell usage.
EOF
echo "Generating PR description..."
droid exec --skip-permissions-unsafe -f pr_description_prompt.txt
echo "PR description updated successfully."
- name: Perform automated code review
shell: bash
env:
FACTORY_API_KEY: ${{ inputs.factory-api-key }}
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
cat > prompt.txt << 'EOF'
You are running automated code review in a GitHub Actions runner. The gh CLI is available and authenticated via GH_TOKEN.
Context:
- Repo: ${{ github.repository }}
- PR Number: ${{ github.event.pull_request.number }}
- PR Head SHA: ${{ github.event.pull_request.head.sha }}
- PR Base SHA: ${{ github.event.pull_request.base.sha }}
Objectives:
1) Re-check existing review comments and reply resolved when addressed.
2) Review the current PR diff and flag only clear, high-severity issues.
3) Leave very short inline comments (1-2 sentences) on changed lines only and a brief summary at the end.
Procedure:
- Get existing comments: gh pr view --json comments
- Get diff: gh pr diff
- Get changed files with patches to compute inline positions: gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files --paginate --jq '.[] | {filename,patch}'
- Compute exact inline anchors for each issue (file path + diff position). Comments MUST be placed inline on the changed line in the diff, not as top-level comments.
- Detect prior top-level "no issues" style comments authored by this bot (match bodies like: "no issues", "No issues found", "LGTM"; include earlier emoji-prefixed variants if present).
- If CURRENT run finds issues and any prior "no issues" comments exist:
- Prefer to remove them to avoid confusion:
- Try deleting top-level issue comments via: gh api -X DELETE repos/${{ github.repository }}/issues/comments/<comment_id>
- If deletion isn't possible, minimize them via GraphQL (minimizeComment) or edit to prefix "[Superseded by new findings]".
- If neither delete nor minimize is possible, reply to that comment: "Superseded: issues were found in newer commits".
- If a previously reported issue appears fixed by nearby changes, reply: This issue appears to be resolved by the recent changes
- Analysis scope (broad but precise):
- Correctness: boundary/off-by-one error.
- Robustness & validation: missing input validation.
- API/contract misuse: wrong parameter order.
- Concurrency & async: race condition due to shared mutable state.
- Performance (evidence-based): N+1 queries.
- Resource management: unclosed file handle.
- Dead/unreachable code that affects behavior.
- Regression risks: breaking existing behavior or tests.
- Accuracy gates:
- Base findings on the current diff and minimal repo context available via gh; avoid speculation.
- Prioritize high-severity/high-confidence; cap at 10 comments.
- If confidence is low, ask a clarifying question rather than asserting an issue.
- Do not flag purely stylistic or preference-only concerns.
- Deduplication policy:
- Never repeat or re-raise an issue previously highlighted by this bot on this PR, regardless of whether the thread is marked resolved or unresolved.
- Do not create a new comment for a previously reported issue; if needed, reply in the existing thread with a brief status update (e.g., "Resolved ...") or skip.
Commenting rules:
- Max 10 inline comments total; prioritize the most critical issues
- One issue per comment; place on the exact changed line
- All issue comments MUST be inline (anchored to a file and line/position in the PR diff)
- Natural tone, specific and actionable; do not mention automated or high-confidence
- Tone: write like a junior developer who defers to the PR author; be polite and tentative, avoid authoritative language, and prefer concise, respectful phrasing.
- Confidence: for each potential issue, internally assess confidence as High/Medium/Low.
- Low confidence: phrase the comment as a question (e.g., "I noticed the code does X — did you mean to Y?") and keep it brief.
- Medium/High confidence: state the issue directly and concretely.
- False positives are very undesirable: only surface an issue when you are fairly confident it is valid; when uncertain, prefer a single clarifying question over a definitive claim.
- Only propose an exact code change (e.g., a concrete patch/suggestion) when you are absolutely certain the change is correct and safe; otherwise do not suggest a code change—only describe the issue succinctly.
- No speculative or stylistic suggestions; focus strictly on definitive fixes to high-severity issues.
Submission:
- If there are NO issues to report and an existing top-level comment indicating "no issues" already exists (e.g., "no issues", "No issues found", "LGTM"), do NOT submit another comment. Skip submission to avoid redundancy.
- If there are NO issues to report and NO prior "no issues" comment exists, submit one brief summary comment noting no issues.
- If there ARE issues to report and a prior "no issues" comment exists, ensure that prior comment is deleted/minimized/marked as superseded before submitting the new review.
- If there ARE issues to report, submit ONE review containing ONLY inline comments plus an optional concise summary body. Use the GitHub Reviews API to ensure comments are inline:
- Build a JSON array of comments like: [{ "path": "<file>", "position": <diff_position>, "body": "..." }]
- Submit via: gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews -f event=COMMENT -f body="$SUMMARY" -f comments='[$COMMENTS_JSON]'
- Do NOT use: gh pr review --approve or --request-changes
EOF
echo "Running code review analysis..."
droid exec --skip-permissions-unsafe -f prompt.txt
- name: Upload debug artifacts
uses: actions/upload-artifact@v4
with:
name: droid-review-debug-${{ github.run_id }}
path: |
prompt.txt
~/.factory/logs/droid-log-single.log
~/.factory/logs/console.log
~/.factory/sessions/*
if-no-files-found: ignore
retention-days: 7