pushしたら自動でUnityビルドが走る人権環境を手に入れるの続編です。
はじめに
詳細を書くのが面倒なので、GitHub ActionsやFastlaneを分かってる人向け記事です。
ポイント
match不使用
今回はmatchを使用せず、証明書(.p12)とmobileprovisionを手動で生成して使用するフローです。
これは好みが分かれるところだと思いますが、自分の趣味です。
すぐLinuxに切り替える
わざわざubuntuでUnityビルド、macOSでXcodeビルド、またubuntuに戻してAppCenterにアップロードと面倒なことをしています。
理由は簡単で、XcodeビルドにはmacOSを利用する必要がありますが、Linuxに比べて値段が10倍もします。
(GitHub Actionsの支払いについて)
ArtifactのUpload/Downloadは結構早いので、Linuxで出来ることはLinuxでやる方針にしています。
Artifactは忘れず消す
Job間を跨いでファイルを共有するためにArtifactを利用していますが、Artifactも課金対象です。
(自動で課金されることはなく、上限を超えると古いものから消えていきます。)
そのため、job間のファイル共有に使ったArtifactは忘れず消えるようなコードにしましょう。
Jobの途中でエラーになったときも正しく削除されるよう気をつけましょう。
development-build.yml
ここからは直接コードにコメントを入れながら解説していきます。
name: Development build on: push: branches: - main jobs: build_unity: name: Build ${{ matrix.targetPlatform }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: targetPlatform: - iOS steps: - name: Checkout repository uses: actions/checkout@v2 - uses: actions/cache@v2 with: path: Unity/Library key: Library-${{ matrix.targetPlatform }} restore-keys: | Library- - name: Build uses: game-ci/unity-builder@v2 env: UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} with: projectPath: Unity targetPlatform: ${{ matrix.targetPlatform }} versioning: Custom version: 0.1.${{ github.run_number }} # ここでバージョンを入れておくと出来たROMとGitHubActionsの対応付けが出来て便利 - uses: actions/upload-artifact@v2 with: name: Build-${{ matrix.targetPlatform }} path: build/${{ matrix.targetPlatform }} build_xcode: name: Build xcode project runs-on: macos-latest needs: build_unity env: IOS_APP_ID: dev.kyubuns.test IOS_BUILD_PATH: ${{ format('{0}/build/iOS', github.workspace) }} CERTIFICATES_PATH: ${{ format('{0}/Certificates.p12', github.workspace) }} MOBILEPROVISION_PATH: ${{ format('{0}/Target.mobileprovision', github.workspace) }} IPA_OUTPUT_PATH: ${{ format('{0}/Build.ipa', github.workspace) }} CODESIGNING_IDENTITY: ${{ secrets.CODESIGNING_IDENTITY }} CERTIFICATES_PASSWORD: ${{ secrets.CERTIFICATES_PASSWORD }} steps: - name: Checkout Repository uses: actions/checkout@v2 - name: Download Artifact uses: actions/download-artifact@v2 with: name: Build-iOS path: build/iOS - name: Fix File Permissions run: | find $IOS_BUILD_PATH -type f -name "**.sh" -exec chmod +x {} \; - uses: actions/cache@v2 with: path: vendor/bundle key: ${{ runner.os }}-${{ hashFiles('**/Gemfile.lock') }} - name: Write Key Files env: CERTIFICATES_P12: ${{ secrets.CERTIFICATES_P12 }} MOBILEPROVISION: ${{ secrets.MOBILEPROVISION }} run: | echo "$CERTIFICATES_P12" | base64 --decode > $CERTIFICATES_PATH echo "$MOBILEPROVISION" | base64 --decode > $MOBILEPROVISION_PATH - name: Build Xcode uses: maierj/fastlane-action@v2.0.0 with: lane: 'ios development' - uses: actions/upload-artifact@v2 with: name: Build-iOS-ipa path: ${{ env.IPA_OUTPUT_PATH }} - name: Cleanup if: always() uses: geekyeggo/delete-artifact@v1 with: name: Build-iOS # FastlaneでAppCenterにアップロードするところまで行っても良かったものの、macOSの稼働時間を減らすためにlinuxで行っている upload_appcenter: name: Upload ipa to AppCenter runs-on: ubuntu-latest needs: build_xcode steps: - name: Download Artifact uses: actions/download-artifact@v2 with: name: Build-iOS-ipa - name: Upload to App Center uses: wzieba/AppCenter-Github-Action@v1 with: appName: kyubuns/Test token: ${{ secrets.APPCENTER_API_TOKEN }} file: Build.ipa group: Internal - name: Cleanup if: always() uses: geekyeggo/delete-artifact@v1 with: name: Build-iOS-ipa
fastlane/Fastfile
fastlane init
してGemfileとかは作ってください。
keychain_name = "temporary_keychain" keychain_password = SecureRandom.base64 platform :ios do lane :development do certificates provisining_uuid = sh("grep UUID -A1 -a #{ENV["MOBILEPROVISION_PATH"]} | grep -io \"[-A-Z0-9]\\{36\\}\"").strip build_options = {} build_options[:scheme] = "Unity-iPhone" build_options[:output_name] = File.basename(ENV['IPA_OUTPUT_PATH']) build_options[:output_directory] = File.dirname(ENV['IPA_OUTPUT_PATH']) build_options[:configuration] = "Debug" build_options[:project] = "#{ENV['IOS_BUILD_PATH']}/iOS/Unity-iPhone.xcodeproj" build_options[:export_method] = "ad-hoc" build_options[:codesigning_identity] = ENV['CODESIGNING_IDENTITY'] build_options[:export_options] = { signingStyle: "manual", compileBitcode: false, provisioningProfiles: { "#{ENV["IOS_APP_ID"]}": "#{provisining_uuid}" }, } build_options[:skip_profile_detection] = true update_app_identifier( xcodeproj: build_options[:project], plist_path: "Info.plist", app_identifier: ENV["IOS_APP_ID"], ) update_project_provisioning( xcodeproj: build_options[:project], target_filter: build_options[:scheme], profile: ENV["MOBILEPROVISION_PATH"], code_signing_identity: build_options[:codesigning_identity] ) build_ios_app(build_options) end lane :certificates do cleanup_keychain create_keychain( name: keychain_name, password: keychain_password, default_keychain: true, lock_when_sleeps: true, timeout: 3600, unlock: true ) import_certificate( certificate_path: ENV["CERTIFICATES_PATH"], certificate_password: ENV["CERTIFICATES_PASSWORD"], keychain_name: keychain_name, keychain_password: keychain_password ) install_provisioning_profile(path: ENV["MOBILEPROVISION_PATH"]) end lane :cleanup_keychain do if File.exist?(File.expand_path("~/Library/Keychains/#{keychain_name}-db")) delete_keychain(name: keychain_name) end end after_all do if File.exist?(File.expand_path("~/Library/Keychains/#{keychain_name}-db")) delete_keychain(name: keychain_name) end end end
参考
GAME.CI - Deploy to the App Store https://game.ci/docs/github/deployment/ios