Skip to content

Repair: pygal for violin-basic (attempt 3) #1182

Repair: pygal for violin-basic (attempt 3)

Repair: pygal for violin-basic (attempt 3) #1182

Workflow file for this run

name: "Impl: Repair"
run-name: "Repair: ${{ inputs.library }} for ${{ inputs.specification_id }} (attempt ${{ inputs.attempt }})"
# Repairs a rejected implementation based on AI feedback
# Triggered by impl-review.yml when ai-rejected label is added
on:
workflow_dispatch:
inputs:
pr_number:
description: "PR number to repair"
required: true
type: string
specification_id:
description: "The specification ID"
required: true
type: string
library:
description: "The library to repair"
required: true
type: string
attempt:
description: "Current attempt number (1, 2, or 3)"
required: true
type: string
env:
DEPS_matplotlib: "matplotlib>=3.9.0 numpy>=1.26.0"
DEPS_seaborn: "seaborn>=0.13.0 matplotlib>=3.9.0 numpy>=1.26.0"
DEPS_plotly: "plotly>=5.18.0 kaleido>=0.2.1 numpy>=1.26.0"
DEPS_bokeh: "bokeh>=3.4.0 numpy>=1.26.0 selenium>=4.15.0 webdriver-manager>=4.0.0"
DEPS_altair: "altair>=5.2.0 vl-convert-python>=1.3.0 numpy>=1.26.0"
DEPS_plotnine: "plotnine>=0.13.0 numpy>=1.26.0"
DEPS_pygal: "pygal>=3.0.0 cairosvg>=2.7.0"
DEPS_highcharts: "highcharts-core>=1.10.0 numpy>=1.26.0 selenium>=4.15.0 webdriver-manager>=4.0.0"
DEPS_letsplot: "lets-plot>=4.5.0"
jobs:
repair:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
actions: write
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Checkout PR branch
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BRANCH=$(gh pr view ${{ inputs.pr_number }} --json headRefName -q '.headRefName')
echo "branch=$BRANCH" >> $GITHUB_ENV
git fetch origin "$BRANCH"
git checkout "$BRANCH"
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.14'
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Get library dependencies
id: deps
run: |
DEPS_VAR="DEPS_${{ inputs.library }}"
DEPS="${!DEPS_VAR}"
echo "deps=$DEPS" >> $GITHUB_OUTPUT
- name: Install dependencies
run: |
uv venv .venv
source .venv/bin/activate
uv pip install ${{ steps.deps.outputs.deps }} pandas>=2.2.0 ruff Pillow>=10.0.0
- name: Setup Chrome for Highcharts
if: inputs.library == 'highcharts'
uses: browser-actions/setup-chrome@v2
with:
chrome-version: stable
- name: Extract AI feedback from PR
id: feedback
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
FEEDBACK=$(gh pr view ${{ inputs.pr_number }} --json comments -q '
[.comments[] | select(.body | contains("AI Review"))] | last | .body
' 2>/dev/null || echo "")
if [ -z "$FEEDBACK" ]; then
FEEDBACK="No specific feedback available. Review the implementation against the spec."
fi
echo "$FEEDBACK" > /tmp/ai_feedback.md
- name: Remove ai-rejected label
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr edit ${{ inputs.pr_number }} --remove-label "ai-rejected" 2>/dev/null || true
- name: Run Claude Code to repair implementation
id: claude
continue-on-error: true
timeout-minutes: 45
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
claude_args: "--model opus"
allowed_bots: '*'
prompt: |
Read `prompts/workflow-prompts/impl-repair-claude.md` and follow those instructions.
Variables for this run:
- LIBRARY: ${{ inputs.library }}
- SPEC_ID: ${{ inputs.specification_id }}
- ATTEMPT: ${{ inputs.attempt }}
- BRANCH: ${{ env.branch }}
- name: Retry Claude (on failure)
if: steps.claude.outcome == 'failure'
id: claude_retry
timeout-minutes: 45
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
claude_args: "--model opus"
allowed_bots: '*'
prompt: |
Read `prompts/workflow-prompts/impl-repair-claude.md` and follow those instructions.
Variables for this run:
- LIBRARY: ${{ inputs.library }}
- SPEC_ID: ${{ inputs.specification_id }}
- ATTEMPT: ${{ inputs.attempt }}
- BRANCH: ${{ env.branch }}
- name: Process repaired image
if: success()
env:
SPEC_ID: ${{ inputs.specification_id }}
LIBRARY: ${{ inputs.library }}
run: |
IMPL_DIR="plots/${SPEC_ID}/implementations"
if [ ! -f "$IMPL_DIR/plot.png" ]; then
echo "::warning::No plot.png found after repair"
exit 0
fi
source .venv/bin/activate
# Process PNG: optimize and create thumbnail
python -m core.images process \
"$IMPL_DIR/plot.png" \
"$IMPL_DIR/plot.png" \
"$IMPL_DIR/plot_thumb.png"
echo "::notice::Processed images: optimized + thumbnail created"
ls -la "$IMPL_DIR/"
- name: Upload repaired plot to GCS staging
if: success()
env:
GCS_CREDENTIALS: ${{ secrets.GCS_CREDENTIALS }}
SPEC_ID: ${{ inputs.specification_id }}
LIBRARY: ${{ inputs.library }}
run: |
IMPL_DIR="plots/${SPEC_ID}/implementations"
STAGING_PATH="gs://pyplots-images/staging/${SPEC_ID}/${LIBRARY}"
if [ -z "$GCS_CREDENTIALS" ]; then
echo "::warning::GCS_CREDENTIALS not configured"
exit 0
fi
echo "$GCS_CREDENTIALS" > /tmp/gcs-key.json
gcloud auth activate-service-account --key-file=/tmp/gcs-key.json
if [ -f "$IMPL_DIR/plot.png" ]; then
gsutil cp "$IMPL_DIR/plot.png" "${STAGING_PATH}/plot.png"
gsutil acl ch -u AllUsers:R "${STAGING_PATH}/plot.png" 2>/dev/null || true
fi
if [ -f "$IMPL_DIR/plot_thumb.png" ]; then
gsutil cp "$IMPL_DIR/plot_thumb.png" "${STAGING_PATH}/plot_thumb.png"
gsutil acl ch -u AllUsers:R "${STAGING_PATH}/plot_thumb.png" 2>/dev/null || true
fi
if [ -f "$IMPL_DIR/plot.html" ]; then
gsutil cp "$IMPL_DIR/plot.html" "${STAGING_PATH}/plot.html"
gsutil acl ch -u AllUsers:R "${STAGING_PATH}/plot.html" 2>/dev/null || true
fi
rm -f /tmp/gcs-key.json
- name: Post repair status
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr comment ${{ inputs.pr_number }} --body "## :wrench: Repair Attempt ${{ inputs.attempt }}/3
Applied fixes based on AI review feedback.
**Status:** Repair completed, re-triggering review...
---
:robot: *[impl-repair](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})*"
- name: Re-trigger review
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUM: ${{ inputs.pr_number }}
run: |
# Use repository_dispatch as workaround for workflow_dispatch caching issue
gh api repos/${{ github.repository }}/dispatches \
-f event_type=review-pr \
-f "client_payload[pr_number]=$PR_NUM"
echo "::notice::Triggered impl-review.yml via repository_dispatch for PR #$PR_NUM"