本文へ移動
cccskills
無料GitHub で公開

analyzing-ci-flakiness

Analyzes recent CI failures on pull requests to identify flaky tests, using retry outcomes (failed attempt → green re-run) and cross-PR recurrence as evidence, and maintains a local longitudinal ledger so flakiness can be tracked over time. TRIGGER when: the user wants to find flaky tests, correlate recent CI failures, check which tests fail across PRs or recover on retry, or refresh the flakiness trend report. DO NOT TRIGGER when: babysitting a single PR's CI until green → monitoring-pull-requests; diagnosing or fixing one specific failing test → the bug-analysis skills.

インストール方法を見る

含まれるファイル(2)

  • SKILL.md7.9 KB
  • scripts/collect.py17.7 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

CI Flakiness Analyzer

Introduction

A test is flaky when its failure does not reproduce on the same code: the run was retried and went green, or the same test fails on unrelated PRs. This skill mines both signals from GitHub Actions history, downloads the failed job logs once into a local cache, and appends every observation to a ledger (~/ci-cache/<owner>-<name>/ledger.jsonl) so repeated invocations — weekly, or ad hoc — accumulate trend data instead of starting from scratch.

The mechanical part (fetching, caching, test-name extraction, known-signature classification) is done by the bundled script. Your job is the judgment part: separating flakes from real regressions, spotting new systemic signatures, and writing the report.

Step 1 — Parse arguments

  • Base-branch filter: any arguments that look like branch names or globs (release-1.11, release-*, stable). Default: no filter (all PR bases), which is usually what "how flaky is CI" means. Filter when the user names a branch.
  • Window: a bare integer is a number of days (default 7). An ISO date means "since that date".

Step 2 — Collect

Run the bundled collector (repo-root relative):

python3 .agents/skills/analyzing-ci-flakiness/scripts/collect.py \
  [--base <glob> ...] [--days N | --since YYYY-MM-DD] [--repo owner/name]

It prints a JSON report to stdout and writes everything under ~/ci-cache/<owner>-<name>/windows/<since>_<until>/:

  • runs.jsonl — every pull_request workflow run created in the window
  • failed_jobs_with_tests.json — failed jobs of the interesting run-attempts, with extracted failing tests, systemic-bucket tags, and a recovered_same_run flag
  • report-data.json — headline numbers, ranked per-test table, per-bucket incident counts (bucket_incidents: distinct jobs/runs/PRs per systemic bucket), and the ledger's weekly history
  • joblogs/<job_id>.log — raw logs (ANSI intact; strip with sed 's/\x1b\[[0-9;]*m//g')

