Skip to main content
  1. Posts/

[Fastlane不使用] iOSアプリのリリースを自動化する

iOSアプリのリリース作業を自動化するとき、おそらくは「Fastlane」を使うプロジェクトが多いと思います。私も、これまでいくつものプロジェクトでFastlaneを使ってきました。しかしながらFastlaneは、導入のしやすさはありますが、維持コストが高いなと感じます。プロジェクトがRubyに依存する上、頻繁にバージョンアップに追随する必要があり、RubyのバージョンやGemの管理もしたほうがよく、結局アプリ開発ではないところにメンテコストがかかってきます。そこで、Xcodeのコマンドラインツールだけで、リリース作業を自動化したいと考えました。

前提 #

  • ローカルで実行
    • CIではありません
    • GitHub Actionsなどは、まだ導入していません
  • 開発者アカウントでログイン済みの端末で実行

自動化されること #

以下の作業が自動化されます。

  • Build Version、Marketing Versionの入力
    • Build Versionについては、自動付与
    • Marketing Versionは、引数で指定するとプロジェクトに自動反映
  • アーカイブ操作
    • アーカイブ作成のクリック操作をカット
    • リリース用のScheme指定ミスなどを防止
  • エクスポート操作
    • Organizerウィンドウでやっていたクリック操作が無くなります
    • OKボタンやNextボタンが表示されるのを待たなくて良くなります
    • アップロードまで自動化します
  • GitHubへのプッシュ
    • プッシュし忘れを防ぎます
    • タグもつけるようにしました

実装したスクリプト #

プロジェクトによってコマンドは変わりますが、概ね以下のとおりです。 スクリプトの保存場所は、プロジェクトのルートディレクトリ/script/upload_to_appstore.shにしました。

#!/bin/zsh

# 使い方
# プロジェクトのルートディレクトリで実行します
#
# [1] バージョンを変更せずに、AppStoreにアップロード
# $ ./script/upload_to_appstore.sh
#
# [2] バージョンを指定して、AppStoreにアップロード
# $ ./script/upload_to_appstore.sh 1.0.0

if [ $# -eq 1 ]; then
    ## バージョン指定があれば、バージョンを更新
    echo ------------------------------
    echo "ストアに表示するバージョンの更新"
    echo ------------------------------
    agvtool new-marketing-version $1
fi

## バージョンを更新する
echo ------------------------------
echo "ビルドバージョンの更新(年.月日.時分)"
echo ------------------------------
agvtool new-version `date "+%Y.%m%d.%H%M"`
# ↑ masterにマージしたときなどのイベントフックでやるなら、
#   new-versionではなくnext-versionでもよいと思う

MARKETING_VERSION=$(agvtool what-marketing-version -terse1)
BUILD_VERSION=`agvtool what-version -terse`
echo ------------------------------
echo "アップロードするバージョン: $MARKETING_VERSION"
echo "アップロードするビルドバージョン: $BUILD_VERSION"
echo ------------------------------

## アーカイブ
echo ------------------------------
echo "アーカイブの作成"
echo ------------------------------
xcodebuild -workspace MyApplication.xcworkspace -scheme MyApplication \
 -configuration Release -archivePath build/MyApplication.xcarchive archive

## エクスポート(App Store Connectへアップロード) 設定の詳細は ExportOptions.plist に記載
echo ------------------------------
echo "App Store Connectへアップロード"
echo ------------------------------
xcodebuild -exportArchive -archivePath build/MyApplication.xcarchive \
 -exportOptionsPlist script/ExportOptions.plist

## コミットする
echo ------------------------------
echo "コミット & タグ"
echo ------------------------------
git fetch
git add .
git commit -m "bump up version to $MARKETING_VERSION($BUILD_VERSION)"
git tag -a $MARKETING_VERSION -m "$MARKETING_VERSION($BUILD_VERSION)"

## プッシュする
BRANCH_NAME=`git symbolic-ref --short HEAD`
if [ "main" = $BRANCH_NAME ]; then
    echo -------------------------------------------------------------
    echo "mainブランチで作業しています。誤pushを防ぐため、手動でpushしてください。"
    echo "以下のコマンドを実行します。"
    echo "$ git push origin main & git push origin --tags"
    echo -------------------------------------------------------------
else
    git push origin $BRANCH_NAME
    git push origin --tags
    echo ------------------------------
    echo "正常終了"
    echo ------------------------------
fi

解説 #

agvtool #

アプリのバージョン名やビルドバージョンを変更できるコマンドラインツールです。 Xcodeに付属というよりは、標準で入っているのかなと思います。 (/Library/Developer/CommandLineTools/usr/bin ではなく、/usr/bin にいる)。

使い方は、manや–helpなどで表示できます。 以下のQiitaもわかりやすいです。 https://qiita.com/taisuke_h/items/ad3615717388c3e08925

xcodebuild #

Xcodeプロジェクトをビルドしたり、アーカイブしたり、エクスポートしたり、テストしたり……できるコマンドです。 できることが多すぎて、ほとんど把握できていません。

以下の記事が参考になります。 https://blog.ch3cooh.jp/entry/20150210/1423573065 https://ah-2.com/post/xcodebuild_example/

ExportOptions.plist #

ExportOptions.plistは、アーカイブをエクスポートするときのオプションをまとめたプロパティリストです。 手作業で作成しても良いですが、最もかんたんなのは以下の方法です。

https://qiita.com/uhooi/items/a17a5d0e5dd5a76191ac

上記の方法でリストを取得したあと、destinationの項目をexportからuploadに変更します。

その他のオプションを変更したり追加したりしたい場合は、以下の記事も参考になります。

https://qiita.com/taisuke_h/items/e37d96c96a811b630c0c

使用上の注意 #

  • 引数のバリデーションはつけていません
    • 入力に対するエラーは、agvtoolやxcodebuildに任せることにしました
  • アーカイブ・エクスポートの細かなオプションについてはXcodeで設定します
    • スクリプトからは、アーカイブ・エクスポートの呼び出しのみにしています
  • buildディレクトリを、.gitignoreに追加しておく
    • 割と重要。

まとめ #

アプリのリリース作業をFastlaneなしで自動化する方法をまとめました。 ローカル用のスクリプトですが、CI未対応のプロジェクトにとっては必要十分なスクリプトになっているかと思います。 これがあることで、Build Versionの設定ミスや、画面の前で待つことから開放されるようになります。ほんの少しですが、生産的なことに時間を使えるようになります。 仕事をどんどん効率化して、手作業を減らしていきましょう……!