暗黙の前提に依存した脆い設計が、層状に積み重なっていました。
表層:pod install衝突
CocoaPodsというツールが部品を自動で集める時、UnityAdsの4.17.0版と4.18.1版の両方が同時に必要だという要求をしてきました。これはあきらかにおかしい。
最初はリポジトリの重複が原因だと思い、修正しました。
しかし本当の問題は「なぜ過去は成功していたのか」でした。
中層:Podfile.lockファイルの存在
過去のビルドには各アプリフォルダに Podfile.lock という履歴ファイルが残っていました。
このファイルがあるとCocoaPodsは「前回と同じバージョンを使う」と判断し、不要な要求があっても無視します。
ところが、自動ビルドスクリプトにフォルダを毎回削除して新しく作り直すという後付の修正を入れてしまいました。
履歴ファイルも削除されるので、CocoaPodsは新たに判断し直し、古い不要な要求を拾ってバージョン衝突が起きたのです。
教訓:状態ファイルに依存していた脆さです。
深層:バッチが1本で止まる
複数アプリを連続ビルドする仕込み(バッチ)が、1本目の後で止まってしまいました。
ビルド後、Unityが自動的にコードを再コンパイルし、ドメインリロード(内部リセット)が発生していました。
この時、毎フレーム実行するよう登録した処理は登録自体が消滅します。
バッチの進行ロジックもそれだったため、マーカーファイルがあっても誰も見に行かなくなったのです。
教訓:変更検知と状態管理の設計が分離していました。
なぜ気づけなかったか
「以前動いていた」という事実に縛られていました。
本来は「なぜ動いていたのか」を問うべきでした。答えは特定の条件(履歴ファイルの存在、設定値が変わらない、バッチを使わない)に暗黙に依存していたからです。
解決策
1つ目:Podfileの不要な行を自動削除する。
2つ目:バッチ中は設定値復元をスキップする。
どちらも「依存していた前提を取り除く」設計です。
最後に
ネットで既知の原因を調べることが役に立ちました。
そして最大の教訓は「動いていたのに動かない」という問い自体が脆い設計の信号だということです。
追伸
今回はAIも苦労していました。