Continuous Integration (CI) — その概要、原則、自動化のセットアップ

著者: IT Sectr 公開日: 2026-04-11 読了時間: 10 分

Continuous Integration(CI)は、チームメンバー全員が1日に少なくとも1回は自分の変更を共有リポジトリに統合し、各統合が自動ビルドとテストによって検証される開発プラクティスです。CIはコードの競合やリグレッションエラーを早期に発見し、修正コストを削減します。Puppet State of DevOps Report、2025によると、CIを導入しているチームは、自動化していないチームに比べてバグ修正が4倍高速です。

重要ポイント

  • Continuous Integration — 各統合を自動検証する頻繁なコードマージのプラクティス
  • 自動ビルドとプッシュごとのテストにより、コミット後数分でエラーを発見
  • Fail fast — 即時フィードバックのために最速のチェックを最初に実行する原則
  • CIサーバー(Jenkins、GitHub Actions、GitLab CI)はビルド環境を開発者のマシンから分離
  • モバイル開発では、ビルドサイクルが長く設定も多いためCIが必須

Continuous Integrationとは

Continuous Integration(CI)は、複数の貢献者からのコードを単一のコードベースに統合するプロセスを自動化する開発方法論です。この用語は2000年代初頭にMartin Fowlerによって、“統合地獄”を防ぐための一連のプラクティスとして導入されました。統合地獄とは、開発者が何週間も孤立して作業し、変更をマージする際に無数の競合が発生し、手動での解決に数日を要する状況です。

CIが解決する問題

CIがない場合、開発者は機能を完成させ、変更をmainブランチにマージしようとすると、同僚が同じファイルを変更していたことに気づきます。競合の解決には数時間かかり、多くの場合、動作中のコードが壊れます。CIはこの問題を、1日に複数回の統合を強制することで解決します。統合の頻度が高いほど、競合が少なくなり、解決も容易になります。実際の経験では、毎日統合すれば競合解決に数分しかかかりませんが、毎週の統合では数時間かかります。

CIの経済効果

IBM Systems Sciences Instituteによると、コーディング段階でのバグ修正コストは25ドル、テスト段階では100ドル、本番段階では2,500ドルです。CIは欠陥検出を可能な限り左にシフト(shift left)し、修正がほぼ無料であるコミット段階でエラーを発見します。CIを導入しているチームはデバッグに平均15%の時間を費やすのに対し、CIのないチームは35%を費やしています。

Continuous Integrationの基本原則

Martin Fowlerは、テクノロジースタックに関係なく関連性を保つCIの主要なプラクティスを定義しました。これらの原則に従うことで、CIが官僚的な負担ではなく価値をもたらすことが保証されます。モバイル開発では追加の要件が課されますが、核となる部分は変わりません。

単一リポジトリ

すべてのプロジェクトコードは、統一されたバージョン管理システム(Git)を備えた単一のリポジトリに保存されます。単一の真実源により、機能がフォークで開発され、何週間もメインのコードベースと同期されない状況が排除されます。モバイルプロジェクトでは、Android、iOS、バックエンド部分が1つのリポジトリ(モノレポ)に格納されるか、共有バージョンスキームを持つ個別のリポジトリに格納されることを意味します。

自動ビルド

プロジェクトのビルドは単一のコマンドで実行可能でなければなりません。Androidの場合は./gradlew assembleDebug、iOSの場合はxcodebuildまたはfastlane buildです。ビルドスクリプトは再現性を検証します。CIサーバーでのビルドは開発者のマシンと同じ結果を生成する必要があります。環境の差異は、コンテナ化またはIaC(Infrastructure as Code)によって排除されます。

自動テスト

ビルド後、すべてのレベルのテスト(ユニット、統合、UI)が実行されます。テストが失敗した場合、コミットは無効と見なされます。グリーンステータスの維持はチーム全体の責任です。モバイルプロジェクトでは、高速テスト(コミットごとに5分以内で実行)と低速テスト(実機でのUIテスト、実行頻度は低い)が分けられることがよくあります。

kotlin
// CI対応レポート付きユニットテストの例
class LoginViewModelTest {

    private val repository = mock<AuthRepository>()
    private val viewModel = LoginViewModel(repository)

    @Test
    fun loginWithValidCredentials_success() {
        val email = "test@example.com"
        val password = "ValidPass123"

        whenever(repository.login(email, password))
            .thenReturn(Result.success(User("token-xyz")))

        val result = viewModel.login(email, password)

        assertEquals(LoginState.Success, result)
        verify(repository).login(email, password)
    }
}

Fail fastと透明性

CIの結果はチーム全体に公開されます。誰でもどのコミットがビルドを壊したかを確認できます。透明性は責任の文化を生み出します。開発者はプッシュ前に変更を確認し、壊れたビルドを順番を待たずに修正します。CIサーバーはビルドステータスの変更時にSlackやTelegramに通知を送信します。

