This skill automatically diagnoses and fixes CI failures for the current branch by fetching GitHub Actions logs, categorizing the failure, applying targeted fixes, and pushing the result.
Usage
/fix-ci # Auto-diagnose and fix
/fix-ci --dry-run # Show what would be fixed without applying
Workflow
Step 1: Fetch CI Failure Details
Determine the current branch:
git branch --show-current
Fetch the latest CI run for this branch:
gh run list --branch <current-branch> --limit 1 --json databaseId,conclusion
- If the latest run has
"conclusion": "failure", fetch the failed logs:gh run view <run-id> --log-failed - If no failed run is found (conclusion is "success" or no runs exist), report "No CI failures found" and stop.
Step 2: Categorize Failure
Parse the failed log output to determine the failure type(s):
- lint: ruff check errors (look for
ruff checkoutput, rule codes like E, F, I, UP, B, SIM) - format: ruff format errors (look for
ruff formatoutput, "would reformat" messages) - type: mypy errors (look for
mypyoutput, type annotation errors like "Incompatible type", "Missing return") - test: pytest failures (look for
pytestoutput, "FAILED" markers, assertion errors) - multiple: if more than one category is detected, fix them in order: format -> lint -> type -> test
Step 3: Apply Fixes
Apply targeted fixes based on the failure category:
For format errors:
ruff format synapse/ tests/
For lint errors:
ruff check --fix synapse/ tests/
For type errors:
- Read the specific mypy error messages from the log
- Identify the file and line number for each error
- Read the source code around the error location
- Apply targeted fixes to the type annotations (add return types, fix incompatible types, add missing imports)
For test failures:
- Read the pytest output to identify failing test names and assertion errors
- Read the failing test code and the source code under test
- Determine whether the fix belongs in the source code or the test
- Apply the targeted fix
After each fix category, run the corresponding check locally to verify before proceeding to the next category.
If --dry-run flag is provided: report what would be fixed for each category but do NOT apply any changes, do NOT commit, and do NOT push.
Step 4: Local Verification
Run all relevant checks to verify the fixes:
ruff check synapse/ tests/
ruff format synapse/ tests/ --check
uv run mypy synapse/
If test failures were involved:
pytest
If any check still fails after the initial fix, attempt one more targeted fix for that category (max 1 retry per category). If it still fails after the retry, proceed to the error handling step.
Step 5: Commit and Push
After all checks pass locally:
-
Stage only modified files (do NOT stage untracked files):
git add -u -
Commit with a descriptive message indicating which categories were fixed:
git commit -m "fix: resolve CI failures (<categories>)"Where
<categories>is a comma-separated list of what was fixed (e.g.,lint, formatortestorformat, lint, type, test). -
Push to the current branch:
git push -
Report a summary of what was fixed, including:
- Which failure categories were detected
- Which files were modified
- Whether all local checks pass
Step 6: Error Handling
- gh CLI not authenticated: If
gh run listfails with an authentication error, report "GitHub CLI is not authenticated. Rungh auth loginfirst." and stop. - Fixes do not resolve the issue: If local verification still fails after one retry per category, report exactly what remains broken (include the error output) and stop. Do NOT commit partial fixes that leave CI in a broken state.
- Never force-push: Always use
git push, nevergit push --forceorgit push --force-with-lease.
Examples
Auto-diagnose and fix all CI failures
/fix-ci
Preview what would be fixed without applying changes
/fix-ci --dry-run
Tool Configuration
This project uses the following CI checks (from pyproject.toml):
Ruff
- Target: Python 3.10
- Line length: 88
- Rules: E, F, I, UP, B, SIM
- Ignored: E501, B008
- Excluded: synapse/proto/a2a_pb2*.py
Mypy
- Strict mode with disallow_untyped_defs
- Tests have relaxed rules (ignore_errors)
- Proto files excluded
Pytest
- asyncio_mode: auto
- Run with:
pytestorpytest tests/ -v