CI Fix Failure
DevOps & Securityci-fix-failureCI Fix Failure is an Agent Skill for devops & security published in the camunda/camunda repository on GitHub: a SKILL.md instruction file an AI agent can load to do this task.
Diagnose failing GitHub Actions runs and propose fixes. Use when given a GHA run/job URL, or asked why CI failed, why a job failed, what broke in a run, or to fix a red check on a PR.
How to use this skill
Bring this guide into your coding agent with a prompt tailored to the tool you use.
- Open your project in Codex.
- Copy and paste the prompt below.
- Review files and risks before approving any action.
Inspect the Agent Skill at https://github.com/camunda/camunda/blob/HEAD/.claude/skills/ci-fix-failure/SKILL.md and all supporting files. Report provenance, permissions, scripts, dependencies, and security risks. Propose an exact installation into .agents/skills/ci-fix-failure, but wait for my approval before writing files or running scripts.
Copying this prompt does not install or run the skill. Review third-party files before use.
CI Job Failure Diagnosis
Scope: diagnose + propose. Never apply, commit, or push automatically.
When to use
User shares a GHA URL (actions/runs/<id>, actions/runs/<id>/job/<id>, or pull/<n>/checks?check_run_id=<id>) and asks why it failed.
- No URL → ask. Don't guess from recent context.
- Non-
camunda/camundarepo → tell user this skill assumes monorepo conventions; some fixes won't apply.
Prerequisites
gh auth statusworks againstcamunda/camunda.- CWD is the repo root.
Hard rules — read first
- NEVER increase a job/step timeout. Timeouts are contracts. Fix the slow work, the cache, the runner size, or (one-off
pull_requestonly) rerun. Perci.md§flaky tests: retry within the timeout. - NEVER propose workflow/cache/retry/sizing changes without reading and quoting
ci.md. Silent or contradicts → drop. Use the prescribed composite actions (setup-maven-cache,setup-yarn-cache); cache writes only frommain/stable*.
Procedure
1. Parse URL → run_id (required), job_id (optional), attempt (optional)
For check URLs, check_run_id is the job id. /attempts/<n> → attempt=<n>.
2. Pull run and job metadata
gh run view <run-id> --repo camunda/camunda [--attempt <n>] --json \
status,conclusion,name,headBranch,headSha,event,workflowName,jobs,url,attempt
Default returns the latest attempt — a successful rerun masks the original failure. Always pass --attempt <n> if the URL had one; thread it through Step 5's --log-failed too.
in_progress→ tell user, stop.success→ tell user, ask what they actually want.
3. Identify failing jobs and steps
From jobs[] where conclusion ∈ {failure, cancelled}, find the failing step (steps[].conclusion). If job_id given, restrict to it.
Matrix / cascade: find the upstream root cause first (usually Java Checks, build-*, Unit - Back End). Group identical step failures. Tell user the shortlist before pulling logs.
4. Fetch annotations (mandatory, before logs)
gh api --paginate "/repos/camunda/camunda/check-runs/<job-id>/annotations?per_page=100" \
--jq '.[] | {level: .annotation_level, message: .message, path: .path}'
Watch level: failure:
"exceeded the maximum execution time of 30m0s"→ GHA per-job timeout. Real failure, not transient."<TestClass.method> -- Time elapsed: …s <<< ERROR!"→ the specific test that hung/errored."The operation was canceled."→ cascade noise; ignore alone.
If annotations name a test/file, often enough to skip Step 5.
5. Pull logs for failing step
gh run view <run-id> --repo camunda/camunda --log-failed --job <job-id>
Extract: the error line, ±few lines of context, the step + action that ran it.
headSha == HEAD (git rev-parse HEAD) → Read source files locally; skip gh api.
6. Classify
Pick one primary category per failing job.
- A. Code/test — diff broke something, or test errored/hung. Signals: compile errors, assertion failures, spotless/license, lint, timeout naming a specific slow test. →
references/code-test-failures.md - B. Flaky test — nondeterministic test failed. Signals: passes on rerun, timing/race, network/container in stack. Repo has a flaky-test gate. →
references/flaky-tests.md - C. Workflow/CI config — workflow itself is wrong. Signals: actionlint, missing secret, bad
permissions:, invalid expression, conftest violation. →references/workflow-config.md. Also invokeci-validationonce fix is drafted. - D. CI Infrastructure / transient — runner, network, image, or GitHub misbehaved. Signals:
Error waiting for runner, image pull failure, registry 5xx, OOMKilled with no test signal. →references/infra-transient.md
cancelled is NOT automatically D. In this repo it's usually a per-job timeout triggered by a slow/hung test (Category A). For push / merge_group, every non-success is a real failure — no "transient" merge-queue or base-branch failures exist.
Decide by Step 4 annotations:
- timeout + names a test/step → A
- timeout + step is non-deterministic by history → B
- runner/image/infra signal, no test in picture → D
- nothing useful → default A/B over D on
push/merge_group. Prefer A over B without evidence.
7. Find root cause
Per category:
- A: read failing file at
headSha. If in diff, read the diff; elsegit log -p -- <path>. Compile/format → message names the line. - B: search existing flake issue (
gh issue list --repo camunda/camunda --label kind/flake --search "<test>"); check the flaky-test gate. - C: read workflow under
.github/workflows/. Cross-checkci-workflow-authoring. - D: nothing to fix in code; confirm transient.
Drill until you can name the smallest change that makes the job pass (file, function, line, or workflow key).
8. Gate: read ci.md before any workflow/cache/retry/sizing change
This is a gate, not a suggestion (see Hard Rule 2). Before proposing any change to .github/workflows/, .github/actions/, caching, retries, runner sizing, or timeouts:
- Open docs/monorepo-docs/ci.md and read the relevant section (Caching strategy §"GitHub Actions Cache"; flake/timeout handling §flaky tests; allowed third-party actions; runner labels).
- In the brief's Proposed fix, quote the specific
ci.mdrule that authorizes the change ("perci.md§…setup-yarn-cacheis the prescribed action for NPM caches"). - If
ci.mdis silent on the case, fall back to theci-workflow-authoringskill conventions and say so. Ifci.mdcontradicts your proposal, drop it.
Common contradictions to watch for:
- "increase timeout" — forbidden (Hard Rule 1).
- "add
cache-from: type=ghafor Docker" —ci.md§caching forbids this. - Hand-rolled cache steps when a composite action (
setup-maven-cache,setup-yarn-cache) already exists.
9. Apply branch sensitivity (Cat D only)
event / headBranch | Bar | Cat D disposition |
|---|---|---|
push to main/stable/* | Strict | Hardening primary (retry, caching, mirror, sizing); rerun = unblock, not fix |
merge_group | Strict | Same |
pull_request | Looser | Rerun fine for one-off; harden only if recurring |
schedule / workflow_dispatch | Per-workflow | Harden if # owner: is set; otherwise rerun |
A/B/C: branch only changes the brief framing.
On strict-bar branches, never close with "rerun" alone — name the smallest hardening change in .github/workflows/ or .github/actions/ as primary fix.
10. Brief
**Run**: <workflow> · <branch> · <event> · <url>
**Failed jobs**: <n> (<grouped if matrix>)
**Category**: A | B | C | D
**Reliability bar**: strict (main/stable/*/merge_group) | looser (pull_request)
**Root cause**
<1–3 sentences, specific file/line/condition>
**Proposed fix**
<concrete edit + path; for D on strict bar, the hardening is the fix, rerun is the unblock>
**Verification**
<exact local command — usually module-scoped `./mvnw`, or a workflow re-run>
Don't cite reference files in the brief. Stop. Apply only after user confirms; re-run verification; report.
Guardrails
- Stop after brief. No edits without user go-ahead.
- No silent reruns. Recommend
gh run rerun --failed <run-id> --repo camunda/camunda; don't trigger. - Don't blame the diff blindly — verify the failing code is reachable from the changeset.
- Format/build via repo conventions (
./mvnw license:format spotless:apply -T1C+ module-scoped command fromAGENTS.md). Never full-repo builds. - Backports — for bug fixes that may need
stable/*, ask the user perAGENTS.md. - Never disable/skip/@Disabled a flaky test. File
kind/flakeissue viacreate-issue, assign engineer, leave test enabled.
Compose with
ci-validation— after any workflow edit, pre-commit.ci-workflow-authoring— for non-trivial workflow changes.create-issue— to file a flake issue.ci-incident— escalate if part of a declared incident, not a single job.