MoTLab -GO Inc. Engineering Blog-MoTLab -GO Inc. Engineering Blog-

iOS アプリにおける GitHub Actions 活用術

iOS
May 23, 2022

タクシーアプリ「GO」の iOS アプリを開発している今入です。本記事では GitHub Actions の特徴を紹介し、それを iOS アプリ開発にどう活かしているのかについて紹介します。


はじめに

タクシーアプリ「GO」の iOS アプリでは、CI サービスとして Bitrise と GitHub Actions を利用しています。もともと Bitrise のみで運用していましたが、GitHub Actions が登場して以来、一部の Workflow を GitHub Actions に移行したものもあります。

どのような使い分けをしているのか、iOS アプリ開発において GitHub Actions をどのように活用しているのかについて、実例を交えて以下に紹介します。

GitHub Actions の特徴

まずはじめに GitHub Actions 特徴について紹介します。

1.豊富なトリガー

GitHub Actions は GitHub の一部の機能として動作していることもあり、GitHub との相性が抜群です。GitHub 上でのさまざまな操作を GitHub Actions の Workflow を動作させるためのトリガーとして利用することができます。

たとえば、以下のように記述することで「Pull Request がマージされたとき」というトリガーを表現することができます。

on:
  pull_request:
    types: [closed]

  ...

  if: github.event.pull_request.merged == true

on で特定のトリガーを指定します。 代表的なものとしては Push のタイミングをトリガーにできる push や、手動実行を行う workflow_dispatch などがあります。schedule を利用すれば、毎週日曜日の午前0時に実行するといった定期的なスケジューリングも可能です。

トリガーの中には types でいくつかの種類に分けられているものもあり、さらに詳細の状態を指定することができます。

その他にも if 構文でさまざまな条件を指定することで、より詳細なトリガーを作成することができるでしょう。その他、トリガーに関する情報は GitHub Actions のドキュメントをご参考ください。

このように、GitHub 上の多種多様な操作をトリガーに Workflow を実行することができるのは GitHub Actions の強みの 1 つといえます

2.GitHub を容易に操作できる

Workflow を実行し、GitHub に対して何かしらの操作を行いたいことがあります。たとえば以下のようなケースが考えられます。

  • 静的解析を実行し、その結果を Pull Request にコメントする
  • 検知された不要なファイルを削除し、Pull Request を作成する
  • 指定された名前でブランチを作成する

通常、外部からこういった GitHub の操作をするためにはアクセストークンが必要となります。自分自身でアクセストークンを発行しそれを利用してもよいのですが、複数人で開発しているプロジェクトの場合は、属人化やセキュリティの観点からそういった運用は望ましくありません。

そこで、共通の Bot アカウントを作成し Bot のアクセストークンを利用したり、GitHub App 経由でアクセストークンを発行するといった運用の仕方があります。属人化やセキュリティの観点ではよくなるものの、管理の手間が発生してしまいます。

GitHub Actions では secrets.GITHUB_TOKEN が用意されており、GitHub の操作をするためのアクセストークンを発行する必要がありません。アクセストークンを発行するための手間や運用コストなどを省くことができ、手軽に GitHub の操作が可能となります。これは他の CI サービスにはない魅力だと思います。 secrets.GITHUB_TOKEN の詳細は GitHub 公式の「GITHUB_TOKENシークレットについて」をご参考ください。

ただし、このアクセストークンに与えられている権限は局所的であるため、GitHub 上のすべての操作ができるわけではありません。 secrets.GITHUB_TOKEN では操作できない処理を行いたい場合は、先述のとおり Bot アカウントのアクセストークンを利用したり GitHub App を作成する必要があります。

「GO」iOS アプリにおける自動化

上記の GitHub Actions の特徴を踏まえ、タクシーアプリ「GO」の iOS アプリでの活用方法を以下に紹介します。

RC ブランチの作成

「GO」では、QA 用のバイナリ配布時に RC ブランチを作成します。RC ブランチの名前には rc-6.0.0 のようなリリースされるバージョン番号が含まれている形になります。

An image from Notion

上記のように、バージョン番号を手動で指定することで、RC ブランチの作成が行えるようにしました。

また、RC ブランチの作成と同時に以下の作業が Workflow 内で行われます。

  • Info.plist 内のバージョンを更新
  • Branch Protections rules の設定
  • Slack へ通知

Workflow 実行時にバージョン番号を指定するので、このバージョンに Info.plist の CFBundleShortVersionString が書き換えられます。

