この記事は、フラー株式会社 Advent Calendar 2021 の7日目の記事です。
6日目の記事は @zzzaaawwwaaa さんによる Rubyやってた人間がGo始めて思ったこと でした。
概要
Fastlane 2.197.0 で dSYM のダウンロードが App Store Connect API 対応しました。
これで証明書のダウンロードからストアへのアップロード、dSYM ダウンロードなど一通り CI で利用する処理が API 経由で利用可能になったので、おさらいしようと思い、記事にしました。
準備
Xcode プロジェクトを作成して、Apple Developer Portal で App Identifier を作成します。
App Store Connect で iOS アプリの作成し ユーザとアクセス > キー から App Store Connect Key を作成します。
Fastlane の ドキュメント で示されている通り、作成した鍵をダウンロードし、key_id, issuer_id と合わせて以下の json ファイルを作成します。
{
"key_id": "D383SF739",
"issuer_id": "6053b7fe-68a8-4acb-89be-165aa6465141",
"key": "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHknlhdlYdLu\n-----END PRIVATE KEY-----",
"duration": 1200,
"in_house": false
}
Fastlane
Fastlane を Bundler でインストールします。
$ bundle init
$ bundle add fastlane
$ bundle exec fastlane init
証明書の作成
fastlane/Fastfile
が生成されるので、match
の設定を行います。
GitHub で証明書配置用のリポジトリを作成し、Fastfile に プロビジョニングプロファイル作成用の lane を追加します。
API Key の指定方法は複数ありますが、ここでは json ファイルを指定する方式を利用します。
前述のファイルを配置し、ファイルパスを match の引数に指定します。
lane :renew_profile do
match(
app_identifier: '{アプリの bundle ID}',
api_key_path: '{json ファイルのパス}',
type: 'appstore',
git_url: '{作成した証明書用のレポジトリの Git URL}'
)
end
この lane はプロビジョニングプロファイルの更新時にも利用できるので、lane として定義しておけば端末登録後などに便利です。
$ bundle exec fastlane renew_profile
実行すると証明書とプロビジョニングプロファイルが作成されます。最初に実行したとき、証明書の暗号化用のパスワードを設定する必要があります。
App Store Connect へアップロード
Fastlane でビルドし、ipa ファイルをストアにアップロードする lane を作成します。
lane :upload do
match(
app_identifier: '{アプリの bundle ID}',
type: 'appstore',
readonly: true,
git_url: '{作成した証明書用のレポジトリの Git URL}'
)
gym(
export_method: 'app-store'
)
deliver(
app_identifier: '{アプリの bundle ID}',
api_key_path: '{json ファイルのパス}',
skip_metadata: true,
skip_screenshots: true,
precheck_include_in_app_purchases: false
)
end
dSYM のダウンロード
App Store Connect に ipa のアップロードが完了し、処理が完了したら dSYM をダウンロードできるようになります。
以下の lane を作成しておき、fastlane で簡単にダウンロードできるようにしておきます。
lane :donwload_dsym do
download_dsyms(
app_identifier: '{アプリの bundle ID}',
api_key_path: '{json ファイルのパス}',
version: "latest"
)
# Firebase Clashlitics などにアップロード
end
CI の利用
作成した3つの lane のうち、ストアでアップロードする処理を CI から実行させてみます。
ここでは GitHub Actions を利用します。
CI 用の Keychain の設定
Fastfile に CI で Match を動かすため、以下の設定を追加します。
before_all do
if is_ci?
create_keychain(
name: 'fastlane_tmp_keychain',
default_keychain: true,
unlock: true,
timeout: 3600,
lock_when_sleeps: true,
password: '',
add_to_search_list: true
)
end
end
App Store Connect API Key の配置
リポジトリの設定から Secrets を追加します。適当な名前を付け、json ファイルの中身を貼り付け、その環境変数をファイルに出力する処理を GitHub Actions で行います。
- name: Export App Store Connect API Key
run: |
cat << "EOF" > appstore-connect-key.json
${{ secrets.APP_STORE_CONNECT_API_KEY_JSON }}
EOF
SSH 鍵の設定
Fastlane Match
では、証明書管理用のリポジトリを clone するので、アクセスできるように設定する必要があります。
ssh キーペアを ssh-keygen
で作成し、証明書管理用のリポジトリの Deploy Key に public key を、アプリ側のリポジトリの secrets に秘密鍵をそれぞれ登録し、GitHub Actions からその鍵を利用するように設定します。
GitHub Actions のワークフロー
App Store Connect にアップロードするワークフローを作成します。
on:
push:
branches:
- main
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Bundle Install
run: bundle install
- name: Export App Store Connect API Key
run: |
cat << "EOF" > appstore-connect-key.json
${{ secrets.APP_STORE_CONNECT_API_KEY_JSON }}
EOF
- name: Export SSH Key
run: |
cat << "EOF" > ssh_private_key
${{ secrets.SSH_PRIVATE_KEY }}
END
- name: Upload To App Store
run: |
chmod 600 ssh_private_key
bundle exec fastlane upload
env:
GIT_SSH_COMMAND: ssh -i ssh_private_key -o StrictHostKeyChecking=no
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
上記のワークフローでは、以下の3つの Secrets をリポジトリの設定から登録する必要があります。
-
APP_STORE_CONNECT_API_KEY_JSON
: API キーを Json 形式で貼り付ける -
SSH_PRIVATE_KEY
: 作成した秘密鍵を貼り付ける -
MATCH_PASSWORD
: match の初回実行時に設定したパスワード
※ main ブランチの更新時にビルドとアップロードを行う例です。
終わりに
今までは iOS アプリ開発の CI といえば、Bitrise が主流だったと思いますが、今年8月に新プランによる価格改定がなされ、2022年8月頃から従来のプランが利用できなくなります。
今までが安かった分、従来のプランより高額になるケースがほとんどだと思います。
今のうちに CI 周りの整理をしておくと、いざ乗り換える必要がでたときにも安心ですね。