classi/fastlane-example
fastlane-example - fastlane example by Classi Corp.
https://github.com/classi/fastlane-example
Classi で iOS エンジニアをしている @star__hoshi と申します。
Classi 社には iOS エンジニアが 1 人しかいないのにアプリが 3 つあります。
iOS 開発では UDID の追加や証明書の更新など、非常に多くのちょっとしたタスク
があり、このようなアプリ3つ分の雑務ばかりしていれば本来やるべきことができません。
そのため、もろもろの雑務を fastlane の match, gym, deliver などで自動化しました。実際の開発フローの流れと、何をどう自動化したのかコードを含め書いていきます。
この記事では詳しい fastlane の使い方を述べたものではなく、 fastlane を使うことによる効能などの概念的な話が中心になります。fastlane の使い方に関しては docs.fastlane.tools という素晴らしいドキュメントがありますので、そちらを参照ください。
Classi では、クックパッド社の iOS ブランチ運用を参考にして開発フローを整備しています。
master ブランチを開発ブランチとし、リリース時には release ブランチを作成、リリースされたタイミングで master にマージしています。
クックパッド社 https://speakerdeck.com/morishin/cookpad-ios-release-flow?slide=14
このフローを回すのは難しくありませんが、いくつか手動作業が発生してしまいます。
feature が master にマージされたときに beta 版配布をして動作確認を行います。
beta 版配布を手動でやると以下の作業が必要になります。
UDID の追加がなければ 1.1〜1.6 はしなくて良いですが、追加があると特に大変ですよね。
この手順を踏むのになんやかんや 30 分くらいかかったりします😭 、ここを CI Server + fastlane に請け負ってもらいましょう。
register_device の action を実行すると UDID の登録がコマンド1発で行えます。
Crashlytics から通知のメールがきたら手動でこれを実行しています。 (メールを hook して自動化できそうですね 😃 )
$ bundle exec fastlane run register_device name:"アイフォーン7" udid:1111111111111111111111111111
$ bundle exec fastlane beta
beta lane を実行すると、ざっくり以下の手順を実行します。
BETA
の文字を載せるbeta 版配布で必要なことを一通り実行できます 😊
lane :beta do
# 証明書のダウンロードとインストール、必要があれば証明書を更新
match(type: "development", forcefor new_devices: true)
# 日付フォーマットで build number を更新
incrementbuild number(build_number: Time.now.strftime("%Y%m%d%H%M"))
# アプリアイコンを加工し BETA の文字をアイコンに装飾する
badge(shield: "#{getversion number}-#{getbuild number}-blue", dark: true)
# Compile
gym
# ipa と dSYM を Artifacts に保存する
if is_ci?
sh "cp #{lane_context[SharedValues::IPAOUTPUT PATH]} $CIRCLEARTIFACTS"
sh "cp #{lane context[SharedValues::DSYMOUTPUT PATH]} $CIRCLE_ARTIFACTS"
end
# Crashlytics beta でアプリを配布
crashlytics(
crashlytics_path: "Pods/Crashlytics/iOS/Crashlytics.framework",
api_token: ENV['CRASHLYTICSAPI TOKEN'],
build_secret: ENV['CRASHLYTICSBUILD SECRET'],
ipa_path: lane_context[SharedValues::IPAOUTPUT PATH],
notes: changelog,
groups: "CLASSI_APP"
)
# dSYM を Crashlytics にアップロード
uploadsymbols tocrashlytics
# notify slack
payload = {"Git Commit" => changelog}
payload["Circle Artifacts Url"] = ENV["CIRCLE BUILDURL"] + "#artifacts/containers/0" if is ci?
slack(
message: ":crashlytics: Beta App successfully released!",
payload: payload,
default_payloads: default_payloads
)
end
アンダースコアで code が崩れてしまうので、こちらの Fastfile を参照ください
Classi では CircleCI を使っていますので、 Beta 配布を CI でやるようにしています。これで master にマージされるたびに Beta 最新版を利用できるようになります。
deployment:
master:
branch: master
commands:
- brew install imagemagick
- brew install graphicsmagick
- bundle exec fastlane beta --verbose
アプリのリリース作業を手動でやると、15分〜30分くらいかかってしまいますね 😢
この流れも CI でできるようにしてしまいましょう。
$ bundle exec fastlane release
release lane を実行すると、ざっくり以下の手順を実行します。
これで iTunes Connect にアプリをアップロードできます。 deliver の説明文管理などは利用せず、 iTunes Connect の画面でやっています。
lane :release do
# 証明書のダウンロードとインストール
match(type: "appstore")
# 日付フォーマットで build number を更新
incrementbuild number(build_number: Time.now.strftime("%Y%m%d%H%M"))
# Compile
gym(scheme: "Release")
# ipa と dSYM を Artifacts に保存する
if is_ci?
sh "cp #{lane_context[SharedValues::IPAOUTPUT PATH]} $CIRCLE_ARTIFACTS"
sh "cp #{lane context[SharedValues::DSYMOUTPUT PATH]} $CIRCLEARTIFACTS"
end
# iTunes Connect に Upload
deliver
# dSYM を Crashlytics にアップロード
upload symbolsto crashlytics
# git のリリースタグを打つ
# 同じバージョンで再申請する場合があるので、 force push してタグをうわがく
addgit tag(
tag: "v#{getversion number}",
message: "build_number: #{getbuild number} by fastlane\n\n#{changelog}",
force: true
)
pushgit tags(force: true)
# notify slack
payload = {"Git Commit" => changelog}
slack(
message: ":itunesconnect: Successfully uploaded a new App Store build",
payload: payload,
default_payloads: default_payloads
)
end
アンダースコアで code が崩れてしまうので、こちらの Fastfile を参照ください
release ブランチに変更があったら、自動で release lane が実行されるようにしています。これで、 release ブランチを作成して Push するだけで iTunes Connect へアップロードが完了します。
deployment:
release:
branch: /release.*/
commands:
- bundle exec fastlane release --verbose
release ブランチを Push すれば自動で iTunes Connect にアップロードされるのですが、その release ブランチの作成や Git Push も fastlane でやってしまいましょう。
$ bundle exec fastlane release_branch version:1.0.1
release_branch lane では以下を実行してくれます。
lane :release_branch do |options|
# 引数に release version が指定されていることを確認する
UI.user error!("Required release version. ex: fastlane release_branch version:1.0.0") unless options[:version]
branch = "release/#{options[:version]}"
# リリースブランチを作成
sh("git checkout master && git pull origin master")
sh("git checkout -b #{branch}")
# 引数で指定した version に Info.plist を更新
incrementversion number(version_number: options[:version])
commitversion bump(
message: "Create #{branch} branch.",
xcodeproj: "classi.xcodeproj"
)
# git push し PR を作成
pushto gitremote
create pull_request(
repo: "classi/classiios app",
title: "#{branch}",
body: "release v#{options[:version]}"
)
end
アンダースコアで code が崩れてしまうので、こちらの Fastfile を参照ください
これでアプリのバージョンの更新やプルリクエストの作成もコマンド1つで実行できるようになりました。
release ブランチが Push されるため release lane が動き、 iTunes Connect へアップロードまで流れで行えます 😊
証明書の更新から beta 版の配布や iTunes Connect へのアップロードなど、今まで手動で実施していた様々なことを自動化することができました。
Beta 版の配布は1日に何度も必要だったりして、特に効率が良いです。まだ fastlane を利用していない人は是非利用を検討してみてください 💪
本記事で紹介した Fastfile だけでなく、 Appfile や Matchfile なども公開しています。疑問点などあれば @star__hoshi にご連絡ください✉️