今まで手動で更新して Pull Request を送ってマージをしていましたが、その手間が省かれます。

そして、RC ブランチには直接 Push できないようにするなどの制限を与えたいので Branch Protections rules を GitHub API を通じて設定します。

上記の作業が終わり無事 RC ブランチが作成されたら、Slack にてチームメンバ全員に「rc-6.0.0 が作成されました」といった RC ブランチ作成完了通知がお知らせされます。

それぞれ難しい作業ではありませんが、手動で行うと漏れが発生してしまう可能性があります。こういった複数の作業を誰でも迷いなく確実に行うために CI による自動化を構築しています

コードの整形

「GO」では週次でコードの整形を GitHub Actions 上で行っています。以前は SwiftLint でルールを課していましたが、開発を進めていく中であまり必要性を感じられなくなったため、現在ではコードの整形処理のみの利用になりました。(整形処理は SwiftLint から SwiftFormat や apple/swift-format への乗り換えを検討中。)コードの整形は、Pull Request 単位ではなく、main ブランチに対して週次でまとめて行う運用になっています。

An image from Notion

SwiftLint の実行は、GitHub Action for SwiftLint を利用することで、Linux 環境で動作できるようにしています。GitHub Actions で macOS を利用する場合、Linux に比べて 10 倍のコストがかかるため、コスト面を意識しこのような構成をとりました。

整形処理後、GitHub の API を利用して Pull Request を作成するところまで行われます。

Danger による警告

Pull Request の作成をトリガーに、Danger による静的解析が行われるようにしています。解析内容は不要な定義の指摘で danger-detect_unused_definition を利用しています。

GitHub の操作は Pull Request に対するコメントのみなので、Danger に対して先述の secrets.GITHUB_TOKEN を与えるだけで実行されます。

残された TODO の Issue 化

iOS アプリ開発に限った利用ではありませんが、TODO を Issue 化できる TODO to Issue という Action を利用しています。

指定したブランチに対して push された際に、「// TODO: xxxx」といった TODO コメントが残されていた場合に GitHub の Issue として新規登録してくれます。「labels: 」を付与すればラベルの自動適用も可能です。

また、TODO が解消された際は、該当の Issue を自動的に Close してくれるので管理が楽です。

TODO のまま放置されて必要な処理が実装されないままリリースされてしまったことがあったため、Issue 化することで残されているタスクを意識しやすくしました。特に大規模な案件を開発する際に重宝します。

Bitrise と GitHub Actions の使い分け

「GO」では Bitrise も活用しており、GitHub Actions との使い分けをしています。使い分けの基準は大きく分けて以下の 2 つがあります。

1.一時的なスケジューリングの有無

「今週だけ特定の Workflow を毎日実行したい」「QA 期間が終わるまで Workflow を週次で実行したい」など、期間限定で Workflow のスケジューリングが必要となるケースがあります。そのようなとき、Bitrise を使えば GUI 上で手軽にスケジューリングの追加・変更・削除を行うことができます。

GitHub Actions では、スケジューリング機能が備わっているものの、Wokflow の yml ファイルを更新する必要があったり、そのコードレビューの必要があったりして、気軽にスケジューリングの変更を行うことができません。

そのため、固定化されていないスケジューリングの必要がある処理については Bitrise を利用するようにしています。

2.特定の証明書によるビルドの有無

「GO」の iOS アプリの証明書は基本的に fastlane の match により管理されています。しかし、一部の証明書を手動管理せざるを得ない環境にあるため、Bitrise の Certificates を活用しています。

GitHub Actions には証明書管理の仕組みが備わっていないため、手動での管理をするとなると運用コストが発生します。そのため、手動管理の証明書によるビルド処理が必要なものは Bitrise を利用することになっています。

おわりに

GitHub Actions は GitHub に特化した処理を非常に手軽に扱うことができる CI サービスです。GitHub Actions の特徴を活かせる場面があれば活用してみてはいかがでしょうか。

他にもさまざまな CI サービスがあるので、それぞれの特徴を活かしつつ運用コストのバランスを考えながら使い分けていくのがよいと思います。

また、「MoT x エウレカ 大規模アプリを支えるアプリ開発現場のリアル」にて本記事に関連する内容を登壇しましたので、そちらも合わせてご参考ください。


We're Hiring!

📢
Mobility Technologies ではともに働くエンジニアを募集しています。

興味のある方は 採用ページ も見ていただけると嬉しいです。

Twitter @mot_techtalk のフォローもよろしくお願いします!