From engineering
Fix failing CI checks on a PR end-to-end — fetch the failing checks and logs (GitHub Actions and any `gh pr checks` check), triage each with the user, diagnose (routing test failures to triage-tests), apply fixes, run local lint/test verification, commit/amend, and push to re-trigger CI. Use when asked to "fix CI", "fix the failing checks", "make the build pass", "fix the red checks", "address CI failures", or "my PR is failing CI". This fixes CHECKS (build/lint/test failures), not review comments — for those use fix-pr-feedback.
How this skill is triggered — by the user, by Claude, or both
Slash command
/engineering:fix-pr-ci-checks [PR-number-or-URL][PR-number-or-URL]This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Fetch the failing CI checks on a PR — GitHub Actions workflows and any check surfaced by `gh pr checks` — triage each failure with the user, diagnose the cause (delegating test failures to `test:triage-tests`), apply fixes, run the matching local linters and tests, commit (amend or follow-up depending on review state), and push to re-trigger CI. Then hand off to `release:read-ci-status --watch`...
Fetch the failing CI checks on a PR — GitHub Actions workflows and any check surfaced by gh pr checks — triage each failure with the user, diagnose the cause (delegating test failures to test:triage-tests), apply fixes, run the matching local linters and tests, commit (amend or follow-up depending on review state), and push to re-trigger CI. Then hand off to release:read-ci-status --watch to confirm the build goes green.
Works for any repo via the gh CLI; derive owner/repo from gh repo view rather than hardcoding.
Scope: failing CI checks, not review comments. If the user wants to address reviewer/bugbot comments, that's the sibling skill fix-pr-feedback. This skill is single-pass and human-in-the-loop: it does not loop, and it does not watch CI to green itself (that's release:read-ci-status's job).
Composition / dependencies:
release:read-ci-status to fetch CI state. Read-only.test:triage-tests (test plugin) to diagnose test failures — it auto-routes E2E/crash/rspec/jest and diagnoses and recommends; it does not fix.fix-pr-feedback (engineering plugin), which addresses review comments. A future orchestrator / ship-practice loops the two to drive a PR both green and feedback-addressed.$ARGUMENTS is provided, use it. Accept either a PR number or a full URL (https://github.com/{owner}/{repo}/pull/{number} — extract owner/repo/number from the URL).gh pr view --json number --jq .number (works when checked out on the PR's branch).
b. If that fails, search by branch name: gh pr list --head $(git branch --show-current) --json number --jq '.[0].number'.{owner}/{repo} from gh repo view --json nameWithOwner --jq .nameWithOwner (or from the URL).gh pr view <N> --json headRefName --jq .headRefNamegit branch --show-current.git checkout <pr-branch> && git pull --ff-only. Do not proceed until on the PR branch — the failing checks were produced against the PR branch's content, and fixes only make sense there.BASE=$(gh pr view <N> --json baseRefName --jq .baseRefName), usually main), then git fetch origin "$BASE" && git log --oneline HEAD..origin/$BASE. If that shows any commits, the branch is behind — rebase it: git rebase origin/$BASE, resolving conflicts before applying fixes. This repo requires branches be up-to-date with main to merge, so the rebase has to happen eventually anyway — do it now, and a failing check is sometimes nothing more than a stale base. If the rebase does not complete cleanly (conflicts, or a nonzero exit leaving the repo mid-rebase), stop and surface it to the user — never edit, commit, or push while mid-rebase. Confirm the rebase finished (git status shows no rebase in progress) before continuing. Do not talk yourself out of it because the failing check looks unrelated: a behind branch can still conflict on shared files (plugin manifests, version bumps, lockfiles, changelogs), and those conflicts surface only on rebase. Do the rebase before the Step 3 fetch; if you rebase after already fetching CI state, re-run the entire Step 3 fetch — a rebase produces new commits and a new CI run, so the prior failing checks/logs are stale. (A rebase rewrites history → the later push needs --force-with-lease. Note: rebasing + force-pushing an approved PR usually dismisses its approvals — re-check reviewDecision in Step 7 afterward, since the PR may no longer be approved.)Prefer composing release:read-ci-status (via the Skill tool) on the PR number to get the current check states — it wraps gh pr checks / gh run view read-only and returns a per-check status table. Otherwise fetch inline:
gh pr checks <N> --repo <owner>/<repo>
gh run view <run-id> --repo <owner>/<repo> --json status,conclusion,jobs,url
gh run view <run-id> --repo <owner>/<repo> --log-failed
(--log-failed prints only the failed steps' logs — far less noise than the full log.)release:read-ci-status for a live snapshot) and stop — there is nothing to fix.Sort every failing check into one of three buckets:
waiting-on-review, required-reviewers, merge-queue, draft-blocked, or similar process gates. → SKIP. Never try to "fix" these with code; they clear when a human or the queue acts.Present a triage table:
| # | Check | Failure type | Diagnosis | Proposed action |
Failure type is code / human-gate / flaky-or-infra. Proposed action is fix / skip / surface (your call).
AI-reviewer checks (e.g. Cursor Bugbot, Copilot) lie quiet, not clean. A
skipping/NEUTRALstate on an AI code-review bot reflects whether its run was gated/neutralized — not whether it found anything. Bugbot routinely readsskippingingh pr checkswhile having fully run and posted high-severity review comments. So never read a neutral/green board as "no findings." Those findings are review comments, not checks — out of scope here. Surface to the user that Bugbot may have left comments and point them at the siblingfix-pr-feedbackskill; do not try to address them in this skill.
Present numbered options (use AskUserQuestion) for how to handle each open failure:
The user may scope by number (e.g. "fix #1 and #3, explain #2, skip #4"). Collect decisions into a fix queue.
test:triage-tests skill (via the Skill tool) — forward the failing report/CI link/spec output verbatim so it can root-cause and classify (code bug vs. test bug vs. flaky vs. environment) before you propose a fix. Do not jump straight to editing code for a test failure; let triage classify first.For each item in the fix queue:
a. Read the relevant file and lines.
b. Diagnose and apply the fix. (For test failures, use the root cause from triage-tests.)
c. Identify which commit in the PR introduced the affected lines (reuse $BASE from Step 2):
git log "origin/$BASE..HEAD" --follow --format="%H %s" -- <file> to find candidate commits.git log "origin/$BASE..HEAD" --oneline for context if needed.
d. Track which files were modified and which commits they belong to.After all fixes are applied, run local verification before pushing — match the linter/tests to the file types and the failing check:
.rb): rubocop <files>.js, .jsx, .ts, .tsx): the project's lint command (e.g. npx eslint <files>); the relevant tests (e.g. npx jest <path>) if a test check failed..md): npx prettier --check <files>For a test fix specifically, re-run the exact failing spec/test locally and confirm it now passes before trusting CI — see the failure go green on your machine first (verify-before-completion: don't push a "fix" you haven't watched pass). If you can't reproduce the failure locally, say so in the triage rather than assuming the fix worked.
gh pr view <N> --json reviewDecision):
git add <files> && git commit --amend --no-edit.--amend only touches HEAD, so do not use it here — it would fold every staged fix into HEAD and misplace them. Instead, stage and create a fixup per originating commit (git add <files-for-that-commit> && git commit --fixup=<sha>), then fold them in with git rebase --autosquash origin/$BASE (a rewrite → push needs --force-with-lease). Commit each commit's fixes separately so each fixup targets the right <sha>.git add <files> && git commit -m "...") so re-reviewers see exactly what changed since approval, instead of rewriting approved history.git push for a new follow-up commit; git push --force-with-lease if you amended or rebased. Pushing re-triggers CI.--force-with-lease lease, or non-fast-forward), stop and surface it — do not proceed to Step 8 and tell the user CI was re-triggered for a commit that never reached the remote. Confirm git rev-parse HEAD matches the remote (git rev-parse @{u}, or re-check the PR head) before continuing.There are no comment replies to post. Instead:
release:read-ci-status <N> --watch (reference the skill by name). Do not watch CI to green yourself — that preserves this skill's single-pass contract and is release:read-ci-status's job.required-reviewers is still red — that clears when a reviewer approves; flaky-integration-test re-ran clean is your call").skipping/NEUTRAL, remind the user that does not mean it had no findings — it may have posted review comments that this skill doesn't touch. Point them at fix-pr-feedback to address those.Summary table:
| # | Check | Failure type | Action | Commit |
Followed by the PR URL and the line: "Run release:read-ci-status <N> --watch to confirm CI goes green."
fix-pr-feedback).Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub blacksam07/agent-skills --plugin engineering