iOS・Androidで、CI/CD環境を作る際の選択肢

# Overview

* iOS・AndroidでCI/CDやDevOps環境を作成する際に、使えそうなツールをまとめたものです。

# ツールリスト

[※WEBページ版](https://gist.githack.com/Tea-and-Coffee/4cd999f960aebebb212da82ae28ce9ae/raw/c9747bdbd8663cd2484081af0caa5fe4fbd79d31/mobile_ci_cd_table.html)

<style>
  table td {
    background: #eee;
  }
  table tr:nth-child(even) td {
    background: #fff;
  }
  table tr:first-child td {
    background: #0ff;
  }
</style>
<table border="1" cellspacing="2" cellpadding="4">
  <tbody>
    <tr>
      <td>用途</td>
      <td>分類</td>
      <td>小項目</td>
      <td colspan=9>サービス名</td>
    </tr>
    <tr>
      <td>構成管理ツール</td>
      <td></td>
      <td></td>
      <td>Ansible + Ansible Container</td>
      <td>Chef</td>
      <td>Puppet</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td rowspan=3>コンテナクラスタ</td>
      <td>コンテナ</td>
      <td></td>
      <td>Docker</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>オーケストレーション</td>
      <td></td>
      <td>Docker Compose + Docker Swarm + Docker Machine</td>
      <td>Kubernetes</td>
      <td>Amazon ECS</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>OS</td>
      <td></td>
      <td>CentOS</td>
      <td>Ubuntu</td>
      <td>maxOS</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td rowspan=7>インフラ</td>
      <td>クラウドサーバー</td>
      <td></td>
      <td>Amazon Web Services (AWS)</td>
      <td>Google Cloud Platform</td>
      <td>Microsoft Azure</td>
      <td>IBM Cloud</td>
      <td>Alibaba Cloud</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>デバッギング</td>
      <td></td>
      <td>Rookout</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>ロギング</td>
      <td></td>
      <td>Fluentd</td>
      <td>Redash</td>
      <td rowspan=2>Elasticsearch + Kibana</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>モニタリング</td>
      <td></td>
      <td>Datadog</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>インシデントライフサイクル管理</td>
      <td></td>
      <td>PagerDuty</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td rowspan=2>コラボレーション</td>
      <td>Issues</td>
      <td>Jira</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>Chat</td>
      <td>Slack</td>
      <td>HipChat</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td rowspan=2>レポジトリー</td>
      <td>パブリック</td>
      <td></td>
      <td rowspan=2>GitHub</td>
      <td>GitHub Gists</td>
      <td rowspan=2>GitLab</td>
      <td rowspan=2>Bitbucket</td>
      <td rowspan=2>Azure Repos</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>プライベート</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td rowspan=2>パッケージマネージャー</td>
      <td>パブリック</td>
      <td>iOS</td>
      <td>CocoaPods</td>
      <td>Swift Package Manager (SwiftPM)</td>
      <td>Carthage</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>プライベート</td>
      <td>iOS</td>
      <td>CocoaPods Private Specs</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td rowspan=2>パッケージ・アーティファクトレポジトリー</td>
      <td>パブリック</td>
      <td></td>
      <td>Maven Central Repository</td>
      <td>GitHub Package Registry</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>プライベート</td>
      <td></td>
      <td>Sonatype Nexus Repository Manager</td>
      <td>github/maven-plugins</td>
      <td>JFrog Artifactory</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td rowspan=4>CI</td>
      <td>個人・小規模チーム</td>
      <td>クラウドサーバー</td>
      <td rowspan=3>Bitrise</td>
      <td rowspan=3>CircleCI</td>
      <td rowspan=2>GitHub Actions<br>(GitHubホストランナー又はセルフホストランナー)</td>
      <td rowspan=3>Xcode Cloud (Beta)</td>
      <td rowspan=2>Travis CI</td>
      <td rowspan=2>Buildkete</td>
      <td rowspan=2>Cirrus CI + Anka Cloud MacStadium</td>
      <td rowspan=2>Azure Pipelines</td>
      <td>Visual Studio App Center</td>
    </tr>
    <tr>
      <td rowspan=2>エンタープライズ</td>
      <td>クラウドサーバー</td>
      <td></td>
    </tr>
    <tr>
      <td>オンプレミスサーバー</td>
      <td>GitHub Actions + <a href="https://docs.github.com/ja/actions/hosting-your-own-runners/about-self-hosted-runners">セルフホストランナー</a></td>
      <td></td>
      <td></td>
      <td></td>
      <td>Azure Pipelines + <a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/osx-agent?view=azure-devops">Self-hosted macOS agents</td>
      <td></td>
    </tr>
    <tr>
      <td>個人 ~ エンタープライズ</td>
      <td>クラウド + オンプレミスサーバー</td>
      <td>Concourse CI</td>
      <td>GitLab CI/CD</td>
      <td>Jenkins</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>CD</td>
      <td>Beta配布</td>
      <td></td>
      <td>App Store Connect + TestFlight</td>
      <td>Firebase App Distribution</td>
      <td>DeployGate</td>
      <td>Bitrise Ship</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td rowspan=2>ビルド自動化ツール</td>
      <td>iOS</td>
      <td></td>
      <td>fastlane</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>Android</td>
      <td></td>
      <td>Gradle</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td rowspan=6>静的コード解析</td>
      <td rowspan=3>コーディングスタイル</td>
      <td>Swift</td>
      <td>realm/SwiftLint</td>
      <td>sleekbyte/tailor</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>Objective-C</td>
      <td>oclint/oclint</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>Kotlin</td>
      <td>shyiko/ktlint</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>バグ・脆弱性・コードの匂い</td>
      <td></td>
      <td rowspan=2><a href="https://www.sonarqube.org/">SonarQube</a>,<br><a href="https://sonarcloud.io/">SonarCloud</a></td>
      <td rowspan=2><a href="https://www.codacy.com/">Codacy</a><br><a href="https://support.codacy.com/hc/en-us/articles/207994735-Supported-Languages">(※Not supported Objective-C)</a></td>
      <td><a href="https://codeclimate.com/">Code Climate</a></td>
      <td><a href="https://www.shiftleft.io/index.html">ShiftLeft</a></td>
      <td><a href="https://hub.codebeat.co/">codebeat</a></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>コードカバレッジ</td>
      <td></td>
      <td>Codecov</td>
      <td>Coveralls</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>UI</td>
      <td>iOS<br>(Interface builder)</td>
      <td>fastred/IBAnalyzer</td>
      <td>IBDecodable/IBLinter</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td rowspan=3>コードレビュー自動化</td>
      <td>Linterコラボ</td>
      <td></td>
      <td>reviewdog/reviewdog</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td rowspan=2>PRエチケット</td>
      <td>Swift</td>
      <td>danger/swift</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>Kotlin</td>
      <td>danger/kotlin</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td rowspan=3>テスト</td>
      <td rowspan=2>実機テスト</td>
      <td>iOS</td>
      <td rowspan=2><a href="https://firebase.google.com/docs/test-lab/android/available-testing-devices?hl=ja">Firebase Test Lab</a></td>
      <td rowspan=2><a href="https://aws.amazon.com/jp/device-farm/device-list/">AWS Device Farm</a></td>
      <td rowspan=2><a href="https://appkitbox.com/devicelist/">Remote TestKit</a></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>Android</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>テスト管理</td>
      <td>TestRail</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
  </tbody>
</table>

## 説明

### CI

* Bitrise
    * サーバーメンテナンスが不要な`クラウド型`と、メンテナンスが必要ながらセキュアな`オンプレミス型`を選択出来る。`i/Aともにサポート`している。
    * CircleCIと比較されやすい。
    * `ジョブ作成方法はGUIなのでとっつきやすい`と思います。その反面GUIなので、大企業での一括導入の場合、導入推進者は苦労するかも知れません。
    * bitrise.yml
    * `GitHubとGitLabとBitbucketをサポート`しており、そのどれかでレポジトリ管理している必要があります。
    * 静的なパブリックIPアドレスが提供されている。
        * [Virtual machines - Bitrise Docs](https://devcenter.bitrise.io/infrastructure/virtual-machines/)
    * 開発規模は、`個人〜小中だと相性がいい`と思います。
    * `料金体制は月額`です。
* CircleCI
    * サーバーメンテナンスが不要な`クラウド型`と、メンテナンスが必要ながらセキュアな`オンプレミス型`を選択出来る。`i/Aともにサポート`している。
    * Bitriseと比較されやすい。サービス内容はTravis CIに似ている。
    * `ジョブ作成方法はYAML`です。YAMLなので記述し易く、gitで管理されます。
    * `GitHubとBitbucketをサポート`しており、そのどちらかでレポジトリ管理している必要があります。
    * 静的なパブリックIPアドレスは、提供されていない。(提供するか検討はされている)
         * [IP Address ranges for whitelisting/Do you have static IP addresses available? – CircleCI Support Center](https://support.circleci.com/hc/en-us/articles/115014372807-IP-Address-ranges-for-whitelisting-)
    * 開発規模は、`中小企業〜大規模だと相性がいい`と思います。個人でもたくさんアプリリリースするなら有り。
    * `料金体制は月額`です。
    * CircleCIのビルド傾向を解析したい場合は、[Buildtrakr](https://www.buildtrakr.com/?mkt_tok=eyJpIjoiWmpSbU1qZzBaVE13TVRSayIsInQiOiJKWWZMa0xkM3l0YnNuczc1enF3UGtYU1VBODVEeHhWbjg2Ym83cUVnUDBvYU1HZjN0WFRGUGlKRm1iRWNsTWpwVGN2MGVHdTJ3MUx1czdJSVhOSVg5a055d3NIcndYVmxnXC81b3FwNWpTUE5hSHVFcTgyaTFjcllka3hsWlpiMTYifQ%3D%3D) が良さそう。
* Travis CI
    * サーバーメンテナンスが不要な`クラウド型`が選択出来る。`i/Aともにサポート`している。
    * CircleCIと比較されやすく、両者は似ている。
    * `ジョブ作成方法はYAML`です。YAMLなので記述し易く、gitで管理されます。
    * `GitHubをサポート`しており、GitHubでレポジトリ管理している必要があります。
    * 開発規模は、`中小企業〜大規模だと相性がいい`と思います。個人でもたくさんアプリリリースするなら有り。
    * `料金体制は月額`です。
* Cirrus CI + Anka Cloud MacStadium
    * 執筆予定
* Azure Pipelines
    * 執筆予定
* Visual Studio App Center
    * 執筆予定
* Concourse CI
    * CI環境構築が必要。
    * Androidのビルドのみの場合、`クラウド型`か`オンプレミス型`になる。
    * iOSをビルドする場合、`オンプレミスオンリー`か`クラウドとオンプレミス複合環境`になる。
        * AWSなどのクラウドサーバーで、macOS環境を提供している会社がないため、macOSマシンを自前する必要がある。
    * Jenkinsの後発です。
    * `ジョブ作成方法はYAML`です。YAMLなので記述し易く、gitで管理されます。
    * `CI環境構築とメンテナンスを自前で行えるのがメリットであり、デメリットでもある`と思います。
    * 開発規模は、`中小企業〜大規模だと相性がいい`と思います。
    * 完全オンプレミスの場合、初期費用としてサーバー購入費用がかかります。ランニングコストはさほどかかりませんが、`メンテナンスを行うエンジニアを常駐する必要があります`。
* Jenkins
    * CI環境構築が必要。
    * Androidのビルドのみの場合、`クラウド型`か`オンプレミス型`になる。
    * iOSをビルドする場合、`オンプレミスオンリー`か`クラウドとオンプレミス複合環境`になる。
        * AWSなどのクラウドサーバーで、macOS環境を提供している会社がないため、macOSマシンを自前する必要がある。
    * CIの本家に当たり、Concourse CIと比較されます。バージョンアップは現在も頻繁に行われている。
    * `ジョブ作成方法はGUIです`。`柔軟性にはすごく長けているのですが、設定項目が多く属人化し易い`です。
    * `CI環境構築とメンテナンスを自前で行えるのがメリットであり、デメリットでもある`と思います。
    * 開発規模は、`中小企業〜大規模だと相性がいい`と思います。
    * 完全オンプレミスの場合、初期費用としてサーバー購入費用がかかります。ランニングコストはさほどかかりませんが、`メンテナンスを行うエンジニアを常駐する必要があります`。
* GitLab CI/CD
    * CI環境構築が必要。
    * Androidのビルドのみの場合、`クラウド型`か`オンプレミス型`になる。
    * iOSをビルドする場合、`オンプレミスオンリー`か`クラウドとオンプレミス複合環境`になる。
        * AWSなどのクラウドサーバーで、macOS環境を提供している会社がないため、macOSマシンを自前する必要がある。
    * 開発規模は、`中小企業〜大規模だと相性がいい`と思います。
    * `レポジトリ管理とCIを全て、GitLabにしたい場合はメリットがある`と思います。
    * レポジトリ管理のGitLabと同じライセンスで利用できます。
    * 完全オンプレミスの場合、初期費用としてサーバー購入費用がかかります。ランニングコストはさほどかかりませんが、`メンテナンスを行うエンジニアを常駐する必要があります`。
* [Nevercode (Beta)](https://nevercode.io/)
    * [Authenticating repository access](https://developer.nevercode.io/docs/authenticating-repository-access)
    * 執筆予定
* [Semaphore](https://semaphoreci.com/product)
    * 執筆予定
* [Buildkite](https://buildkite.com/)
    * 執筆予定

### コードレビュー自動化

* [reviewdog/reviewdog](https://github.com/reviewdog/reviewdog)
    * linterの解析結果を一行単位で、自動的にPRにコメントしてくれる。
    * 作成者による開発経緯とライブラリ紹介
        * [reviewdog を飼ってコードレビューや開発を改善しませんか - haya14busa](http://haya14busa.com/reviewdog/)
* danger
    * RP作成時のルールやエチケットをコンフィグファイルに記述することで、違反がないか自動的にチェックしてくれる。
        * [danger/swift](https://github.com/danger/swift)
        * [danger/kotlin](https://github.com/danger/kotlin)