Skip to content

ci: 3 workflow を単一 ci.yml に統合、並列化とキャッシュで高速化 - #20

Merged
neguse merged 9 commits into
masterfrom
agent/ci-unify-parallel
Jul 30, 2026
Merged

ci: 3 workflow を単一 ci.yml に統合、並列化とキャッシュで高速化#20
neguse merged 9 commits into
masterfrom
agent/ci-unify-parallel

Conversation

@neguse

@neguse neguse commented Jul 30, 2026

Copy link
Copy Markdown
Owner

構成

PR のマージ gate と master deploy を 1 つの ci.yml に統合し、全 platform を同じ骨格に揃える:

changes ─┬─ lint
         ├─ linux ───────────────┐
         ├─ windows ─────────────┤
         └─ web-build ─┬─ web-verify ×10 ─┼─ gate ── deploy (master/dispatch のみ)
                       └─ web-golden ×2 ──┘
  • required check は集約 job gate のみ。test job の増減やシャード数変更で branch protection を触らずに済む
  • changes job は保守的な 2 クラスだけ判定: docs のみの PR → lint だけ、web/haxe-wasm のみの PR → native をスキップ。それ以外は全実行
  • Haxe 5 導入は composite action .github/actions/setup-haxe5 に一本化

速度(通常 PR、warm cache で全体 ~5.5分。従来 ~18-27分)

ボトルネックは workflow 構造ではなくスクリプト内の直列性と無効化されていた cache だった:

  • C# sample gate(旧 11.3分 → ~4分、うち大半は C build と並行):
    • dotnet run の MSBuild 評価 ~5秒/回を排し、Transpiler を一度 build して DLL 直接実行(LUB_TCS_DLL)
    • transpile(pool)→ csproj build(直列。並列は MSBuild/NuGet の取り合いで逆効果)→ capture(直列。llvmpipe は 1 プロセスでコア数分の thread を立てるため多重化しても縮まない)の 3 相に分割し、dotnet 相は C build と並行実行
    • CI(--skip-golden)の capture は golden cmp を伴わない crash smoke なので frame 240 → 30。golden 比較する pre-push 経路は 240 を維持
  • web verify(旧 11分 → 最遅シャード ~2分): サンプル毎の固定 6秒 sleep を screenshot poll に置換し、LUB_VERIFY_SHARD で 10 分割(shard 1 = 編集/C# セッション系、2..n = A5 を cs 重み付きで分担)
  • web golden: LUB_GOLDEN_SHARD で 2 分割(概算コスト greedy で均す)
  • cache: ccache(linux native / emcc。emsdk は setup-emsdk の毎 run ランダム展開パスが ccache を全ミスさせるため ~/emsdk 固定 + actions/cache に変更)、tcs wasm assets + prebuilt snapshot(tcs submodule SHA + C# ソースの content key。hit 時は dotnet workload ごとスキップ)、haxe5、playwright browsers。master push が cache を温め PR が読む

haxe-wasm / tcs を触る PR は再生成(docker ~8分等)が乗るためこの目標の対象外。

マージ後の作業(人間)

branch protection の required check を旧 3 job(native-gate / build-test / verify)から gate に付け替える。

🤖 Generated with Claude Code

https://claude.ai/code/session_016WGX3e2vn3kWMnPbvTvF5v

neguse and others added 9 commits July 31, 2026 01:50
required check を集約 job gate に一本化し、build → test 並列 fan-out の
対称な骨格に揃える。速度の主対策:

- C# sample gate: Transpiler を一度だけ build して DLL 直接実行
  (dotnet run の MSBuild 評価 ~5s/回を排除)、サンプルを pool で並列化
- web verify: LUB_VERIFY_SHARD で suite を 4 分割し matrix 並列、
  A5 の固定 6s sleep を screenshot poll (上限 2 倍維持) に置換
- web golden を verify と並列の独立 job に分離
- cache: ccache (native/emcc)、tcs assets (content key)、haxe5、playwright
- changes job: docs のみ → lint だけ、web/haxe-wasm のみ → native skip

マージ後に branch protection の required check を gate へ付け替える。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WGX3e2vn3kWMnPbvTvF5v
初回 run の実測反映:
- C# pool 一括 6m16s の主因とみられる並列 dotnet build (csproj) の
  MSBuild/NuGet 取り合いを避け、transpile (pool) → csproj build (直列) →
  capture (pool) の 3 相に分割。相ごとの所要時間をログに出す
- A5 シャードは cs エントリ (~9.5s) と haxe (~7s) の重み付き累積で分割し、
  4 → 6 シャードに増やす

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WGX3e2vn3kWMnPbvTvF5v
warm run の実測で capture pool (4 並列) が 234s、旧直列は ~1s/件 (30s 級)。
llvmpipe は 1 プロセスでコア数分の render thread を立てるため、多重化すると
16 thread/4 core のスラッシングで 30 倍級に劣化する。pool 幅 1 で実行する。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WGX3e2vn3kWMnPbvTvF5v
capture 合計 ~250s は lavapipe の実レンダリングで、並列化では縮まない
(llvmpipe がプロセスごとにコア数分の render thread を立て CPU 飽和)。
仕事量を減らす:
- --skip-golden (CI) は golden cmp を行わず capture は crash smoke なので
  240 frame → 30 frame に短縮。golden 比較する pre-push 経路は 240 を維持
- dotnet 相 (Transpiler prebuild / transpile / csproj build) は native
  binary に依存しないため C build と並行に実行し、capture の前で join
- verify シャードを 6 → 8 に増やす

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WGX3e2vn3kWMnPbvTvF5v
standalone シャードの settle 待ちに使っていた waitForPlayerReady は
listener を張る前に playerReady が発火済みだと 60s timeout を丸ごと待つ
(シャード 8 実測: 起動から最初の A5 まで 95s)。canvas に絵が出るまでの
pixel poll (上限 30s) に置き換える。verify は 10 分割に増やし、web-build
の wasm build (warm 81s) 診断用に ccache 統計を出力する。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WGX3e2vn3kWMnPbvTvF5v
setup-emsdk action は毎 run ランダムな temp パスに展開するため、コンパイラ
パスが変わって emcc の ccache が全ミスしていた (実測 hit 0.4%)。~/emsdk に
固定して actions/cache し、CCACHE_COMPILERCHECK=content を併用する。
web チェーンの律速に浮上した web-golden は LUB_GOLDEN_SHARD で 2 分割する。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WGX3e2vn3kWMnPbvTvF5v
連続スライスだと 16_box2d (frame 120) と 18_coin_pusher (frame 240) が
隣接インデックスで同じ側に寄り、shard 間が 96s/149s に偏っていた。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WGX3e2vn3kWMnPbvTvF5v
- golden: round-robin でも 18_coin_pusher と 26_renderer3d が同じ shard に
  落ちて 96s/152s に偏っていた。概算コスト表 + greedy で 74/74 に均す
- C# transpile は dotnet プロセス起動のレイテンシ支配なので pool 幅を
  コア数の 2 倍にする

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WGX3e2vn3kWMnPbvTvF5v
C build と並行する区間では CPU が飽和しており、pool 幅を広げても
取り合いになるだけだった (実測 66s → 108s)。既定の nproc に戻す。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WGX3e2vn3kWMnPbvTvF5v
@neguse
neguse merged commit 7c28e13 into master Jul 30, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant