Skip to content

Commit cd39036

Browse files
committed
Refactor fix command
1 parent 1d10815 commit cd39036

File tree

6 files changed

+437
-187
lines changed

6 files changed

+437
-187
lines changed

.github/workflows/fix-remote-pr.yml

Lines changed: 35 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -154,46 +154,26 @@ jobs:
154154
cat /tmp/classification.json
155155
echo ""
156156
157-
# Extract fields from JSON
157+
# Extract fields from JSON for validation
158158
FAILURE_TYPE=$(jq -r '.failure_type' /tmp/classification.json)
159159
CONFIDENCE=$(jq -r '.confidence' /tmp/classification.json)
160-
FAILED_CHECK_NAMES=$(jq -r '.failed_check_names | join(",")' /tmp/classification.json)
161160
REASONING=$(jq -r '.reasoning' /tmp/classification.json)
162-
RECOMMENDED_ACTION=$(jq -r '.recommended_action' /tmp/classification.json)
163161
164162
# Output to GitHub Actions
165163
echo "failure-type=$FAILURE_TYPE" >> $GITHUB_OUTPUT
166164
echo "confidence=$CONFIDENCE" >> $GITHUB_OUTPUT
167-
echo "failed-check-names=$FAILED_CHECK_NAMES" >> $GITHUB_OUTPUT
168165
{
169166
echo "reasoning<<EOF_REASONING"
170167
echo "$REASONING"
171168
echo "EOF_REASONING"
172169
} >> $GITHUB_OUTPUT
173-
{
174-
echo "recommended-action<<EOF_ACTION"
175-
echo "$RECOMMENDED_ACTION"
176-
echo "EOF_ACTION"
177-
} >> $GITHUB_OUTPUT
178-
env:
179-
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
180-
GH_TOKEN: ${{ secrets.ORG_ACCESS_TOKEN }}
181-
182-
- name: Prepare for agent execution
183-
id: prepare
184-
run: |
185-
FAILURE_TYPE="${{ steps.analyze.outputs.failure-type }}"
186-
CONFIDENCE="${{ steps.analyze.outputs.confidence }}"
187-
REASONING="${{ steps.analyze.outputs.reasoning }}"
188170
171+
# Check if we should skip (unknown failure type)
189172
echo "Classification: $FAILURE_TYPE (confidence: $CONFIDENCE)"
190-
# Use printf with %s to safely output reasoning without bash interpreting special chars
191173
printf 'Reasoning: %s\n' "$REASONING"
192174
193-
# Skip unknown failure types
194175
if [ "$FAILURE_TYPE" = "unknown" ]; then
195176
echo "Failure type is unknown - skipping automated fix attempt"
196-
printf 'Reasoning: %s\n' "$REASONING"
197177
echo "should-skip=true" >> $GITHUB_OUTPUT
198178
exit 0
199179
fi
@@ -202,94 +182,76 @@ jobs:
202182
case "$FAILURE_TYPE" in
203183
merge_conflict|test|lint|security|build)
204184
echo "✓ Failure type '$FAILURE_TYPE' is supported"
185+
echo "should-skip=false" >> $GITHUB_OUTPUT
205186
;;
206187
*)
207188
echo "Unsupported failure type: $FAILURE_TYPE - skipping"
208189
echo "should-skip=true" >> $GITHUB_OUTPUT
209190
exit 0
210191
;;
211192
esac
212-
213-
# Copy skills to target-repo so agent can use them
214-
echo "Copying Claude Code skills to target repository..."
215-
cp -r bot-repo/.claude target-repo/.claude
216-
echo "✓ Skills copied to target-repo/.claude/"
217-
218-
# LAYER 1: Add bot files to git's local exclude list (safety net)
219-
echo "Excluding bot files from git..."
220-
{
221-
echo "# AI Engineering Bot temporary files - DO NOT COMMIT"
222-
echo ".claude/"
223-
echo ".pr-context.json"
224-
} >> target-repo/.git/info/exclude
225-
echo "✓ Bot files added to .git/info/exclude"
226-
227-
echo "should-skip=false" >> $GITHUB_OUTPUT
228-
echo "Ready to apply fixes using skills"
193+
env:
194+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
195+
GH_TOKEN: ${{ secrets.ORG_ACCESS_TOKEN }}
229196

