はじめに
クラウドで Unity 自動ビルド環境の構築 では Win64 でビルドを行ったのですが、Android 版の場合は署名が必要になります。
今回は Android のビルド&コード署名までを行いたいと思います。
ゴール
- Unity の Self-hosted 環境で Android ビルドと APK の署名
事前準備
以下の記事で事前準備をしておいてください。
ソースコード
まずはソースコードです。
trigger:
- master
variables:
Unity.TargetBuild: 'Android'
Unity.ProjectPath: '$(Build.SourcesDirectory)'
Keystore.FileName: '<Keystore FileName>'
Keystore.Alias: '<Alias Name>'
Output.FileName: 'drop'
pool:
name: 'Unity Agent for Mac'
jobs:
- job: Unity
displayName: 'Unity Android build started.'
condition: or(not(variables['Unity.UserName']), not(variables['Unity.Password']), not(variables['Unity.SerialKey']))
workspace:
clean: outputs
steps:
- task: UnityGetProjectVersionTask@1
name: UnityGetProjectVersion
displayName: 'Getting a version of Unity'
inputs:
unityProjectPath: '$(Unity.ProjectPath)'
- bash: echo "##vso[task.setvariable variable=ANDROID_ROOT]/Applications/Unity/Hub/Editor/$(UnityGetProjectVersion.projectVersion)/PlaybackEngines/AndroidPlayer"
displayName: 'Set ANDROID_ROOT'
- bash: echo "##vso[task.setvariable variable=ANDROID_HOME]$(ANDROID_ROOT)/SDK"
displayName: 'Set ANDROID_HOME'
- bash: echo "##vso[task.setvariable variable=JAVA_HOME]$(ANDROID_ROOT)/OpenJDK"
displayName: 'Set JAVA_HOME'
- task: UnityBuildTask@3
displayName: 'Unity Building.'
condition: succeeded()
inputs:
buildTarget: '$(Unity.TargetBuild)'
unityProjectPath: '$(Unity.ProjectPath)'
outputPath: '$(Build.BinariesDirectory)'
outputFileName: '$(Output.FileName)'
- task: AndroidSigning@3
displayName: 'Signing the APK File.'
inputs:
apkFiles: '$(Build.BinariesDirectory)/*.apk'
apksignerKeystoreFile: '$(Keystore.FileName)'
apksignerKeystorePassword: '$(Keystore.Password)'
apksignerKeystoreAlias: '$(Keystore.Alias)'
apksignerKeyPassword: '$(Keystore.Password)'
zipalign: true
- task: CopyFiles@2
displayName: 'Copying builds...'
condition: succeeded()
inputs:
SourceFolder: '$(Build.BinariesDirectory)'
Contents: '*.apk'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
CleanTargetFolder: true
OverWrite: true
- task: PublishBuildArtifacts@1
displayName: 'Publish builds...'
condition: succeeded()
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'Release'
publishLocation: 'Container'
ANDROID_HOME の設定
Android 版の自動ビルドで一番躓いた箇所は ANDROID_HOME の設定でした。
Self-hosted の場合、環境変数に ANDROID_HOME を指定する方法はあまり得策ではない、と言うか Unity のインストールで『Android SDK & NDK Tools』『OpenJDK』が、バージョンごとにインストールされるパスが違いますので、それを Unity のプロジェクトバージョンを元に参照するパスを切り替えということをしたほうが良いという結論になりました。
- bash: echo "##vso[task.setvariable variable=ANDROID_ROOT]/Applications/Unity/Hub/Editor/$(UnityGetProjectVersion.projectVersion)/PlaybackEngines/AndroidPlayer"
displayName: 'Set ANDROID_ROOT'
- bash: echo "##vso[task.setvariable variable=ANDROID_HOME]$(ANDROID_ROOT)/SDK"
displayName: 'Set ANDROID_HOME'
- bash: echo "##vso[task.setvariable variable=JAVA_HOME]$(ANDROID_ROOT)/OpenJDK"
displayName: 'Set JAVA_HOME'
Pipelines では
- bash: echo "##vso[task.setvariable variable=<変数名>]変数に設定する値"
で変数を設定可能です。
また variables で変数を宣言しておかなくても変数が利用可能です。
APK ファイルの署名
Android の署名に必要な
- Keystore ファイル
- Keystore パスワード
- Keystore エイリアス
を YAML で利用します。
variables:
Keystore.FileName: '<Keystore FileName>'
KeyStore.Alias: '<Alias Name>'
# KeyStore.Password: 事前に Variables に設定しておく
- task: AndroidSigning@3
displayName: 'Signing the APK File.'
inputs:
apkFiles: '$(Build.BinariesDirectory)/*.apk'
apksignerKeystoreFile: '$(Keystore.FileName)'
apksignerKeystorePassword: '$(Keystore.Password)'
apksignerKeystoreAlias: '$(Keystore.Alias)'
apksignerKeyPassword: '$(Keystore.Password)'
zipalign: true
証明書などの保存方法 で保存されているセキュアファイルライブラリから Keystore ファイルを参照するだけで、署名付きの APK ファイルが作成されます。
※最近では Gradle を利用したビルド環境を作ることも多いですが、今回は Gradle は利用せずに Unity で生成された APK をそのまま利用しています。
おわりに
署名自体はそんなに難しくないです。
Pipelines のセキュアファイルライブラリが便利ですので、それが出来れば Android ビルドも怖くないです。