skills/gh-logs/SKILL.md
Fetch and analyze GitHub Actions logs via gh CLI. Diagnoses CI failures, detects flaky tests, profiles slow steps, and suggests fixes. Use when CI is broken, builds are failing, or you need to understand workflow run history.
npx skillsauth add johnie/skills gh-logsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
CI log analyst. Fetches GitHub Actions logs via gh CLI, reasons about them, diagnoses root causes, and suggests fixes. Stop clicking through the web UI — the terminal is faster, searchable, and doesn't crash on large output.
(none): Auto-detect repo + branch, find latest failed run, diagnose<run-id>: Analyze a specific run by ID<workflow-name>: Filter to a specific workflow--flaky: Detect flaky tests by comparing recent runs--slow: Profile step timing, find bottlenecks--history [n]: Analyze last n failures (default 10)--watch: Monitor a running workflow in real timeVerify gh is authenticated and in a git repo:
gh auth status 2>&1 | head -3
gh repo view --json nameWithOwner --jq '.nameWithOwner'
If auth fails, tell the user to run gh auth login.
No arguments — find latest failed run on current branch:
BRANCH=$(git branch --show-current)
gh run list --branch "$BRANCH" --status failure --limit 1 --json databaseId,displayTitle,conclusion,event,headBranch,workflowName,createdAt
If no failures on current branch, fall back to all branches:
gh run list --status failure --limit 1 --json databaseId,displayTitle,conclusion,event,headBranch,workflowName,createdAt
With run ID — use directly.
With workflow name — filter:
gh run list --workflow "<name>" --status failure --limit 1 --json databaseId,displayTitle,conclusion,event,headBranch,workflowName,createdAt
gh run view <run-id> --json jobs --jq '.jobs[] | {name, conclusion, steps: [.steps[] | select(.conclusion == "failure") | {name, conclusion}]}'
This gives: which jobs failed, which steps within them failed.
gh run view <run-id> --log-failed
If output is too large (>5000 lines), narrow to specific job:
gh run view <run-id> --job <job-id> --log-failed
If you need full context around the failure:
gh run view <run-id> --log
Match log output against known failure patterns. See references/failure-patterns.md for the full signature database.
Classify into one of these categories:
| Category | Signals |
|---|---|
| test | FAIL, assertion errors, snapshot mismatches |
| build | error TS, Build failed, compilation errors |
| deps | ERESOLVE, 404 Not Found, registry timeouts |
| infra | OOM, No space left, runner shutdown |
| lint | found X errors, formatting violations |
| auth | 403, 401, token expiry, secret access denied |
| timeout | exceeded maximum execution time, stuck steps |
Output a structured diagnosis. See references/analysis-templates.md for the full template.
Always include:
The standard mode. Find failure, read logs, identify root cause, suggest fix. This is what runs when you invoke /gh-logs with no flags.
--flaky)Compare recent runs to find tests that intermittently fail:
gh run list --branch "$BRANCH" --limit 20 --json databaseId,conclusion
For each failed run, extract failed test names from logs. Tests that fail in some runs but pass in others are flaky. Report with pass/fail ratio and suspected cause (race condition, timing, port conflict, shared state).
--slow)Extract step timing data:
gh run view <run-id> --json jobs --jq '.jobs[].steps[] | {name, startedAt: .started_at, completedAt: .completed_at, conclusion}'
Calculate durations, sort descending, identify bottlenecks. Suggest optimizations (caching, parallelism, unnecessary steps).
--history [n])Analyze the last n failed runs (default 10):
gh run list --status failure --limit <n> --json databaseId,displayTitle,conclusion,event,headBranch,workflowName,createdAt
For each, get failed job/step names. Identify recurring patterns: same step failing repeatedly, specific branch with persistent issues, time-correlated failures.
--watch)Monitor a running workflow in real time:
gh run watch --exit-status
When it finishes, if it failed, automatically switch to diagnose mode and analyze the failure.
User: /gh-logs
Claude: Checking CI status for branch feat/auth-flow...
Found failed run #4521 (CI / test) from 3 minutes ago.
## Diagnosis
**Category**: test
**Failed step**: Run tests (job: test-ubuntu)
**Root cause**: Snapshot mismatch in LoginForm component — expected output changed after adding the "Remember me" checkbox.
**Log excerpt**:
FAIL src/components/LoginForm.test.tsx
- renders login form (2ms)
Expected: "<form>..."
Received: "<form>...<label>Remember me</label>..."
1 snapshot failed.
**Fix**: Update the snapshot:
bun test -- -u src/components/LoginForm.test.tsx
**Verify**:
git add -A && git commit -m "test: update LoginForm snapshot" && git push
gh run watch
User: /gh-logs --flaky
Claude: Analyzing last 20 runs on feat/payments...
## Flaky Tests Detected
| Test | Pass | Fail | Rate |
|---|---|---|---|
| checkout.test.ts > handles concurrent requests | 14 | 6 | 70% |
| webhook.test.ts > validates signature | 18 | 2 | 90% |
**checkout.test.ts > handles concurrent requests**
Suspected cause: Race condition — test uses shared port 3000 without isolation.
Fix: Use random port assignment or `--forceExit` with test isolation.
**webhook.test.ts > validates signature**
Suspected cause: Timing-dependent — signature validation uses Date.now().
Fix: Mock the clock in test setup.
User: /gh-logs --slow
Claude: Profiling run #4519 (CI / build)...
## Step Timing
| Step | Duration | % of Total |
|---|---|---|
| Install dependencies | 2m 34s | 42% |
| Run tests | 1m 48s | 29% |
| Build | 58s | 16% |
| Lint | 28s | 8% |
| Checkout | 12s | 2% |
| Setup Node | 8s | 1% |
**Bottleneck**: Install dependencies (2m 34s / 42%)
**Suggestion**: Add dependency caching. Example step:
- uses: actions/cache@v4
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }}
gh returns 403/rate limit, wait and retry. Inform the user.--log-failed output exceeds 5000 lines, narrow to specific job with --job. If still too large, use gh api to download raw log and grep for errors.gh CLI: Tell user to install: brew install gh or see https://cli.github.comgh auth login.gh will error with 404. Explain permission requirements.references/failure-patterns.md for the full failure signature databasereferences/gh-commands.md for complete gh CLI command referencereferences/analysis-templates.md for output format templatestools
WordPress CLI operations for database management, plugins, themes, users, content, and site configuration. Use for migrations, bulk updates, user audits, content imports, or any wp-cli commands.
tools
Designs complex generic types, refactors `any` to strict alternatives, creates type guards and utility types, resolves TypeScript compiler errors, and explains type-level concepts. Use when the user asks about TypeScript (TS) types, generics, type inference, type guards, removing `any` types, strict typing, type errors, `infer`, `extends`, conditional types, mapped types, template literal types, branded/opaque types, `satisfies`, `unknown`, function overloads, declaration merging, strict mode, or utility types like `Partial`, `Record`, `ReturnType`, `Awaited`, and `NoInfer`.
tools
Build type-safe CLI applications with Stricli. Use when creating TypeScript CLIs with typed flags/positional args, multi-command routing, or automatic help generation. Stricli catches parameter errors at compile time. Use this whenever the user mentions CLI frameworks, command-line tools, argument parsing, or typed commands in TypeScript.
tools
Create, update, and review GitHub PRs. Commands: create [-v] [--draft], update [-v], review <number|url>. Generates structured PR bodies with conditional sections (Testing, Deployment, Screenshots). Requires gh CLI.