mcpField
F
flaker-storage-cache-on-ci

flaker-storage-cache-on-ci

github.com/mizchiクラウド・DevOps41651 回インストール1 週間前に更新
リポジトリ

flaker-storage-cache-on-ci について

GitHub ActionsでflakerのDuckDB履歴をCI実行間で保持する方法を案内するスキルです。キャッシュ設定、ワークフローの役割分担、レポート取り込み、問題の調査を扱います。

主な機能

  1. 01actions/cache@v6によるDuckDBデータの保持
  2. 02キャッシュとflakerの保存先の一致
  3. 03ハイブリッド実行への変更ファイルの指定
  4. 04CIワークフローからのレポート取り込み
  5. 05履歴消失の原因調査

活用シーン

  1. 01GitHub Actionsの実行間でflaker履歴を保持
  2. 02CIレポートのflakerへの取り込み設定
  3. 03CI履歴の消失やリセットの調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mizchi/skills --skill flaker-storage-cache-on-ci

インストール後、Claude Code で/flaker-storage-cache-on-ciを入力して読み込まれたか確認します。

同梱ファイルREADME.md

詳細

flaker storage cache on GitHub Actions

flaker keeps its data in a DuckDB file at the path declared by flaker.toml [storage] path (default .flaker/data). For flaky detection / KPI / quarantine to work, that file must persist between CI runs. GitHub Actions has no first-class runtime storage, so the convention is actions/cache@v6 with a sliding key.

When this skill applies

  • "新しい repo に flaker を CI で動かす"
  • "flaker の履歴が CI で消えてる / 毎回ゼロからになる"
  • "flaker に を import するワークフロー追加して"
  • "VRT / playwright / custom-adapter report を flaker に流したい"

Cache key shape

- name: Cache flaker data
  if: always()
  uses: actions/cache@v6
  with:
    path: .flaker/data
    key: flaker-data-${{ github.run_id }}
    restore-keys: |
      flaker-data-
  • key uses github.run_id so each run writes a new cache entry on save (GH Actions saves at end of job).
  • restore-keys: flaker-data- matches anything written previously, falling back to the most recent — so the next run sees the latest accumulated state regardless of which earlier run produced it.
  • if: always() so a failed earlier step still triggers the save (history-on-failure is fine and often more useful than history-only-on-success).

The path MUST equal flaker.toml's [storage] path. Default is .flaker/data (a file, not a directory — pre-creating it as a dir breaks the DuckDB open).

In a pnpm workspace monorepo: prefix the cache path with the package directory, e.g. packages/<pkg>/.flaker/data. flaker does NOT walk up to find flaker.toml — it must live next to where flaker is invoked. Mismatched cache path vs flaker.toml location surfaces as Config file not found (when running from repo root) or "history vanished every run" (when cache and flaker disagree on where storage is).

Triggering writes

actions/cache@v6 saves automatically in its post-step. Callers don't cache save explicitly. The save key is the run-id, so duplicate writes never collide.

fetch-depth for --changed derivation

Any flaker invocation that uses the hybrid / affected strategy (flaker run --gate merge in CI profile, by default) needs --changed <files,...>. Without it: Error: hybrid mode requires resolver and changedFiles.

- uses: actions/checkout@v7
  with:
    fetch-depth: 0  # need history for `git diff` against the PR base
- name: flaker run --gate merge
  env:
    BASE_REF: ${{ github.event.pull_request.base.ref }}
  run: |
    changed=$(git diff --name-only "origin/${BASE_REF}...HEAD" | tr '\n' ',' | sed 's/,$//')
    pnpm exec flaker run --gate merge --changed "$changed"

Empty diff (config-only PR, etc.) is fine — hybrid falls back to the configured fallback strategy.

Workflows: which one persists, which one reads

Reference layout for splitting workflows by trigger:

WorkflowTriggerReads cacheWrites cacheNotes
flaker-nightly.ymlcron + workflow_dispatchyesyesRuns flaker apply. The canonical writer of vitest history.
<source>-baseline.ymlpush to main + cronyesyesImports a custom-adapter report via flaker import --adapter <name>. Same cache key.
flaker-pr.ymlpull_requestyes(yes implicitly, harmless)Advisory only, continue-on-error: true.
<source>-pr-gate.ymlpull_requestNONOPR-scoped runs would distort the population — keep them ephemeral.

Rule of thumb: anything that touches main / scheduled writes; PR-scoped checks read-only or no cache.

Adding a new ingest source

Common pattern (custom adapter, see flaker#79 for the adapter contract):

  1. Produce the report file (e.g. <source>-report.json, vitest-report.json).
  2. Restore the cache (or rely on the same job's earlier restore step).
  3. Import:
    - name: Import <source> into flaker
      if: always()
      run: |
        pnpm exec flaker import <report-file> \
          --adapter <name> \
          --commit "${{ github.sha }}" \
          --branch "${{ github.ref_name }}" \
          --source ci
    
  4. The cache save at end-of-job picks up the new rows automatically.

if: always() ensures partial-failure runs still record what they saw before the failure.

やってはいけないこと

  • flaker の実行前に .flaker/data をディレクトリとして事前に作成しないでください。 DuckDB はこれをファイルとして開こうとするため、IO Error: Could not read from file ... Is a directory というエラーが発生します。キャッシュの path: .flaker/data がまだ存在しないファイルを指していても問題ありません。存在する場合は actions/cache が復元し、存在しない場合は flaker が作成します。
  • よく検討せずに PR 専用のワークフローへ flaker import を追加しないでください。 PR の実行はコミットが PR に追加されるたびに発生するため、データの蓄積量が過剰になります。PR のジョブではキャッシュを読み取り専用にしてください。
  • flaker ≥ 0.10.7 では NODE_OPTIONS=--preserve-symlinks-main を使用しないでください。 これは pnpm のシンボリックリンクのバグを回避するためのものでしたが、0.10.7 で修正されました。0.11.x では、この環境変数によって CLI が何もせず終了コード 0 で終了します(出力も処理もありません)。 下流での使用を通じて問題が明らかになり、flaker の上流から削除されました。
  • PR のフォークからキャッシュに書き込もうとしないでください。 GH Actions はセキュリティ上の理由からフォークからの書き込みを許可しません。復元は引き続き動作しますが、保存は何もせずに終了します。

診断

履歴が「消えた」場合:

  1. ワークフローの実行ログでキャッシュのヒットログを確認してください。Cache not found for input keys と表示されている場合、restore-keys のプレフィックスが保存時のものと一致していません。
  2. flaker.toml の [storage] path がキャッシュされた path: と正確に一致していることを確認してください。
  3. 同じジョブで flaker doctor を実行してください。ファイルを開けることを確認できます。
  4. flaker status --markdown で行数を確認し、実際に読み込まれた内容を把握できます。

リファレンス

  • ストレージパスの規則については、flaker 自体の docs/contributing.md を参照してください。
  • カスタムレポートインポーターの作成については、--adapter システムのドキュメントを参照してください。

コメント