Skip to content

Commit 44b72bf

Browse files
authored
Add Android signing option to build task (#269)
* Remove deprecation * Align UnityCMD input options with other tasks and remove deprecation * Revert extension version change until ready for release * Organize input variables into logical groups * Add keystore input options * Map and pass new inputs * Add missing changelog * Update README * Add PR trigger * Update gitignore * Fix tests * Update dep
1 parent 172f120 commit 44b72bf

File tree

6 files changed

+180
-60
lines changed

6 files changed

+180
-60
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Documentation for the extension can be found at [www.unitydevops.com](https://ww
1414

1515
| Branch | Description | Status |
1616
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
17-
| main | The main branch is build and deployed to the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=DinomiteStudios.64e90d50-a9c0-11e8-a356-d3eab7857116) | [![Build Status](https://dev.azure.com/dinomite/Unity%20Tools%20for%20Azure%20DevOps/_apis/build/status%2FDinomite-Studios.unity-azure-pipelines-tasks?branchName=main)](https://dev.azure.com/dinomite/Unity%20Tools%20for%20Azure%20DevOps/_build/latest?definitionId=51&branchName=main) |
17+
| main | The main branch is build and deployed to the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=DinomiteStudios.64e90d50-a9c0-11e8-a356-d3eab7857116) | [![Build, Test and Deploy](https://github.com/Dinomite-Studios/unity-azure-pipelines-tasks/actions/workflows/build-test-deploy.yml/badge.svg)](https://github.com/Dinomite-Studios/unity-azure-pipelines-tasks/actions/workflows/build-test-deploy.yml) |
1818

1919
## Contributions
2020

Tasks/UnityBuild/UnityBuildV3/CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [3.2.5]
9+
10+
### Added
11+
12+
- Add visionOS build target
13+
- Add configuration options to sign an Android build using a keystore
14+
15+
### Changed
16+
17+
- Improved input variables grouping in visual editor
18+
- The output variable now points directly to the genereated lot file instead of the folder containing it. This is to avoid uploading log files from previous runs if there happen to be multiple log files in the log directory
19+
- Optimized editor version selection UX. Instead of using the project's version if the version input variable is empty we use a dropdown element that offers two options. Either to use the project's Unity version or specify one, which will only then show a input textbox for entering a custom Unity version. This is aligned with the other tasks for a consistent user experience
20+
821
## [3.2.4]
922

1023
### Fixed

Tasks/UnityBuild/UnityBuildV3/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@dinomite-studios/unity-build-task",
3-
"version": "3.2.4",
3+
"version": "3.2.5",
44
"description": "An Azure Pipelines task to build Unity projects.",
55
"main": "unity-build.js",
66
"scripts": {

Tasks/UnityBuild/UnityBuildV3/task.json

Lines changed: 123 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,46 +13,36 @@
1313
"version": {
1414
"Major": 3,
1515
"Minor": 2,
16-
"Patch": 4
16+
"Patch": 5
1717
},
1818
"releaseNotes": "[Full Changelog](https://github.com/Dinomite-Studios/unity-azure-pipelines-tasks/blob/master/Tasks/UnityBuild/UnityBuildV3/CHANGELOG.md)",
1919
"minimumAgentVersion": "2.144.0",
2020
"instanceNameFormat": "Unity Build $(buildTarget)",
21-
"groups": [],
22-
"inputs": [
21+
"groups": [
2322
{
24-
"name": "buildTarget",
25-
"type": "pickList",
26-
"label": "Build target",
27-
"defaultValue": "standalone",
28-
"helpMarkDown": "Build platform to build the Unity project for.",
29-
"options": {
30-
"standalone": "Standalone (agent-based)",
31-
"Win": "Windows Standalone (32-bit)",
32-
"Win64": "Windows Standalone (64-bit)",
33-
"OSXUniversal": "macOS Standalone",
34-
"Linux": "Linux Standalone (32-bit)",
35-
"Linux64": "Linux Standalone (64-bit)",
36-
"LinuxUniversal": "Linux Standalone (universal)",
37-
"iOS": "iOS",
38-
"Android": "Android",
39-
"Web": "Web",
40-
"WebStreamed": "Web Streamed",
41-
"WebGL": "WebGL",
42-
"XboxOne": "Xbox One",
43-
"PS4": "PS4",
44-
"WindowsStoreApps": "Windows Store Apps",
45-
"Switch": "Switch",
46-
"N3DS": "N3DS",
47-
"tvOS": "tvOS"
48-
}
23+
"name": "general",
24+
"displayName": "General",
25+
"isExpanded": true
4926
},
27+
{
28+
"name": "build",
29+
"displayName": "Build",
30+
"isExpanded": true
31+
},
32+
{
33+
"name": "platform",
34+
"displayName": "Platform",
35+
"isExpanded": true
36+
}
37+
],
38+
"inputs": [
5039
{
5140
"name": "unityEditorsPathMode",
5241
"type": "pickList",
5342
"label": "Unity editors location",
5443
"defaultValue": "default",
5544
"helpMarkDown": "Define where to look for Unity installations on the agent.",
45+
"groupName": "general",
5646
"options": {
5747
"default": "Default (recommended)",
5848
"environmentVariable": "Use UNITYHUB_EDITORS_FOLDER_LOCATION environment variable on agent",
@@ -64,24 +54,18 @@
6454
"type": "string",
6555
"label": "Editors folder location",
6656
"defaultValue": "",
57+
"groupName": "general",
6758
"required": true,
6859
"visibleRule": "unityEditorsPathMode == specify",
6960
"helpMarkDown": "Specify where to look for Unity Editor versions on the agent."
7061
},
71-
{
72-
"name": "unityProjectPath",
73-
"type": "filePath",
74-
"label": "Unity project path",
75-
"defaultValue": "",
76-
"required": false,
77-
"helpMarkDown": "(Optional) Enter the directory path to the Unity project. If no value is entered, the root of the repository will be used."
78-
},
7962
{
8063
"name": "versionSelectionMode",
8164
"type": "pickList",
82-
"label": "Unity version to build with",
83-
"required": true,
84-
"helpMarkDown": "Select which Unity version to build the project with. You can either use the project's version or specify a version yourself.",
65+
"label": "Unity version",
66+
"groupName": "general",
67+
"required": false,
68+
"helpMarkDown": "Select which Unity version to run the task with.",
8569
"defaultValue": "project",
8670
"options": {
8771
"project": "Project Version",
@@ -92,17 +76,57 @@
9276
"name": "version",
9377
"type": "string",
9478
"label": "Version",
79+
"groupName": "general",
9580
"defaultValue": "",
9681
"required": true,
97-
"helpMarkDown": "The Unity editor version to activate the license with, e.g. value: `2022.2.1f1`.",
82+
"helpMarkDown": "Select which Unity version to run the task with, e.g. value: `2022.2.1f1`.",
9883
"visibleRule": "versionSelectionMode == specify"
9984
},
85+
{
86+
"name": "unityProjectPath",
87+
"type": "filePath",
88+
"label": "Unity project path",
89+
"groupName": "general",
90+
"defaultValue": "",
91+
"required": false,
92+
"helpMarkDown": "(Optional) Enter the path to the Unity project within the repository. If no value is entered, the root of the repository will be used."
93+
},
94+
{
95+
"name": "buildTarget",
96+
"type": "pickList",
97+
"label": "Build target",
98+
"defaultValue": "standalone",
99+
"helpMarkDown": "Build platform to build the Unity project for.",
100+
"groupName": "build",
101+
"options": {
102+
"standalone": "Standalone (agent-based)",
103+
"Win": "Windows Standalone (32-bit)",
104+
"Win64": "Windows Standalone (64-bit)",
105+
"OSXUniversal": "macOS Standalone",
106+
"Linux": "Linux Standalone (32-bit)",
107+
"Linux64": "Linux Standalone (64-bit)",
108+
"LinuxUniversal": "Linux Standalone (universal)",
109+
"iOS": "iOS",
110+
"Android": "Android",
111+
"Web": "Web",
112+
"WebStreamed": "Web Streamed",
113+
"WebGL": "WebGL",
114+
"XboxOne": "Xbox One",
115+
"PS4": "PS4",
116+
"WindowsStoreApps": "Windows Store Apps",
117+
"Switch": "Switch",
118+
"N3DS": "N3DS",
119+
"tvOS": "tvOS",
120+
"visionos": "visionOS"
121+
}
122+
},
100123
{
101124
"name": "buildScriptType",
102125
"type": "radio",
103126
"label": "Build script type",
104127
"defaultValue": "default",
105128
"helpMarkDown": "Build script type: Use `Default` to use a built-in simple script which will perform a build without additional options. Use `Existing` if you already have a build script in your source and only need to specify the method to execute on build. Or use `Inline` to define the script inline, please make sure it's valid C#.",
129+
"groupName": "build",
106130
"options": {
107131
"default": "Default",
108132
"existing": "Existing",
@@ -114,6 +138,7 @@
114138
"type": "filePath",
115139
"helpMarkDown": "Specify the build output path relative to the repository root or fully qualified.",
116140
"label": "Output path",
141+
"groupName": "build",
117142
"required": true,
118143
"defaultValue": "$(Build.BinariesDirectory)",
119144
"visibleRule": "buildScriptType = default"
@@ -122,16 +147,19 @@
122147
"name": "outputFileName",
123148
"type": "string",
124149
"label": "Output filename",
150+
"groupName": "build",
125151
"helpMarkDown": "Enter the output filename to be used when constructing the platform-appropriate output. For instance, if you want the output to be 'thegame.exe' on Windows Standalone, enter 'thegame'",
126152
"required": true,
127-
"defaultValue": "drop"
153+
"defaultValue": "drop",
154+
"visibleRule": "buildScriptType = default"
128155
},
129156
{
130157
"name": "inlineBuildScript",
131158
"type": "multiLine",
132159
"label": "Inline build script",
133160
"visibleRule": "buildScriptType = inline",
134161
"required": true,
162+
"groupName": "build",
135163
"defaultValue": "/* Write your C# build script here. Define a class and make sure to define a public static method to execute for the build. You'll want to verify your script actually works on your local computer.\n\nExample:\npublic class MyClass {\npublic static void PerformBuild() {\n...\n}\n}\n */",
136164
"properties": {
137165
"resizable": "true",
@@ -144,6 +172,7 @@
144172
"name": "scriptExecuteMethod",
145173
"type": "string",
146174
"label": "Build script execute method",
175+
"groupName": "build",
147176
"visibleRule": "buildScriptType = inline || buildScriptType = existing",
148177
"required": true,
149178
"defaultValue": "",
@@ -153,14 +182,65 @@
153182
"name": "additionalCmdArgs",
154183
"type": "string",
155184
"label": "Command line arguments",
185+
"groupName": "build",
156186
"defaultValue": "",
157187
"helpMarkDown": "(Optional) Specify additional command line arguments, see the [documentation](https://docs.unity3d.com/Manual/CommandLineArguments.html) for more info."
188+
},
189+
{
190+
"name": "signAppBundle",
191+
"type": "boolean",
192+
"label": "Sign APK / app bundle",
193+
"groupName": "platform",
194+
"defaultValue": true,
195+
"required": false,
196+
"helpMarkDown": "Whether to sign the produced APK / app bundle using a custom keystore.",
197+
"visibleRule": "buildTarget == Android && buildScriptType == default"
198+
},
199+
{
200+
"name": "keystoreName",
201+
"type": "filePath",
202+
"helpMarkDown": "Android keystore name / file path.",
203+
"label": "Keystore file path",
204+
"groupName": "platform",
205+
"required": true,
206+
"defaultValue": "",
207+
"visibleRule": "buildTarget == Android && signAppBundle == true && buildScriptType == default"
208+
},
209+
{
210+
"name": "keystorePass",
211+
"type": "string",
212+
"label": "Keystore password",
213+
"groupName": "platform",
214+
"helpMarkDown": "Android keystore password.",
215+
"required": true,
216+
"defaultValue": "",
217+
"visibleRule": "buildTarget == Android && signAppBundle == true && buildScriptType == default"
218+
},
219+
{
220+
"name": "keystoreAliasName",
221+
"type": "string",
222+
"label": "Keystore alias name",
223+
"groupName": "platform",
224+
"helpMarkDown": "Android key alias name.",
225+
"required": true,
226+
"defaultValue": "",
227+
"visibleRule": "buildTarget == Android && signAppBundle == true && buildScriptType == default"
228+
},
229+
{
230+
"name": "keystoreAliasPass",
231+
"type": "string",
232+
"label": "Keystore alias password",
233+
"groupName": "platform",
234+
"helpMarkDown": "Password for the key used for signing an Android application. If left empty, the keystore main password is assumed.",
235+
"required": false,
236+
"defaultValue": "",
237+
"visibleRule": "buildTarget == Android && signAppBundle == true && buildScriptType == default"
158238
}
159239
],
160240
"outputVariables": [
161241
{
162-
"name": "logsOutputPath",
163-
"description": "Path to the Unity editor log files generated."
242+
"name": "editorLogFilePath",
243+
"description": "Specifies the location of the editor log file generated."
164244
}
165245
],
166246
"execution": {

Tasks/UnityBuild/UnityBuildV3/unity-build.ts

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,22 @@ const buildTargetInputVariableName = 'buildTarget';
1616
const outputPathInputVariableName = 'outputPath';
1717
const unityProjectPathInputVariableName = 'unityProjectPath';
1818
const versionInputVariableName = 'version';
19+
const buildScriptTypeInputVariableName = 'buildScriptType';
1920
const unityEditorsPathModeInputVariableName = 'unityEditorsPathMode';
21+
const inlineBuildScriptInputVariableName = 'inlineBuildScript';
22+
const scriptExecuteMethodInputVariableName = 'scriptExecuteMethod';
23+
const additionalCmdArgsInputVariableName = 'additionalCmdArgs';
2024
const customUnityEditorsPathInputVariableName = 'customUnityEditorsPath';
2125
const cleanBuildInputVariableName = 'Build.Repository.Clean';
22-
const versionSelectionModeVariableName = "versionSelectionMode";
26+
const versionSelectionModeVariableName = 'versionSelectionMode';
27+
const signAppBundleInputVariableName = 'signAppBundle';
28+
const keystoreNameInputVariableName = 'keystoreName';
29+
const keystorePassInputVariableName = 'keystorePass';
30+
const keystoreAliasNameInputVariableName = 'keystoreAliasName';
31+
const keystoreAliasPassInputVariableName = 'keystoreAliasPass';
32+
33+
// Output variables.
34+
const editorLogFilePathOutputVariableName = 'editorLogFilePath';
2335

2436
async function run() {
2537
try {
@@ -54,8 +66,11 @@ async function run() {
5466

5567
const unityExecutablePath = UnityPathTools.getUnityExecutableFullPath(unityEditorsPath, unityVersion.info!);
5668
const cleanBuild = tl.getVariable(cleanBuildInputVariableName);
69+
70+
// Set output variable values.
5771
const logFilesDirectory = path.join(tl.getVariable('Agent.TempDirectory')!, 'Logs');
5872
const logFilePath = path.join(logFilesDirectory, `UnityBuildLog_${Utilities.getLogFileNameTimeStamp()}.log`);
73+
tl.setVariable(editorLogFilePathOutputVariableName, logFilePath);
5974

6075
// If clean was specified by the user, delete the existing output directory, if it exists
6176
if (cleanBuild === 'true') {
@@ -73,13 +88,13 @@ async function run() {
7388
.arg('-projectPath').arg(projectPath)
7489
.arg('-logfile').arg(logFilePath);
7590

76-
const additionalArgs = tl.getInput('additionalCmdArgs') ?? '';
91+
const additionalArgs = tl.getInput(additionalCmdArgsInputVariableName) ?? '';
7792
if (additionalArgs !== '') {
7893
unityCmd.line(additionalArgs);
7994
}
8095

8196
// Perform setup depending on build script type selected
82-
const buildScriptType = tl.getInput('buildScriptType') ?? 'default';
97+
const buildScriptType = tl.getInput(buildScriptTypeInputVariableName) ?? 'default';
8398

8499
if (buildScriptType === 'default') {
85100
// When using default build scripts we rely on a Utility package being installed to the project via the Unity Package Manager.
@@ -88,20 +103,32 @@ async function run() {
88103
unityCmd.arg('-executeMethod').arg('AzurePipelinesBuild.PerformBuild');
89104
unityCmd.arg('-outputFileName').arg(outputFileName);
90105
unityCmd.arg('-outputPath').arg(outputPath);
106+
107+
if (tl.getBoolInput(signAppBundleInputVariableName)) {
108+
unityCmd.arg('-keystoreName').arg(tl.getPathInput(keystoreNameInputVariableName) ?? '');
109+
unityCmd.arg('-keystorePass').arg(tl.getInput(keystorePassInputVariableName) ?? '');
110+
unityCmd.arg('-keystoreAliasName').arg(tl.getInput(keystoreAliasNameInputVariableName) ?? '');
111+
112+
// The alias password is optional and should only be passed, if not empty or undefined.
113+
const keystoreAliasPass = tl.getInput(keystoreAliasPassInputVariableName) ?? '';
114+
if (keystoreAliasPass) {
115+
unityCmd.arg('-keystoreAliasPass').arg(keystoreAliasPass);
116+
}
117+
}
91118
} else if (buildScriptType === 'inline') {
92119
// Create a C# script file in a Editor folder at the root Assets directory level. Then write
93120
// the default or the user's script into it. Unity will then compile it on launch and make sure it's available.
94121
const projectAssetsEditorFolderPath = path.join(`${projectPath}`, 'Assets', 'Editor');
95122
tl.mkdirP(projectAssetsEditorFolderPath);
96123
tl.cd(projectAssetsEditorFolderPath);
97-
tl.writeFile('AzureDevOps.cs', tl.getInput('inlineBuildScript')!);
124+
tl.writeFile('AzureDevOps.cs', tl.getInput(inlineBuildScriptInputVariableName)!);
98125
tl.cd(projectPath);
99126

100127
// Tell Unity which method to execute for build.
101-
unityCmd.arg('-executeMethod').arg(tl.getInput('scriptExecuteMethod')!);
128+
unityCmd.arg('-executeMethod').arg(tl.getInput(scriptExecuteMethodInputVariableName)!);
102129
} else if (buildScriptType === 'existing') {
103130
// If the user already has an existing build script we only need the method to execute.
104-
unityCmd.arg('-executeMethod').arg(tl.getInput('scriptExecuteMethod')!).arg('-quit');
131+
unityCmd.arg('-executeMethod').arg(tl.getInput(scriptExecuteMethodInputVariableName)!).arg('-quit');
105132
} else {
106133
throw `Unsupported build script type ${buildScriptType}`
107134
}

0 commit comments

Comments
 (0)