アプリケーションをコマンドラインからビルドする
Unityでは Assets/Editor 以下に .cs を置くことでエディタの拡張をすることが出来ます.
それを用いて各種プラットフォーム向けにビルドするスクリプト Build.cs を作成します.
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.Build.Reporting;
using UnityEngine;
public class BuildScript {
[MenuItem("Build/Windows Dev Build")]
public static void WindowsDevelopmentBuild() {
Build(BuildTarget.StandaloneWindows64, false);
Debug.Log("WindowsDevelopmentBuild one");
}
[MenuItem("Build/Windows Release Build")]
public static void WindowsReleaseBuild() {
Build(BuildTarget.StandaloneWindows64, true);
Debug.Log("WindowsReleaseBuild Done");
}
private static void Build(BuildTarget target, bool isReleaseBuild) {
var scenes = GetScenes(isReleaseBuild);
var buildPlayerOptions = new BuildPlayerOptions();
buildPlayerOptions.scenes = scenes;
if (!isReleaseBuild) {
// テスト時はDevelopmentビルドのオプションを有効にする
buildPlayerOptions.options = BuildOptions.Development;
}
var ext = target == BuildTarget.StandaloneWindows64 ? "exe" : "apk";
buildPlayerOptions.locationPathName = $"Build/{Application.productName}.{ext}";
buildPlayerOptions.target = target;
var report = BuildPipeline.BuildPlayer(buildPlayerOptions);
var summary = report.summary;
if (summary.result == BuildResult.Succeeded)
Debug.Log("Build succeeded: " + summary.totalSize + " bytes");
else if (summary.result == BuildResult.Failed) {
Debug.LogError("Build failed");
}
}
}これによりアプリケーションをコマンドラインからビルド出来るようになります.
$ path/to/Unity.exe -quit -batchmode -projectPath . \
-executeMethod BuildScript.WindowsDevelopmentBuild \
-buildTarget StandaloneWindows64 \
-setDefaultPlatformTextureFormat astc -nographics -logFile -インストーラを作成する
ビルドして作成された app.exe のみを配布してもアプリを起動することは出来ません.
Unityアプリの実行には UnityPlayer.dll と WinPixEventRuntime.dll 等が必要になります.
zipファイルで全てまとめてもよいのですが, 今回はインストーラとしてまとめて一つの .exe として配布できるようにします. インストーラを作成するために InnoSetup というツールを使用します.
この記事 のテンプレートを参考にさせていただいています.
/UnityApp.iss
; https://github.com/karinharp/InnoSetupTemplateForUnity
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppUUID "com.idh.choivr"
#define MyAppName "choivr"
#define MyAppVersion "0.1"
#define MyAppPublisher ""
#define MyAppURL ""
#define MyAppExeName "choivr.exe"
#define ResourceDir "Build"
#define OutputDir "Build"
#define OutputBaseFilename "choivr_setup"
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={#MyAppUUID}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
OutputDir={#OutputDir}
OutputBaseFilename={#OutputBaseFilename}
Compression=lzma
SolidCompression=yes
[Languages]
Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
[Files]
Source: "{#ResourceDir}\{#MyAppName}.exe"; DestDir: "{app}\app"; Flags: ignoreversion; Permissions: everyone-full
Source: "{#ResourceDir}\UnityPlayer.dll"; DestDir: "{app}\app"; Flags: ignoreversion; Permissions: everyone-full
Source: "{#ResourceDir}\WinPixEventRuntime.dll"; DestDir: "{app}\app"; Flags: ignoreversion; Permissions: everyone-full
Source: "{#ResourceDir}\UnityCrashHandler64.exe"; DestDir: "{app}\app"; Flags: ignoreversion; Permissions: everyone-full
Source: "{#ResourceDir}\{#MyAppName}_Data\*"; DestDir: "{app}\app\{#MyAppName}_Data"; Flags: ignoreversion recursesubdirs createallsubdirs; Permissions: everyone-full
Source: "{#ResourceDir}\MonoBleedingEdge\*"; DestDir: "{app}\app\MonoBleedingEdge"; Flags: ignoreversion recursesubdirs createallsubdirs; Permissions: everyone-full
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\app\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\app\{#MyAppExeName}"; Tasks: desktopicon
[Run]
Filename: "{app}\app\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
[Dirs]
Name: "{app}\app"; Permissions: everyone-fullインストーラの作成は以下コマンドにより行います.
$ path/to/ISCC.exe UnityApp.issSelf-Hostedランナーでreleaseブランチマージ時にリリースする
Unity Editorはライセンス認証が必要な関係でUnity Cloud Buildを使用せず自前でCI/CD上でビルドさせようとすると非常に面倒くさいです.
今回はGitHub Actionのself-hostedランナーでビルドすることによりその問題を回避します.
以下が release-* ブランチにPRを出し、マージされた際にPRの内容からリリースノートを作成してWindowsのDevelopmentビルドとAndroidのDevelopmentビルドをリリースするWorkflowです.
まだバージョンをつける等のことは出来ていません.
ワークフロー
- feature/xxx で作業をする
- release-x.x.x ブランチを作成する
- feature/xxx → release-x.x.x にPRを出す
- マージされたらCI/CDが走る
- CDが成功したら master にマージされ release-x.x.x タグがつく
name: Release from PR
on:
pull_request:
branches:
- 'release-*'
types: [ closed ]
jobs:
build:
if: github.event.pull_request.merged == true
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v2
with:
lfs: true
clean: false
- name: Extract branch name
uses: mdecoleman/pr-branch-name@1.0.0
id: extract_branch
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Envs
shell: bash
# <https://zenn.dev/uta_mory/articles/14e358a2dbf6e47400dc>
run: |
echo "UNITY_PATH=path/to/Unity.exe" >> $GITHUB_ENV
echo "INSTALLER_CC_PATH=path/to/ISCC.exe" >> $GITHUB_ENV
- name: Unity Android Build
shell: bash
run: |
"${UNITY_PATH}" -quit -batchmode -projectPath . \
-executeMethod BuildScript.AndroidReleaseBuild \
-buildTarget Android \
-setDefaultPlatformTextureFormat astc -nographics -logFile -
- name: Unity Windows Build
shell: bash
run: |
"${UNITY_PATH}" -quit -batchmode -projectPath . \
-executeMethod BuildScript.WindowsDevelopmentBuild \
-buildTarget StandaloneWindows64 \
-setDefaultPlatformTextureFormat astc -nographics -logFile -
- name: Create Installer
shell: bash
run: |
"${INSTALLER_CC_PATH}" UnityApp.iss
powershell -c Compress-Archive -Path "Build/choivr_setup.exe" -DestinationPath "Build/choivr.zip"
- name: Get body from PullRequest
id: pr-body
uses: actions/github-script@v2
with:
github-token: ${{secrets.GITHUB_TOKEN}}
result-encoding: string
script: |
const result = await github.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
})
return result.data.body
- name: Create ReleaseNote
id: create_release
if: startsWith(steps.extract_branch.outputs.branch, 'release')
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.extract_branch.outputs.branch }}
release_name: Release ${{ steps.extract_branch.outputs.branch }}
body: |
${{ steps.pr-body.outputs.result }}
draft: false
prerelease: true
- name: Upload Android Debug Build
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: Build/choivr.apk
asset_name: choivr.apk
asset_content_type: application/zip
- name: Upload Windows Debug Build
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: Build/choivr.zip
asset_name: choivr_win.zip
asset_content_type: application/zip- Unityプロジェクトを管理するときは
Git LFSを使用しているはずなのでcheckout時にlfs: trueを設定,clean: falseにすると毎回のビルド時間を短縮できる - 各step間で環境変数を共有する方法は
::set-env::によるものが非推奨になったので$GITHUB_ENVへリダイレクトする方法に $GITHUB_ENVに設定する値はエスケープしなくてよい(ハマった)- 以前は
Artifactにビルドしたものをおいていたが 1GB の制限に引っかかりお金がかかってしまったのでrelease機能を使うことに .exeは直接asset_content_typeに指定できないのでzipとかにする