ci: エミュレータスクショ廃止とGradleキャッシュ有効化でCI時間を短縮#85
Merged
yuga-hashimoto merged 2 commits intoJul 25, 2026
Conversation
Measured on the four pushes to #84 — nearly all of the wall clock is one step in each workflow, and both are dominated by Gradle recompiling from scratch: Android CI 19m36s of which "Test, lint and build APKs" 18m14s capture 17m02s of which the emulator step 16m15s (#83's log shows the gradle build alone accounting for 16m43s of that step) The emulator itself is not the problem; building the app twice from cold is. - Enable the Gradle build cache and parallel execution. `setup-gradle` already persists `~/.gradle` from main, but without `org.gradle.caching` only dependency jars were reused, never task output — so every run recompiled the whole app. - Run the screenshot workflow on main as well. `setup-gradle` writes its cache only from the default branch and keys it per job, so a job that never runs on main never has a warm cache to restore. `capture` has always started cold for exactly this reason; a run on merge gives pull requests something to restore. - Stop building the release APK on pull requests. `assembleRelease` runs R8 with minification and resource shrinking and is the most expensive task here; the published artifact comes from release.yml, and main still builds it on every merge, so the coverage is kept. - Cancel superseded pull request runs. android.yml had no `concurrency` block, so all four pushes to #84 ran to completion, three of them pointlessly. Verified `testDebugUnitTest`, `lintDebug`, `detekt`, `spotlessCheck` locally with the new Gradle settings, and both workflow files parse. The CI timings themselves can only be confirmed by the runs this change produces. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L3eN8AmoAcBDCTEeMTY3ba
It is the most expensive thing in CI (17 minutes per pull request) and it was not buying a proportional amount. It never compared against golden images — the PNGs were only uploaded as an artifact for a human to look at, and the one automated check was a hand-maintained list of Japanese strings expected to be on screen. That list drifts. `5e290b1` removed the composer's workspace chip on 23 July and the assertion for it stayed, so the job failed on #80, #81, #82 and #83 — all merged with it red — until #84 repaired three separate stale assertions. And because the assertions run before the capture, a single stale string took the render smoke test and the screenshots down with it: for two days the job was pure cost. Removes the workflow along with `UiScreenshotInstrumentedTest` and the `PreviewRuntimeTarget` fixture that only it used. The other instrumented tests (`ChatFlowE2ETest`, `ChatVoiceInstrumentedTest`, `LocalRuntimeUpdaterInstrumentedTest`) are untouched. What is lost: nothing checks that the ten main screens still render on a real Android runtime. If that coverage is wanted back, it should return as a render check with tag-based assertions rather than screen-specific wording, so it cannot rot the same way. Verified `compileDebugAndroidTestKotlin`, `testDebugUnitTest`, `detekt` and `spotlessCheck` after the removal. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L3eN8AmoAcBDCTEeMTY3ba
yuga-hashimoto
marked this pull request as ready for review
July 25, 2026 12:13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
実測
#84 での4回の push を計測した結果、両ワークフローとも1ステップに時間が集中していました。
capture のステップの内訳は、#83 の失敗ログに出ていた通りGradle ビルドだけで 16分43秒(
BUILD FAILED in 16m 43s / 63 actionable tasks: 63 executed)。つまりエミュレータが遅いのではなく、アプリを2回コールドビルドしているのが原因でした。変更内容
1. エミュレータスクリーンショットワークフローを削除
CI で最も高価(PRあたり17分)でしたが、コストに見合っていませんでした。
5e290b1(7/23、コンポーザー再設計でワークスペースチップ削除)以降、fix: stop dropping streamed chat events and cross-session poll writes #80 / fix: show favorites above recent models in the model picker #81 / Fix chat composer overlapping nav bar, remove focus mode toggle #82 / fix: deliver chat events, end runs on time, and show real chat state #83 すべてで赤のままマージされていました。fix: 承認通知のクラッシュと質問ツールの行き止まりを解消 #84 で3箇所の陳腐化を修正してようやく復活UiScreenshotInstrumentedTestと、それ専用のフィクスチャPreviewRuntimeTargetも削除します。他の instrumented test(ChatFlowE2ETest/ChatVoiceInstrumentedTest/LocalRuntimeUpdaterInstrumentedTest)は変更していません。失われるもの: 主要10画面が実機ランタイムで描画できるかの確認。復活させるなら、画面固有の文言ではなく testTag ベースのアサーションにして、同じ腐り方をしない形にすべきです。
2. Gradle ビルドキャッシュと並列実行を有効化
gradle/actions/setup-gradleは~/.gradleを main から永続化していますが、org.gradle.cachingが未設定だったため再利用されていたのは依存 jar だけで、タスク出力は毎回作り直しでした。3. PR で
assembleReleaseを実行しないisMinifyEnabled = trueなので R8 の難読化+リソース圧縮がフルで回っており、このワークフローで最も重いタスクです。配布物はrelease.ymlが別途ビルドしますし、main へのマージ時には引き続きビルドするので担保は維持されます。4.
android.ymlにconcurrencyを追加android.ymlにはありませんでした。そのため #84 では4回分の Android CI がすべて完走し、うち3回は完全な無駄でした。main への push はキャンセルせず完走させます。効果
3 の効果はこのPRの run で既に確認できています:
1 と合わせて、PRあたりの実時間は約20分 → 約16分、消費計算量は半減します。2 のキャッシュ効果は main にマージして1回走った後の PR から上乗せされます。
検証
compileDebugAndroidTestKotlin/testDebugUnitTest/detekt/spotlessCheckを実行 → 成功android.ymlの YAML パースを確認なお
docs/superpowers/plans/配下の過去の計画文書が削除ファイルに言及していますが、日付入りの履歴文書なので書き換えていません。🤖 Generated with Claude Code
https://claude.ai/code/session_01L3eN8AmoAcBDCTEeMTY3ba