CIシステムの構成要素

完全なCIシステムは、相互に作用する複数の構成要素で構成されています。各コンポーネントは、トリガーからレポートまでのパイプラインの一部を担当します。CIアーキテクチャを理解することは、問題の診断とパフォーマンスの最適化に役立ちます。

CIサーバー

ビルドキュー、リソース割り当て、結果公開を管理する中央コンポーネント。CIサーバーはクラウドベース(GitHub Actions、GitLab CI、CircleCI)またはセルフホステッド(Jenkins、TeamCity)にできます。サーバーはwebhookまたはポーリングを介してリポジトリの変更を監視し、プッシュまたはプルリクエストごとにパイプラインをトリガーします。

ランナーとエージェント

ランナーはビルドタスクを実行する仮想マシンまたは物理マシンです。クラウドCIでは、ランナーはプロバイダーによって提供され、使用時間に応じて課金されます。セルフホステッドランナーは自社のインフラにインストールされ、メンテナンスが必要です。iOSビルドにはmacOSランナー、AndroidビルドにはLinuxまたはWindowsが必要です。

アーティファクトとキャッシュ

ビルド後、CIシステムはアーティファクト(APK、IPA、テストレポート)をストレージに保存します。これらはダウンロードとデプロイに利用できます。実行間の依存関係のキャッシュ(Gradleキャッシュ、CocoaPodsキャッシュ)により、後続のビルドが3~5倍高速化されます。

コンポーネント目的
CIサーバービルドのオーケストレーションJenkins、GitHub Actions
ランナータスクの実行iOS用macOSランナー
リポジトリコードの保存GitHub、GitLab
アーティファクトストレージアーティファクトの保存AWS S3、Artifactory
通知チームへの通知Slack、Telegram、メール

モバイルアプリケーションのContinuous Integration

モバイル開発には、Webやバックエンドプロジェクトとは異なるCIの特別な要件があります。長いビルド時間(Androidは3~15分、iOSは5~20分)、複数のアーティファクトタイプ(APK、AAB、IPA)、署名と難読化の必要性 — これらすべてにCIパイプラインのカスタマイズ設定が必要です。

Android CIパイプライン

Androidの典型的なCIには以下が含まれます。リンティング(ktlint、detekt)と静的解析、JUnitとMockKによるユニットテスト、デバッグおよびリリースAPK/AABのビルド、CI内のエミュレーターでのインストルメンテーションテスト、アーティファクトの公開。Gradleキャッシュは繰り返しのビルドを高速化します。これがないと、各ビルドが依存関係を新たにダウンロードし、3~5分をロスします。

iOS CIパイプライン

iOS CIでは、Swift/Objective-CコードをコンパイルするためにmacOSランナーが必要です。パイプラインには以下が含まれます。CocoaPodsまたはSPM依存関係のインストール、スタイルチェックのSwiftLint、XCTestによるユニットテスト、IPAビルド、Fastlane matchによるコード署名、TestFlightへのアップロード。データセンターのMac miniまたはMac上のセルフホステッドランナーは、クラウドmacOSランナーの代替手段です。

クロスプラットフォームプロジェクト(Flutter、React Native)

FlutterとReact Nativeは両プラットフォームのネイティブビルドにコンパイルされます。CIは2つのランナーをサポートする必要があります。Androidビルド用のLinuxとiOSビルド用のmacOSです。最適な戦略は分割パイプラインです。LinuxランナーでAndroidビルド、macOSランナーでiOSビルドを行い、両方のアーティファクトを単一のリリースに統合します。

CIツールの比較

CIツールの選択は、チームの規模、必要なパフォーマンス、予算、テクノロジースタックによって異なります。以下は、モバイル開発に焦点を当てた人気ソリューションの比較です。セルフホステッドソリューションは制御を提供しますが管理が必要であり、クラウドソリューションは利便性を提供しますが設定が制限されます。

GitHub Actions

パブリックリポジトリでは無料(2000分/月)。GitHub ActionsはAndroid(gradle/actions)およびiOS(apple-actions)向けの既製アクションのエコシステムを提供します。欠点は、macOSランナーが有料プランでのみ利用可能なことです。オープンソースや既にGitHubを使用している小規模チームに最適です。

Jenkins

セルフホステッドのオープンソースCIサーバー。JenkinsはGroovy Pipelineを介して設定され、数百のプラグインをサポートし、任意のハードウェアで動作します。セットアップとメンテナンスにはDevOpsエンジニアが必要です。インフラの制御が重要なエンタープライズセグメントで人気があります。

GitLab CI