Notes the script already accounts for — don't re-derive them:

  • The runs API's pull_requests field is empty for many runs; the script joins runs to PRs through every PR head commit SHA as well. Don't trust the field alone.
  • "Interesting attempts" = every earlier attempt of a retried run (that's what the retry fixed) plus final attempts that failed. Runs cancelled on attempt 1 are concurrency noise and skipped.
  • Logs already on disk are never re-downloaded; the ledger is deduplicated by (job, test). Old logs expire on GitHub's side (~90 days) — an empty joblogs/*.log means expired, not passing.

Step 3 — Investigate what the script could not name

For failed jobs with an empty tests list and no bucket tag, read the log yourself (grep for ##[error], FAILED, Error:, Timeout). Two outcomes:

  • It matches a new systemic signature (infra failure that cascades over many tests). Add a regex for it to BUCKETS in collect.py and to the table below, so future runs classify it.
  • It's a genuine test failure the extraction regexes missed — note the test manually and consider extending extract_tests.

Known systemic signatures (as of 2026-08 — keep in sync with BUCKETS in collect.py)

BucketSignatureMeaning
stack-readinessServerNotResponsiveError … /api/schema/loadSeeded testcontainers stack not ready; the whole pytest-playwright shard errors. One incident, not N flaky tests.
vitest-mock-corruptionTypeError: vi.mocked(...).mockX is not a functionvitest browser-mode module-mocking race; hits a different test file each time.
prefect-setup-triggers-timeoutSetup triggers task ReadTimeoutPrefect hang at session setup; downstream tests hit their own timeouts.
neo4j-deadlockNeo.TransientError.Transaction.DeadlockDetectedConcurrent-write deadlock, usually integration suites under xdist.
compose-boot-failuredocker compose … up --wait non-zero exitStack never booted; job-level infra failure.
sqlite-locked(sqlite3.OperationalError) database is locked (also matches the raw sqlite3.OperationalError: form)Prefect's sqlite under contention.
runner-oomProcess completed with exit code 137Runner OOM/SIGKILL; the mass test failures in the same job are casualties, not flakes.
docker-network-pool-exhaustedall predefined address pools have been fully subnettedLeaked compose networks exhausted the docker address pools on a self-hosted runner.
actions-download-429Failed to download action … 429GitHub rate-limited its own action download; pure platform flake.
prefect-task-manager-wedgedRuntimeError: Prefect task manager setup already failed for http…The memoized task-manager setup (backend/tests/helpers/task_manager.py) timed out once against a Prefect test server; every later class fail-fasts on the remembered failure. One incident, hundreds of cascaded ERRORs.
pytest-green-exit-1green pytest summary (no failed, no errors) directly followed by exit 1Session-teardown/plugin abort after all tests passed (e.g. testcontainers result reporting).

Step 4 — Judge: flake vs regression

For each test in the ranked table, classify:

  • Flaky (strong) — fails on ≥2 unrelated PRs, or recovered_on_retry > 0. The more distinct PRs, the stronger.
  • Flaky (weak) — single occurrence with an infra-flavored error (locator timeout, transient branch not found) and the PR later went green. List, but rank low.
  • Suspect regression, not a flake — the same test fails on every attempt of the same commit and the PR is still red, or the failures started only after a specific merge. Say so explicitly; do not bury it in the flake list. Cross-check: does the test fail on any PR that does not contain the suspect change?
  • Systemic bucket — tests whose only failures carry a bucket tag are casualties, not causes. Report the bucket (with the incident count from bucket_incidents in report-data.json), not the individual tests.

Different tests failing on successive attempts of the same run = two independent flakes, not a regression.

Step 5 — Report

Write ANALYSIS.md into the window directory, then give the user a summary. Lead with the ranked flake candidates. Include:

  1. Headline numbers: PRs in scope, runs matched, retried runs, retried-and-recovered runs (pure-flake evidence), hard failures.
  2. Ranked flake candidates — test id, distinct PRs/runs, recovered-on-retry count, one-line error cause. Group systemic buckets as single entries.
  3. Suspected real regressions, clearly separated.
  4. Trend — from weekly_history in report-data.json: which offenders are new this window, which recur week over week, which disappeared (likely fixed). This section is the reason the ledger exists; don't skip it once ≥2 windows of data exist.

Do not propose fixes unless asked; the deliverable is the evidence-ranked candidate list.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Audits internal (dev/) and external (docs/) documentation completeness for a feature, subject, or set of existing docs, maps changes indicated by the user, across Infrahub's documentation layers, reports gaps, and optionally applies the fixes. TRIGGER when: the user wants to audit or check documentation coverage, find doc gaps after a feature branch, or verify docs are still current for a subject or specific files. DO NOT TRIGGER when: authoring new documentation from scratch → use the add-docs flow; only linting/formatting Markdown → run `uv run invoke docs.lint`.

日本語の概要は準備中です。原文の説明を表示しています。

opsmill/infrahub5342026年10月11日 更新

commit

無料

Stages and commits the current changes onto a safe working branch, enforcing branch discipline and optionally pushing upstream. TRIGGER when: the user wants to commit, save, or check in the current changes. DO NOT TRIGGER when: opening a pull request → pr.

日本語の概要は準備中です。原文の説明を表示しています。

opsmill/infrahub5342026年10月11日 更新

Use when you've fixed a bug, added a feature, or made any user-facing change in a project that uses Towncrier and need to record it for the changelog — before committing or opening a PR, or whenever asked to add a changelog entry, towncrier fragment, or news fragment.

日本語の概要は準備中です。原文の説明を表示しています。

opsmill/infrahub5342026年10月11日 更新

Turns a single feature idea, improvement, or bug into ONE well-structured GitHub issue. TRIGGER when: the user wants to file/open/create an issue, turn a feature idea or improvement into a ticket, or capture something missing or broken as a ticket. DO NOT TRIGGER when: breaking work into multiple issues or planning a body of work → a planning skill; writing a full Product Requirements Document → creating-prd; the idea is still fuzzy and unhardened → grilling-ideas first.

日本語の概要は準備中です。原文の説明を表示しています。

opsmill/infrahub5342026年10月11日 更新

Synthesises the current conversation context into a Product Requirements Document and publishes it to GitHub (as a comment on a referenced issue, or a new issue). Synthesises from context; does not interview. TRIGGER when: the conversation has produced enough understanding of a feature and the user wants it captured as a PRD. DO NOT TRIGGER when: a single small issue is enough → creating-issues; the idea has not been stress-tested yet → grilling-ideas first; bug reports.

日本語の概要は準備中です。原文の説明を表示しています。

opsmill/infrahub5342026年10月11日 更新

Stress-tests a fuzzy or vague feature idea before any PRD, spec, or ticket is written. TRIGGER when: the user has a fuzzy feature idea — one or two paragraphs, vague on users / scope / success — and wants to harden it, or says "grill / stress-test / pressure-test this idea." DO NOT TRIGGER when: the idea is already turned into a spec or PRD; bug fixes or refactors; the idea is hardened and you are ready to write the PRD → creating-prd.

日本語の概要は準備中です。原文の説明を表示しています。

opsmill/infrahub5342026年10月11日 更新

opsmill のスキルをすべて見る

このスキルの問題を報告する