Bitrise 初心者が細かい作業の自動化をやってみた話

https://cdn-ak.f.st-hatena.com/images/fotolife/g/go_dev/20240418/20240418124629.jpg

はじめに

JapanTaxi では CI環境 として Travis CI を使っていましたが、今年からモバイル系のチームは Bitrise に移行しました。導入に関してはSETチームの方で環境準備をしてくれたものを各チームで利用しています。

私個人としては今まで自動化に関する取り組みをしてきたことは無かったのですが、日々開発する中で「こんなこと出来たら便利だな〜」ぐらいの気持ちで Bitrise と戯れてみました。

iOSチーム内で利用している WorkFlow

iOSチームでは既に様々な作業の自動化を行っているので紹介したいと思います。

リリースに関するもの

  • Fabric Beta への配信
    • リリース前のQAを行うために、 Fabric Beta にアプリを配信する WorkFlow です。リリース用の branch が切られたのをトリガーにしています。
  • TestFlight への配信
    • アプリを申請するために App Store Connect にバイナリをアップロードする WorkFlow です。Slackのコマンドから WorkFlow と リリース用の branch を指定して実行しています。

開発に関するもの

  • Unit Test の実行
    • branch が Push されたのをトリガーに Unit Test を実行する WorkFlow です。 Bitrise はトリガーになっているだけで、実行自体は fastlane で行っています。
  • Danger による Pull Request のチェック
    • SwiftLint を掛けたり、環境周りのファイルに更新があった場合に警告を出す WorkFlow です。Pull Request の作成をトリガーに しています。

https://cdn-ak.f.st-hatena.com/images/fotolife/g/go_dev/20240418/20240418124625.jpg

更新に関するもの

  • CocoaPods, Carthage, gem の更新
    • スケジューリング機能を利用して毎晩更新のチェック行い、更新があると Pull Request を作成する WorkFlow です。こちらもBitrise はトリガーになっているだけで、更新処理自体は fastlane で行っています。
  • bitrise.yml のリポジトリ反映
    • bitrise.yml をダウンロードし変更があった場合にはPull Request を作成する WorkFlow です。こちらも毎晩実行されています。

今回追加した2つの自動化

基本的に週1のサイクルでリリースをしているのですが、リリース作業の中で手動で行っているものがまだまだあり、ちょっとした作業なのですが毎週やるとなると面倒だなと感じることがあったので、自動化してみようと思いました。

1. branch の保護設定とその削除

運用として、リリース用の branch に対して直接 Push 出来ないように保護設定を掛けてます。branch が作成されたら保護設定を入れて、リリースしたら削除する作業を手動で行っていました。

branch の保護設定を自動化

やったことはシンプルで、リリース用の branch が push されたら GitHub API を叩くだけです。

curl -X PUT https://api.github.com/repos/:owner/:repo/branches/$BITRISE_GIT_BRANCH/protection \
-H "Authorization: token $GITHUB_ACCESS_TOKEN" \
-H "Accept: application/vnd.github.luke-cage-preview+json" \
-d @- << EOF
{
  "required_status_checks": {
    "strict": false,
    "contexts": [
      "ci/bitrise/********/pr"
    ]
  },
  "enforce_admins": true,
  "required_pull_request_reviews": {
    "dismiss_stale_reviews": true,
    "require_code_owner_reviews": false,
    "required_approving_review_count": 1
  },
  "restrictions": null
}
EOF

branch 保護の削除を自動化

こちらもシンプルでリリース後に Tag を作成する運用を行っており、 Tag 作成をトリガーに GitHub API を叩くだけです。

branchName="release/$BITRISE_GIT_TAG"

curl -X DELETE https://api.github.com/repos/:owner/:repo/branches/$branchName/protection \
-H "Authorization: token $GITHUB_ACCESS_TOKEN"

2. リリース branch 作成の自動化

Before

Beta への配信部分の自動化は出来ていましたが、バージョンをインクリメントして branch を push するまでにごにょごにょ手動の作業が入っていました。

https://cdn-ak.f.st-hatena.com/images/fotolife/g/go_dev/20240418/20240418124628.jpg

After

Slack からコマンドを実行するだけでリリース用の branch が GitHub に pushされるように自動化しました。push 後は今まで通りの動きで Fabric Beta に配信されます。

https://cdn-ak.f.st-hatena.com/images/fotolife/g/go_dev/20240418/20240418124627.jpg

Slack からWorkFlow の起動

/japantaxi-ios w:code-freeze | b:maseter | ENV[RELEASE_APP_VERSION]: 4.4.11 と入力することで Bitrise のWorkFlowを呼出しています。

  • w:
    • WorkFlow の指定になります。今回は code-freeze という名前にしました。
  • b:
    • branch の指定になります。リリースは必ず master からbranch を切るので値は master 固定になります。
  • ENV[RELEASE_APP_VERSION]:
    • インクリメントで指定するバージョンアップ情報になります。こちらでコントロールしたいので、パラメーターとして渡す方法を取りました。

バージョンのインクリメント

fastlane に新しくレーンを追加しました。標準でバージョンのインクリメントはあるのですが、info.plist を更新する仕様になっており、JapanTaxi アプリでは xcconfig で管理していたので使えませんでした。今回は plugin を入れて解決しました。

  • fastlane-plugin-xcconfig
    • fastlaneに3つのアクションを追加し、xcconfigファイルを読み取り、更新を簡単にやってくれます。
    • 以下のような指定で xcconfig を簡単に更新することが出来ます。
root_directory = ENV['ROOT_DIRECTORY']
release_app_version = ENV['RELEASE_APP_VERSIION']
xcconfig_path ='sampleApp/Configuration/Base.xcconfig'
update_xcconfig_value(
    path: "#{root_directory}/#{xcconfig_path}",
    name: "APP_VERSION",
    value: release_app_version
)

https://cdn-ak.f.st-hatena.com/images/fotolife/g/go_dev/20240418/20240418124626.jpg

↑初めて本番で動かした時

おわりに

既に動いている WorkFlow があったので、それを真似つつポチポチ Step を繋げていけば自動化出来ちゃう Bitrise は素晴らしいですね。今回で完全に理解することが出来ました。(嘘)

他にも GitHub のリリース作成を自動化したり、細かい部分でいくつかやってみたいことが出来ました。

また、今回触ってみて既存の WorkFlow で共通している Step 部分が個々に定義されており、メンテナンスしづらい状況になっていいることが分かりました。分割して共通化していくことも進めていきたいです。小さいな改善ですが今後も継続して取り組んでいき、開発の効率化をしていきたいと思います。