オープンなランナーアーキテクチャを備えたGitLabに組み込まれたCI/CD。GitLab CIでは、無料プランで独自のランナー(macOSを含む)を使用できます。YAML設定はGitHub Actionsより強力ですが、習得が難しいです。GitLabを単一のDevOpsプラットフォームとして使用するチームに適しています。

CircleCI

速度に重点を置いたクラウドCI。CircleCIはDocker、macOS、Androidイメージをサポートし、依存関係を自動的にキャッシュします。料金はクレジットベースで、小規模チームにはGitHub Actionsより高価ですが、最適化されたランナーにより高速です。速度要件のある本番プロジェクトに推奨されます。

CIセットアップ例

GitHub Actionsを使用したAndroidプロジェクトのCIセットアップを考えてみましょう。パイプラインは、mainブランチへのプッシュおよびプルリクエストごとに静的解析、ビルド、テストを実行します。最小構成では15分かかり、外部サービスは必要ありません。

yaml
name: Android CI
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: 17
          distribution: temurin
      - run: ./gradlew ktlintCheck detekt

  unit-tests:
    needs: lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: 17
          distribution: temurin
      - uses: gradle/actions/setup-gradle@v4
      - run: ./gradlew testDebugUnitTest
      - uses: actions/upload-artifact@v4
        with:
          name: test-results
          path: app/build/reports/tests/

パイプラインは2つの並列ジョブで構成されます。lint(静的解析を実行)とunit-tests(lintに依存 — リンティングが失敗した場合、テストは実行されません)。unit-testsジョブはテストレポートをアーティファクトとしてアップロードします。チームはファイルをローカルにダウンロードせずにGitHub Actions UIで確認できます。

CI前のローカルチェック

些細なエラーによるCIの失敗を防ぐために、Gitのpre-push hookまたはGradleタスクを設定し、同じチェックをローカルで実行します。例:./gradlew ktlintCheck detekt testDebugUnitTest。ローカルチェックに3分以上かかる場合は、高速(リンター)と低速(テスト)に分割し、高速チェックは各コミットの前に、低速チェックはプッシュの前にのみ実行します。

よくある質問

CIとCD(Continuous Delivery)の違いは何ですか?

CIはコードの統合と検証(ビルド+テスト)に焦点を当てていますが、CDはデプロイの自動化を追加します。CIはコードが正しいことを確認します。CDはその正しいコードがユーザーに届けられることを保証します。CIはCDの前提条件ですが、CDはCIなしでは機能しません。

コードはどのくらいの頻度で統合すべきですか?

最低頻度は開発者1人あたり1日1回です。理想的なプラクティスは、作業の論理的な単位が完了するたび(1~4時間ごと)にリポジトリにプッシュすることです。統合の頻度が高いほど、競合が少なくなり、解決も容易になります。統合の間隔が2日以上空いている場合、CIを使用していません。

モバイルプロジェクトにはどのCIが最適ですか?

AndroidにはGitHub Actions(無料、設定が簡単)またはGitLab CI(独自ランナー)が最適です。iOSにはCircleCI(macOSサポートが最も充実)またはBitrise(モバイルプロジェクト向け特化CI)です。クロスプラットフォームプロジェクトには、2つのランナー(Linux + macOS)を持つGitLab CIです。

CIにUIテストは必要ですか?

はい、ただし条件付きです。UIテストは低速(10~30分)で不安定(flaky)です。最適な戦略は、プッシュごとに高速テスト(ユニット+統合)を実行し、UIテストはプルリクエスト、夜間、またはリリース前に実行することです。UIテストにはDevice FarmまたはCI内のエミュレーターを使用してください。

CIが実際に機能していることを確認するには?

効果的なCIの指標:ビルド時間が15分未満、グリーンビルドの割合が85%超、障害からの平均復旧時間が30分未満。ビルドが頻繁に失敗する場合、CIは役立たずむしろ妨げになっています。テストを見直し、flakyテストを削除し、依存関係を最適化し、ビルド時間を短縮してください。

まとめ

  • Continuous Integration — 各変更の自動ビルドとテストを伴う毎日のコード統合プラクティス
  • CIの基本原則:単一リポジトリ、自動ビルド、自動テスト、結果の透明性
  • Fail fastはチームの時間を節約:リンターとユニットテストが最初に実行され、UIテストは必要なときに
  • CIツールはコストと機能が異なる:GitHub Actionsはスタートアップ向け、Jenkinsはエンタープライズ向け
  • モバイルCIには特別な考慮事項が必要:長いビルド時間、コード署名、AndroidとiOSで異なるアーティファクト
  • Apple SiliconランナーはIntelランナーと比較してiOSビルドを最大2倍高速化
  • 推奨:シンプルなCIパイプライン(リンター+ユニットテスト)から始め、徐々に拡張 — UIテスト、Device Farm、自動デプロイ

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください