Skip to content

Commit 696d21f

Browse files
committed
Make sure to swtitch branch before making changes
1 parent 4a556b4 commit 696d21f

File tree

3 files changed

+248
-228
lines changed

3 files changed

+248
-228
lines changed
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
import {
2+
UnityToolRunner,
3+
UnityPathTools,
4+
UnityVersionInfoResult,
5+
Utilities,
6+
UnityPackageManagerTools,
7+
UnityVersionTools,
8+
} from "@dinomite-studios/unity-azure-pipelines-tasks-lib";
9+
import fs = require("fs-extra");
10+
import tl = require("azure-pipelines-task-lib/task");
11+
import path = require("path");
12+
import {
13+
outputFileNameInputVariableName,
14+
unityProjectPathInputVariableName,
15+
versionSelectionModeVariableName,
16+
outputPathInputVariableName,
17+
unityEditorsPathModeInputVariableName,
18+
customUnityEditorsPathInputVariableName,
19+
versionInputVariableName,
20+
cleanBuildInputVariableName,
21+
buildFlowInputVariableName,
22+
buildTargetInputVariableName,
23+
buildProfileInputVariableName,
24+
additionalCmdArgsInputVariableName,
25+
buildScriptTypeInputVariableName,
26+
signAppBundleInputVariableName,
27+
keystoreNameInputVariableName,
28+
keystorePassInputVariableName,
29+
keystoreAliasNameInputVariableName,
30+
keystoreAliasPassInputVariableName,
31+
buildAppBundleInputVariableName,
32+
inlineBuildScriptInputVariableName,
33+
scriptExecuteMethodInputVariableName,
34+
editorLogFilePathOutputVariableName,
35+
} from "./variables";
36+
37+
export class UnityBuildProject {
38+
public static async run(): Promise<number> {
39+
// Setup and read inputs.
40+
const outputFileName =
41+
tl.getInput(outputFileNameInputVariableName) ?? "drop";
42+
const projectPath =
43+
tl.getPathInput(unityProjectPathInputVariableName) ?? "";
44+
const versionSelectionMode = tl.getInput(
45+
versionSelectionModeVariableName,
46+
true
47+
)!;
48+
const outputPath = tl.getPathInput(outputPathInputVariableName) ?? "";
49+
const unityEditorsPath = UnityPathTools.getUnityEditorsPath(
50+
tl.getInput(unityEditorsPathModeInputVariableName, true)!,
51+
tl.getInput(customUnityEditorsPathInputVariableName)
52+
);
53+
54+
let unityVersion: UnityVersionInfoResult;
55+
if (versionSelectionMode === "specify") {
56+
let customVersion = tl.getInput(versionInputVariableName, true)!;
57+
unityVersion = {
58+
info: {
59+
isAlpha: false,
60+
isBeta: false,
61+
version: customVersion,
62+
revision: undefined,
63+
},
64+
error: undefined,
65+
};
66+
} else {
67+
unityVersion = getUnityEditorVersion();
68+
}
69+
70+
const unityExecutablePath = UnityPathTools.getUnityExecutableFullPath(
71+
unityEditorsPath,
72+
unityVersion.info!
73+
);
74+
const cleanBuild = tl.getVariable(cleanBuildInputVariableName);
75+
76+
// Set output variable values.
77+
const logFilesDirectory = path.join(
78+
tl.getVariable("Agent.TempDirectory")!,
79+
"Logs"
80+
);
81+
const logFilePath = path.join(
82+
logFilesDirectory,
83+
`UnityBuildLog_${Utilities.getLogFileNameTimeStamp()}.log`
84+
);
85+
tl.setVariable(editorLogFilePathOutputVariableName, logFilePath);
86+
87+
// If clean was specified by the user, delete the existing output directory, if it exists
88+
if (cleanBuild === "true") {
89+
fs.removeSync(outputPath);
90+
}
91+
92+
// No matter if clean build or not, make sure the output diretory exists
93+
tl.mkdirP(outputPath);
94+
tl.checkPath(outputPath, "Build Output Directory");
95+
96+
// Execute Unity command line.
97+
const buildFlow = tl.getInput(buildFlowInputVariableName) ?? "platform";
98+
const unityCmd = tl
99+
.tool(unityExecutablePath)
100+
.arg("-batchmode")
101+
.arg(buildFlow === "platform" ? "-buildTarget" : "-activeBuildProfile")
102+
.arg(
103+
tl.getInput(
104+
buildFlow === "platform"
105+
? buildTargetInputVariableName
106+
: buildProfileInputVariableName,
107+
true
108+
)!
109+
)
110+
.arg("-projectPath")
111+
.arg(projectPath)
112+
.arg("-logfile")
113+
.arg(logFilePath);
114+
115+
const additionalArgs =
116+
tl.getInput(additionalCmdArgsInputVariableName) ?? "";
117+
if (additionalArgs !== "") {
118+
unityCmd.line(additionalArgs);
119+
}
120+
121+
// Perform setup depending on build script type selected
122+
const buildScriptType =
123+
tl.getInput(buildScriptTypeInputVariableName) ?? "default";
124+
125+
if (buildScriptType === "default") {
126+
// When using default build scripts we rely on a Utility package being installed to the project via the Unity Package Manager.
127+
// By adding it to the manifest before opening the project, Unity will load the package before trying to build the project.
128+
UnityPackageManagerTools.addPackageToProject(
129+
projectPath,
130+
"games.dinomite.azurepipelines",
131+
"https://github.com/Dinomite-Studios/games.dinomite.azurepipelines.git#v1.0.14"
132+
);
133+
unityCmd.arg("-executeMethod").arg("AzurePipelinesBuild.PerformBuild");
134+
unityCmd.arg("-outputFileName").arg(outputFileName);
135+
unityCmd.arg("-outputPath").arg(outputPath);
136+
137+
if (tl.getBoolInput(signAppBundleInputVariableName)) {
138+
unityCmd
139+
.arg("-keystoreName")
140+
.arg(tl.getPathInput(keystoreNameInputVariableName) ?? "");
141+
unityCmd
142+
.arg("-keystorePass")
143+
.arg(tl.getInput(keystorePassInputVariableName) ?? "");
144+
unityCmd
145+
.arg("-keystoreAliasName")
146+
.arg(tl.getInput(keystoreAliasNameInputVariableName) ?? "");
147+
148+
// The alias password is optional and should only be passed, if not empty or undefined.
149+
const keystoreAliasPass =
150+
tl.getInput(keystoreAliasPassInputVariableName) ?? "";
151+
if (keystoreAliasPass) {
152+
unityCmd.arg("-keystoreAliasPass").arg(keystoreAliasPass);
153+
}
154+
}
155+
156+
if (tl.getBoolInput(buildAppBundleInputVariableName)) {
157+
unityCmd.arg("-buildAppBundle");
158+
}
159+
} else if (buildScriptType === "inline") {
160+
// Create a C# script file in a Editor folder at the root Assets directory level. Then write
161+
// the default or the user's script into it. Unity will then compile it on launch and make sure it's available.
162+
const projectAssetsEditorFolderPath = path.join(
163+
`${projectPath}`,
164+
"Assets",
165+
"Editor"
166+
);
167+
tl.mkdirP(projectAssetsEditorFolderPath);
168+
tl.cd(projectAssetsEditorFolderPath);
169+
tl.writeFile(
170+
"AzureDevOps.cs",
171+
tl.getInput(inlineBuildScriptInputVariableName)!
172+
);
173+
tl.cd(projectPath);
174+
175+
// Tell Unity which method to execute for build.
176+
unityCmd
177+
.arg("-executeMethod")
178+
.arg(tl.getInput(scriptExecuteMethodInputVariableName)!);
179+
} else if (buildScriptType === "existing") {
180+
// If the user already has an existing build script we only need the method to execute.
181+
unityCmd
182+
.arg("-executeMethod")
183+
.arg(tl.getInput(scriptExecuteMethodInputVariableName)!)
184+
.arg("-quit");
185+
} else {
186+
throw `Unsupported build script type ${buildScriptType}`;
187+
}
188+
189+
const result = await UnityToolRunner.run(unityCmd, logFilePath);
190+
return result;
191+
}
192+
}
193+
194+
function getUnityEditorVersion(): UnityVersionInfoResult {
195+
const projectPath = tl.getPathInput("unityProjectPath") ?? "";
196+
console.log(`${tl.loc("projectPathInfo")} ${projectPath}`);
197+
198+
const unityVersion =
199+
UnityVersionTools.determineProjectVersionFromFile(projectPath);
200+
if (unityVersion.error) {
201+
const error = `${tl.loc("failGetUnityEditorVersion")} | ${
202+
unityVersion.error
203+
}`;
204+
console.error(error);
205+
throw new Error(error);
206+
}
207+
208+
const successGetVersionLog = `${tl.loc("successGetUnityEditorVersion")} ${
209+
unityVersion.info!.version
210+
}${
211+
unityVersion.info!.revision
212+
? `, revision=${unityVersion.info!.revision}`
213+
: ""
214+
}, alpha=${unityVersion.info!.isAlpha}, beta=${unityVersion.info!.isBeta}`;
215+
console.log(successGetVersionLog);
216+
217+
if (unityVersion.info!.isAlpha || unityVersion.info!.isBeta) {
218+
console.warn(tl.loc("warningAlphaBetaVersion"));
219+
}
220+
221+
return unityVersion;
222+
}

0 commit comments

Comments
 (0)