コネヒト開発者ブログ

コネヒト開発者ブログ

GitHub ActionsからマニュアルトリガーでBitriseを動かす方法

はじめに

コネヒトでiOSエンジニアをやっているYoshitakaです。

先日、iOSアプリ開発のCI/CD環境を改善するため、これまで一部ローカルから実行していたfastlaneの処理をGitHub ActionsをトリガーにしてBitrise上で実行するように対応したので、一部内容を紹介したいと思います。

改善したこと

ママリのiOSアプリ開発では主にBitrise, fastlane(一部GitHub Actions)を使ってCI/CD環境を構築しております。

Bitrise(fastlane)で実行しているワークフローは以下の通りです。

  • Testの実行
  • App Distributionへの配布
  • App Store Connectへのデプロイ
  • Developer Accountへのデバイス追加

今回の改善ではこれまでローカルで実行していたデバイス追加のワークフローをGitHub ActionsでトリガーしてBitrise上で実行するように対応しました。

この対応によりローカル実行ではApple IDの認証で2FA認証を使っていましたが、Bitrise経由で実行することで推奨されているApp Store Connect API keyを使った認証に切り替えることができました。

やったこと

改善前はfastlaneをローカルから直接実行し対話型でデバイス名とUDIDを入力してデバイス追加をしていました。

  desc "Add test device and update provisioning profile"
  lane :add_device do
    name = UI.ask('Name of device:')
    udid = UI.ask('UDID of device:')
    register_devices(devices: {name => udid})

    match(type: "development", readonly: false, force: true)
  end

これを GitHub ActionsBitrisefastlane と実行するようにします。

GitHub Actionsfastlane としても動くのですが、 App Store Connect API keyの情報は現状Bitriseでのみ使っており、一元化管理したいため今回はBitrise上で動かすようにしています。

GitHub Actions

GitHub Actionsのトリガー部分は、workflow_dispatchinputsを設定することでデバイス名とUDIDを入力できるようにします。

こちらがGitHub ActionsからBitriseをマニュアルトリガーするworkflowです。

on:
  workflow_dispatch:
    inputs:
      device_name:
        description: input device name
        required: true
        type: string
      device_udid:
        description: input device udid
        required: true
        type: string

jobs:
  add_device:
    runs-on: ubuntu-latest
    steps:
    - name: Trigger Bitrise workflow
      env:
        bitrise_api_key: ${{ secrets.BITRISE_API_TOKEN }}
        bitrise_app_slug: "abc0123456789"
      run: |
        curl -H "Authorization: $bitrise_api_key" https://api.bitrise.io/v0.1/apps/$bitrise_app_slug/builds -d \
        '{
          "build_params":{
            "environments":[ 
                {
                    "mapped_to":"DEVICE_NAME",
                    "value":"${{ inputs.device_name }}", 
                    "is_expand":false
                }, 
                {
                    "mapped_to":"DEVICE_UDID",
                    "value":"${{ inputs.device_udid }}", 
                    "is_expand":false
                 }
            ],
            "workflow_id":"add_device"
          },
          "hook_info":{
            "type":"bitrise"
          }
        }'

BitriseのworkflowをGitHub ActionsからトリガーするためBitrise APIを使います。

devcenter.bitrise.io

手順は以下の通り

  • Bitrise API Keyを発行してGitHubのSecretsに保存
  • bitrise_api_keybitrise_app_slugworkflow_idをcurlコマンドに追加
  • inputsで入力した値はBitrise側で使えるようenvironmentsに追加

bitrise_app_slugはBitriseの対象のAPPページのURLで確認できます。 /app/abc0123456789 ← app/から後の値

Bitrise API KeyはBitriseのProfile SettingsSecurityCreate tokenから発行できます。

workflow_idはbitrise.ymlに定義したworkflow名になります。

デバイス名とUDIDをBitrise側に渡してfastlaneで使う方法は、公式ドキュメントを参考にしました。

Bitrise

BitriseではFastfileに定義したデバイス追加のlane(add_device)を実行、結果をslack通知しています。

slack通知の細かい設定方法は公式ドキュメントを確認しても見つからずでしたが、 inputsの値を指定することでconfigが変わり通知内容をカスタマイズできました。configの値はBitriseのLogを見ることで確認できます。

  add_device:
    meta:
      bitrise.io:
        stack: osx-xcode-14.2.x-ventura
    steps:
    - activate-ssh-key@4:
        run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
    - git-clone@6: {}
    - cache-pull@2: {}
    - fastlane@2:
        title: fastlane add_device
        inputs:
        - lane: ios add_device
    - slack@3:
        title: Slack Notification
        is_always_run: true
        inputs:
        - webhook_url: $SLACK_WEBHOOK_URL
        - title: "Add Device"
        - message: "デバイスを追加しました"
        - message_on_error: "デバイス追加に失敗しました"
    description: fastlane add_device_via_github_actionsを実行するワークフロー

fastlane

GitHub Actionsで入力したデバイス名とUDIDはENV["DEVICE_NAME"],ENV["DEVICE_UDID"]とすることで取得できました。

  desc "Add test device and update provisioning profile"
  lane :add_device do
    app_store_connect_api_key(
      key_id: ENV["ASC_KEY_ID"],
      issuer_id: ENV["ASC_ISSUER_ID"],
      key_content: ENV["ASC_KEY_CONTENT"],
      in_house: false
    )
    register_devices(devices: {ENV["DEVICE_NAME"] => ENV["DEVICE_UDID"]})

    match(type: "development", force_for_new_devices: true)
  end

認証はApp Store Connect API keyで行うためapp_store_connect_api_keyを使います。

今回は既存でapp_store_connect_api_keyを使っていたので対応してませんが、 新しく追加する場合はApp Store ConsoleからAPI Keyを発行してBitrise側のSecretsに保存しておく必要があります。

保存した値はENV["ASC_KEY_ID"],ENV["ASC_ISSUER_ID"], ENV["ASC_KEY_CONTENT"]のような形で取得できるのでこれをfastlaneのapp_store_connect_api_keyに渡してあげることでAPI Keyでの認証が可能になります。

デバイスの追加はfastlaneのregister_devicesにデバイス名とUDIDを渡してあげることで実現できます。

またデバイス追加後のプロファイルの更新ではmatch(type: "development", force_for_new_devices: true)とオプションを追加することで不要な更新をしないようにしました。

docs.fastlane.tools

まとめ

今回は元々あったワークフローのトリガー部分を変更しただけの改善でしたが、Bitriseやfastlaneのドキュメントを読むと他にできることがたくさんあるようなので、引き続き開発業務と並行してCI/CD環境の改善にも力を入れていきたいと思います!

参考

docs.github.com

devcenter.bitrise.io