230197
- name: Install Claude Code CLI
231-
if: steps.prepare.outputs.should-skip != 'true'
198+
if: steps.analyze.outputs.should-skip != 'true'
232199
run: |
233200
curl -fsSL https://claude.ai/install.sh | bash
234201
echo "$HOME/.local/bin" >> $GITHUB_PATH
235202
236203
- name: Setup Python for Agent SDK
237-
if: steps.prepare.outputs.should-skip != 'true'
204+
if: steps.analyze.outputs.should-skip != 'true'
238205
uses: actions/setup-python@v6
239206
with:
240207
python-version-file: bot-repo/.python-version
241208

242209
- name: Install uv (Python package manager)
243-
if: steps.prepare.outputs.should-skip != 'true'
210+
if: steps.analyze.outputs.should-skip != 'true'
244211
run: |
245212
curl -LsSf https://astral.sh/uv/install.sh | sh
246213
echo "$HOME/.local/bin" >> $GITHUB_PATH
247214
248215
- name: Authenticate to Google Cloud
249-
if: steps.prepare.outputs.should-skip != 'true'
216+
if: steps.analyze.outputs.should-skip != 'true'
250217
uses: google-github-actions/auth@v3
251218
with:
252219
workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
253220
service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
254221
continue-on-error: true
255222

256223
- name: Set up Cloud SDK
257-
if: steps.prepare.outputs.should-skip != 'true'
224+
if: steps.analyze.outputs.should-skip != 'true'
258225
uses: google-github-actions/setup-gcloud@v3
259226
continue-on-error: true
260227

261-
- name: Apply AI fixes using Claude Agent SDK with Skills
262-
if: steps.prepare.outputs.should-skip != 'true'
228+
- name: Apply AI fixes using Claude Agent SDK
229+
if: steps.analyze.outputs.should-skip != 'true'
263230
id: fix
264231
working-directory: target-repo
265232
run: |
266-
# Apply fixes using skills from .claude/skills/
233+
# Apply fixes using the simplified fix command
234+
# All preparation (skills copying, logs fetching, PR details) is now done in Python
267235
aieng-bot fix \
268236
--repo "${{ github.event.inputs.target_repo }}" \
269-
--pr-number "${{ github.event.inputs.pr_number }}" \
270-
--pr-title "${{ steps.pr-details.outputs.pr-title }}" \
271-
--pr-author "${{ steps.pr-details.outputs.pr-author }}" \
272-
--pr-url "https://github.com/${{ github.event.inputs.target_repo }}/pull/${{ github.event.inputs.pr_number }}" \
273-
--head-ref "${{ steps.pr-details.outputs.head-ref }}" \
274-
--base-ref "${{ steps.pr-details.outputs.base-ref }}" \
275-
--failure-type "${{ steps.analyze.outputs.failure-type }}" \
276-
--failed-check-names "${{ steps.analyze.outputs.failed-check-names }}" \
277-
--failure-logs-file ".failure-logs.txt" \
237+
--pr "${{ github.event.inputs.pr_number }}" \
238+
--cls /tmp/classification.json \
239+
--cwd "$(pwd)" \
278240
--workflow-run-id "${{ github.run_id }}" \
279-
--github-run-url "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
280-
--cwd "$(pwd)"
241+
--github-run-url "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
281242
env:
282243
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
244+
GH_TOKEN: ${{ secrets.ORG_ACCESS_TOKEN }}
283245
continue-on-error: false
284246

