0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Mint と Build Phase を見直して、Xcode Cloud のテスト時間を削減した話

0
Posted at

前書き

私が担当している iOS プロジェクトでは、最近 Xcode Cloud を導入し、テストを中心に運用を試し始めました。

最初に実行してみたところ、想定外だったのが テスト実行時間 です。
1 回の実行に 約 49 分 かかっており、正直なところ「これはさすがに使い続けるのは厳しそうだな……」という印象でした。

Xcode Cloud には無料枠(25 時間 / 月)があるため、このペースだとすぐに上限に達してしまいます。
それ以上に、結果が返ってくるまでに時間がかかりすぎて、日常の開発フローに組み込むのは現実的ではありませんでした。

そこで、

  • なぜここまで時間がかかっているのか
  • 本当に Xcode Cloud は遅いのか

を一度整理し、原因を調べた上で、いくつかの対応を行ってみることにしました。

この記事では、Xcode Cloud の特性を踏まえつつ、テスト時間が長くなっていた原因と、それに対して行った改善内容をまとめています。
同じように Xcode Cloud の導入を検討している方や、「入れてみたけど遅くて困っている」という方の参考になれば幸いです。


なぜ Xcode Cloud でテスト時間が長くなっていたのか

原因を切り分けるため、まず Xcode Cloud がどのような環境で動くか を整理しました。

Xcode Cloud には、ローカル環境や自前 CI と異なる特徴があります。

  • 毎回クリーンな環境で実行される
  • 依存ツールや成果物は基本的にキャッシュされない
  • Xcode の Build Phase に含まれる処理は毎回必ず実行される

この前提を踏まえてプロジェクトの構成を見直したところ、
テスト時間が長くなっていた大きな要因は Build Phase に集約されていた処理 でした。

当時の構成

  • SwiftLint を Mint で管理
  • Xcode の Build Phase で SwiftLint を実行
  • LicensePlist などのツールも Build Phase に含まれている

この構成はローカルではあまり問題になりませんが、Xcode Cloud では以下のような挙動になります。

  • Mint が 毎回ツールをソースからビルド
  • SwiftLint 実行前にそのビルド時間が発生
  • テスト本体とは直接関係ない処理に時間を取られる

結果として、

「テストが遅い」のではなく、「テスト前の準備が重い」

という状態になっていました。


方針:CI から重い処理を外す

原因が見えたので、次に方針を決めました。

今回重視したのは次の 3 点です。

  1. Xcode Cloud 上では極力シンプルにする
  2. コード品質のチェック自体は弱めない
  3. チーム全体で無理なく運用できる構成にする

その結果、

  • CI(Xcode Cloud) → ビルドとテストに集中
  • ローカル開発 → コミット時に品質を担保

という役割分担にすることにしました。


具体的にやったこと

1. SwiftLint を Build Phase から外す

まず、SwiftLint の実行を Build Phase から削除しました。

Build Phase に置くと、

  • ローカルビルド
  • CI ビルド
  • テスト実行

のすべてで実行されてしまうため、Xcode Cloud ではオーバーヘッドが大きくなります。


2. SwiftLint を Homebrew 管理に変更

SwiftLint は Mint ではなく、Homebrew でインストールするように変更しました。

  • Mint:ソースビルドが発生
  • Homebrew:ビルド済みバイナリを利用

これにより、ツール準備にかかる時間を大きく削減できます。


3. Git pre-commit フックで SwiftLint を実行

SwiftLint の実行タイミングを ビルド時 → コミット時 に変更しました。

  • コミット時に変更ファイルのみをチェック
  • --strict モードで警告もエラー扱い
  • 問題があればコミットをブロック

これにより、

  • 新規コードの品質は担保される
  • CI では SwiftLint を実行しない

という構成になります。


この構成のメリット

従来(Mint + Build Phase)

  • CI の速度
    遅い(毎回ツールをソースからビルド)

  • チェック対象
    全ファイル

  • 新規負債の防止
    △ 警告があってもビルド・テストは通る

  • チーム共有
    × 各自がローカルで設定する必要がある


今回(Homebrew + pre-commit)

  • CI の速度
    速い(ビルド済みバイナリを利用)

  • チェック対象
    変更ファイルのみ

  • 新規負債の防止
    ◎ 警告があるとコミットがブロックされる

  • チーム共有
    ◎ リポジトリに含めて全員で共有できる


全体構成

[ローカル開発]
    │
    └── コミット時 ───→ SwiftLint(strict モード)
                         変更ファイルのみ、警告でコミット中止

実装例:SwiftLint を pre-commit で実行する

ここでは、今回採用した 「Homebrew + pre-commit」 の実装例を紹介します。
狙いはシンプルで、CI(Xcode Cloud)ではビルドとテストに集中させ、コード品質チェックはローカルのコミット時に担保することです。

ポイントは次の 3 つです。

  • 変更ファイルのみ を対象にする(既存の警告に引きずられない)
  • --strict を付けて 警告もエラー扱い にする(新規負債を増やさない)
  • .githooks/ をリポジトリに含めて チーム全員に配布 する(属人化させない)

※ 本記事では SwiftLint に絞って紹介しますが、同様の考え方で LicensePlist などの Build Phase 処理も整理しました。
(例:毎回生成する運用をやめ、事前生成してリポジトリ管理する/CI では生成しない など)


1. pre-commit フックを作成

プロジェクトルートに .githooks/pre-commit を作成します。
このフックは ステージングされた Swift ファイルだけ を対象に SwiftLint を実行し、警告があればコミットを止めます。

#!/bin/bash
set -e

echo "Running SwiftLint on staged Swift files..."

# ステージングされた .swift ファイルを取得(追加・変更・コピーのみ)
SWIFT_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.swift$' || true)

# Swift ファイルがない場合は何もせず終了
if [ -z "$SWIFT_FILES" ]; then
  echo "No Swift files staged for commit."
  exit 0
fi

# SwiftLint がインストールされているか確認
if ! command -v swiftlint >/dev/null 2>&1; then
  echo "Error: SwiftLint not found. Please install via 'brew install swiftlint'"
  exit 1
fi

# strict モードで実行(警告もエラー扱い)
echo "$SWIFT_FILES" | xargs swiftlint lint --strict

echo "SwiftLint check passed!"

これにより、

  • 変更ファイルのみをチェック
  • 警告もエラー扱い
  • 問題があればコミットが止まる

という挙動になります。

詳細なセットアップ手順(Makefile や .swiftlint.yml の設定など)は、別記事で紹介する予定です。

まとめ

Xcode Cloud のテスト時間が長くなっていた原因は、
テストそのものではなく Build Phase に集約された重い処理 でした。

Xcode Cloud は毎回クリーンな環境で実行されるため、

  • Build Phase に何を置くか
  • どこでコード品質を担保するか

を整理しないと、簡単に実行時間が膨らみます。

今回の対応では、

  • SwiftLint を Build Phase から外す
  • CI ではビルドとテストに集中させる
  • 品質チェックは pre-commit で担保する

という役割分担にすることで、
テスト時間を 約 49 分 → 約 19 分 まで短縮できました。

Xcode Cloud は「入れれば速くなる仕組み」ではありませんが、
クリーン環境前提で構成を見直すことで、十分実用的な CI になります。

これから Xcode Cloud を導入する場合は、
「CI で何をやらないか」 を先に考えてみるのがおすすめです。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?