ci-triage
Find why a Kaeri CI run, beta release or promotion failed without reading whole logs, and check that a beta published. Use when a PR check, the Release or Promote workflow or a store image fails.
SKILL.md.claude/skills/ci-triage/SKILL.md
GitHubCI triage
Find the failing step
gh pr checks <pr> | grep -P '\t(fail|pending)\t' # what failed or is waiting
gh run view <run> --json jobs -q '.jobs[]|select(.conclusion=="failure")|"\(.name) \(.databaseId)"'
gh api repos/bitknox/kaeri/actions/jobs/<job>/logs \
| grep -E '##\[error\]|error(\[|:)|FAILED|panicked|✘|ERROR' | head -20
- When
gh run viewreturns HTTP 502, usegh api repos/bitknox/kaeri/actions/runs/<run>/jobs. - Swift logs are full of
linkd/Connection]noise; filter it out withgrep -v. - Save a log to the scratchpad and grep it there rather than printing it.
- The
CI passedgate fails whenever another check fails; look at the other check.
Failures seen before
- Date or time dependent tests: a test passes in the morning and fails in the evening. Fix with a fixed clock or zone, never by changing expected values.
- Windows line endings: scripts editing files on the Windows runner must keep CRLF
(
awk -v BINMODE=3,diff --strip-trailing-cr). - New advisory:
auditfails on a RUSTSEC published that day:cargo update -p <crate>. - Cache export: buildx
failed to reserve cachemust not fail the build (ignore-error=true). - Android
NEEDED libc++_shared.so: a dependency linked the C++ runtime dynamically; link it statically. - Flaky timing tests: wait on the condition or the queue, never on a fixed sleep.
- Runners flooded: many Dependabot PRs at once queue main's release behind them;
gh run canceltheir runs.
Re-run and confirm a beta
- Re-run only failed jobs:
gh run rerun <run> --failed. - After a merge to main, confirm the beta pre-release published:
gh run list --commit <sha> --workflow Release --json status,conclusion
gh release view <tag> --json isPrerelease,assets -q '{pre: .isPrerelease, files: (.assets|length)}'
# a beta: pre true, 31 files, including appcast.xml and sidestore.json
gh run list --workflow Promote --limit 1 --json conclusion,displayTitle
gh api repos/bitknox/kaeri/releases/latest -q .tag_name # the stable
Promote failed
Read the run's notice first. A held, too young or missing beta is a notice and a green run, not a
failure. A run waiting for approval is waiting for the maintainer. A real failure names its step:
the checks at the end say which of releases/latest, the appcast, sidestore.json or the image
tag did not match. Clearing the pre-release flag is the last change, so the maintainer can run a
failed promotion again with the same tag if it failed before that. Never dispatch Promote
yourself.