285247
- name: Verify bot files not committed (Layer 3)
286-
if: steps.prepare.outputs.should-skip != 'true'
248+
if: steps.analyze.outputs.should-skip != 'true'
287249
working-directory: target-repo
288250
run: |
289251
echo "Verifying bot temporary files are not staged or committed..."
290252
291253
# Check if bot files are in staging area
292-
BOT_FILES_STAGED=$(git diff --cached --name-only | grep -E "^\.claude/|^\.pr-context\.json$" || true)
254+
BOT_FILES_STAGED=$(git diff --cached --name-only | grep -E "^\.claude/|^\.pr-context\.json$|^\.failure-logs\.txt$" || true)
293255
294256
if [ -n "$BOT_FILES_STAGED" ]; then
295257
echo "❌ ERROR: Bot temporary files found in staging area!"
@@ -302,7 +264,7 @@ jobs:
302264
303265
# Check if bot files exist in any unpushed commits
304266
BASE_REF="${{ steps.pr-details.outputs.base-ref }}"
305-
BOT_FILES_COMMITTED=$(git diff --name-only "origin/$BASE_REF...HEAD" | grep -E "^\.claude/|^\.pr-context\.json$" || true)
267+
BOT_FILES_COMMITTED=$(git diff --name-only "origin/$BASE_REF...HEAD" | grep -E "^\.claude/|^\.pr-context\.json$|^\.failure-logs\.txt$" || true)
306268
307269
if [ -n "$BOT_FILES_COMMITTED" ]; then
308270
echo "⚠️ WARNING: Bot temporary files found in commits!"
@@ -314,10 +276,8 @@ jobs:
314276
315277
echo "✓ No bot files found in staging area or commits"
316278
317-
# Cleanup bot files from working directory
318-
echo "Cleaning up bot temporary files..."
319-
rm -rf .claude/ .pr-context.json 2>/dev/null || true
320-
echo "✓ Bot files cleaned up"
279+
# Note: Cleanup is now handled by the fix command itself
280+
echo "✓ Bot files cleanup handled by fix command"
321281
322282
- name: Upload trace to GCS
323283
if: always()
@@ -447,7 +407,7 @@ jobs:
447407
continue-on-error: true
448408

449409
- name: Check for changes and push
450-
if: steps.prepare.outputs.should-skip != 'true'
410+
if: steps.analyze.outputs.should-skip != 'true'
451411
id: push-fixes
452412
working-directory: target-repo
453413
run: |
@@ -469,12 +429,16 @@ jobs:
469429
git config user.email "aieng-bot@vectorinstitute.ai"
470430
git add -A
471431
432+
# Extract failure info from classification for commit message
433+
FAILURE_TYPE=$(jq -r '.failure_type' /tmp/classification.json)
434+
FAILED_CHECKS=$(jq -r '.failed_check_names | join(", ")' /tmp/classification.json)
435+
472436
cat > /tmp/commit-message.txt <<EOF
473-
Fix ${{ steps.analyze.outputs.failure-type }} failures after dependency updates
437+
Fix ${FAILURE_TYPE} failures after dependency updates
474438
475439
Automated fixes applied by AI Engineering Maintenance Bot
476440
477-
Fixes: ${{ steps.analyze.outputs.failed-check-names }}
441+
Fixes: ${FAILED_CHECKS}
478442
479443
Co-authored-by: AI Engineering Maintenance Bot <aieng-bot@vectorinstitute.ai>
480444
EOF
@@ -497,7 +461,9 @@ jobs:
497461
run: |
498462
REPO="${{ github.event.inputs.target_repo }}"
499463
PR_NUMBER="${{ github.event.inputs.pr_number }}"
500-
FAILURE_TYPE="${{ steps.analyze.outputs.failure-type }}"
464+
465+
# Extract failure type from classification
466+
FAILURE_TYPE=$(jq -r '.failure_type' /tmp/classification.json)
501467
502468
# Read the fix summary if available
503469
FIX_SUMMARY=""

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,4 @@ CLAUDE.md
5050

5151
aieng_bot.egg-info/
5252
coverage.xml
53+
classification.json

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ ignore = [
130130
"E501", # line too long
131131
"D203", # 1 blank line required before class docstring
132132
"D213", # Multi-line docstring summary should start at the second line
133+
"D301", # Use `r"""` if any backslashes in a docstring (conflicts with Click formatting)
133134
"PLR2004", # Replace magic number with named constant
134135
"PLR0913", # Too many arguments
135136
"COM812", # Missing trailing comma

src/aieng_bot/_cli/commands/classify.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,13 +281,14 @@ def classify(
281281
github_token: str | None,
282282
anthropic_api_key: str | None,
283283
) -> None:
284-
r"""Classify PR failure type using Claude AI.
284+
"""Classify PR failure type.
285285
286286
Analyzes a GitHub PR to determine the type of CI/CD failure
287287
(test, lint, security, build, merge_conflict, or unknown).
288288
289289
\b
290290
Examples:
291+
\b
291292
# Rich formatted output (default)
292293
aieng-bot classify --repo VectorInstitute/aieng-template-mvp --pr 17
293294
\b

0 commit comments

Comments
 (0)