Azure DevOpsとAppCenterを使ってCIできるようにした
やったこと
- Azure DevOps(旧VSTS)でソース管理とビルドパイプラインの面倒を見る。AppCenterでテスターにバイナリを配布する。
- AndroidとiOS両方やる
- ビルドマシンは自宅にmacOSな物理マシンを設置する
セットアップ
セットアップ自体は簡単。どれもすぐできるので省略します。
- Android Studioをセットアップする
- XCodeをセットアップする
- Azure DevOpsのビルドエージェントをセットアップする
困ったこと
- iOSのビルドがうまくいかなくて泣いた
iOSはProvisioning Profileとp12を設定しているのに署名がうまくいかなくて泣いた。 結局、VSTSのビルドタスクの実装を読んで、ビルド前にMagicを施すことでなぜかビルドできるようになった。
逆にAndroidはデフォルトでなにも困っていないので特に触れません。
泣いた結果のビルドパイプライン
Pipelineのところ。Schemeをちゃんと書く。
なんかよくわからない文字列をpbxprojに書き込む
echo "/* tweaks ProvisioningStyle = Manual; */" >> ”プロジェクト名”.xcodeproj/project.pbxproj
DerivedDataのせいでビルドにこけることがあるので毎回消す
echo Cleaning DerivedData... rm -rf /Users/<ユーザー名>/Library/Developer/Xcode/DerivedData/<プロジェクト名>-*
XCode Buildはこれでいいらしい。最初Manual署名とかいろいろやってみたけど、結局署名がうまくいかなかったりでよくわからない。 最初の謎の文字列をpbxprojに書き込むとビルドタスクがいい感じに動く。もうさっぱりわからない。
ついでにGitのChangeLogをBuild artifactに入れておく。
echo "$(Build.SourceVersionMessage)" > $(build.artifactstagingdirectory)/CHANGELOG
結局ビルドタスクの実装に依存した謎の文字列を無理やり押し込んで解決したけど、こんなことしなくても通るはず…謎。もう無理。
リリースする
デフォルトでビルド後にAppCenterに投げるようなタスクが書かれてる。けどせっかく(?)なので、Releaseを使った。
トリガーに、CIビルドを設定。タスクにはAppCenterにDeployするタスクを設定しただけとても簡単。
Release notes fileに、ビルド時に生成したCHANGELOGを指定した。
Gitのログを出力したのはここで使うためでした。
AppCenterのIn-app Updateを使う準備をする
In-app Updateを使うにはちゃんとバージョン番号が上がっていないとだめ。
それぞれの場合に、アップデート通知が出る。なのでいい感じにバージョンを更新しないといけない。
調べるとVSTSのビルドタスクでできるよーとか書いてあったりいろいろ試したけどめんどくさくなった*1。 ので、macなんだろsedでいいだろsedで。という感じで解決しました。
Android版
Androidはbuild.gradleのversionCode 1
ってなってるところをsedで$(Build.BuildId)に置換するだけ。簡単
sed -i -e "s/versionCode 1/versionCode $(Build.BuildId)/" app/build.gradle
iOS版
iOSはもっと簡単でmacなのでplistを編集するCLIツールがあるのでそれを使う。CFBundleVersionを文字列で$(Build.BuildId)に書き換える。こちらも簡単
plutil -replace 'CFBundleVersion' -string "$(Build.BuildId)" <プロジェクト名>/Info.plist
アプリにIn-app Updatesをセットアップする
実際にIn-app Updatesを有効にするには、アプリ側にライブラリをインストールして少しだけコードを書き足す必要があります。 ただこれも、使い方はdocs.comを読むと書いてます。
docs.com読めって言えばそれだけの話なんですが、とりあえず簡単に紹介だけしておきます。といってもdocs.comに書いてることと変わりません。
Android版
Androidは簡単。Gradleに依存を書く。
dependencies { def appCenterSdkVersion = '1.10.0' implementation "com.microsoft.appcenter:appcenter-distribute:${appCenterSdkVersion}" }
importを書いて、MainActivityのonCreate
あたりに次のコードを埋める。
AppCenter.start(getApplication(), "{Your App Secret}", Distribute.class);
おわり。簡単。
iOS版
iOSもだいたい同じ。
Cocoapodsからライブラリを入れる。
pod 'AppCenter/Distribute'
importを書いて、didFinishLaunchingWithOptions
あたりに次のコードを埋める。
MSAppCenter.start("{Your App Secret}", withServices: [MSDistribute.self])
ただ、iOSはInfo.plistをちゃんと書かないと動かない。 ドキュメントにもちゃんと書けよ。って書いてあるけど見落とすと動かなくて悩むのでちゃんと書きましょう*2。
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>appcenter-${APP_SECRET}</string> </array> </dict> </array>
おわり
*1:PowerShellタスクだからmacなので動かないとかあって嫌になった
*2:1時間くらい悩んだ