Skip to content

Commit 9d6bdcb

Browse files
feat: add buildProfile parameter (#685)
* feat: add `buildProfile` parameter add new `buildProfile` action param, which will be passed into Unity as the `-activeBuildProfile ...` CLI param. closes #674 * ci: add tests for Unity 6 and build profiles
1 parent 3ae9ec8 commit 9d6bdcb

File tree

18 files changed

+246
-44
lines changed

18 files changed

+246
-44
lines changed

.github/workflows/build-tests-ubuntu.yml

+12-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ env:
3636

3737
jobs:
3838
buildForAllPlatformsUbuntu:
39-
name: ${{ matrix.targetPlatform }} on ${{ matrix.unityVersion }}
39+
name:
40+
"${{ matrix.targetPlatform }} on ${{ matrix.unityVersion}}${{startsWith(matrix.buildProfile, 'Assets') && ' (via Build Profile)' || '' }}"
4041
runs-on: ubuntu-latest
4142
strategy:
4243
fail-fast: false
@@ -91,6 +92,12 @@ jobs:
9192
- targetPlatform: StandaloneWindows64
9293
additionalParameters: -standaloneBuildSubtarget Server
9394
buildWithIl2cpp: true
95+
include:
96+
- unityVersion: 6000.0.36f1
97+
targetPlatform: WebGL
98+
- unityVersion: 6000.0.36f1
99+
targetPlatform: WebGL
100+
buildProfile: 'Assets/Settings/Build Profiles/Sample WebGL Build Profile.asset'
94101

95102
steps:
96103
- name: Clear Space for Android Build
@@ -136,6 +143,7 @@ jobs:
136143
with:
137144
buildName: 'GameCI Test Build'
138145
projectPath: ${{ matrix.projectPath }}
146+
buildProfile: ${{ matrix.buildProfile }}
139147
unityVersion: ${{ matrix.unityVersion }}
140148
targetPlatform: ${{ matrix.targetPlatform }}
141149
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue ${{ matrix.additionalParameters }}
@@ -158,6 +166,7 @@ jobs:
158166
with:
159167
buildName: 'GameCI Test Build'
160168
projectPath: ${{ matrix.projectPath }}
169+
buildProfile: ${{ matrix.buildProfile }}
161170
unityVersion: ${{ matrix.unityVersion }}
162171
targetPlatform: ${{ matrix.targetPlatform }}
163172
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue ${{ matrix.additionalParameters }}
@@ -179,6 +188,7 @@ jobs:
179188
with:
180189
buildName: 'GameCI Test Build'
181190
projectPath: ${{ matrix.projectPath }}
191+
buildProfile: ${{ matrix.buildProfile }}
182192
unityVersion: ${{ matrix.unityVersion }}
183193
targetPlatform: ${{ matrix.targetPlatform }}
184194
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue ${{ matrix.additionalParameters }}
@@ -191,7 +201,6 @@ jobs:
191201
- uses: actions/upload-artifact@v4
192202
with:
193203
name:
194-
'Build ${{ matrix.targetPlatform }} on Ubuntu (${{ matrix.unityVersion }}_il2cpp_${{ matrix.buildWithIl2cpp
195-
}}_params_${{ matrix.additionalParameters }})'
204+
"Build ${{ matrix.targetPlatform }}${{ startsWith(matrix.buildProfile, 'Assets') && ' (via Build Profile)' || '' }} on Ubuntu (${{ matrix.unityVersion }}_il2cpp_${{ matrix.buildWithIl2cpp }}_params_${{ matrix.additionalParameters }})"
196205
path: build
197206
retention-days: 14

action.yml

+5-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ inputs:
1818
projectPath:
1919
required: false
2020
default: ''
21-
description: 'Relative path to the project to be built.'
21+
description: 'Path to the project to be built, relative to the repository root.'
22+
buildProfile:
23+
required: false
24+
default: ''
25+
description: 'Path to the build profile to activate, relative to the project root.'
2226
buildName:
2327
required: false
2428
default: ''

dist/default-build-script/Assets/Editor/UnityBuilderAction/Builder.cs

+70-39
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
using UnityBuilderAction.Versioning;
77
using UnityEditor;
88
using UnityEditor.Build.Reporting;
9+
#if UNITY_6000_0_OR_NEWER
10+
using UnityEditor.Build.Profile;
11+
#endif
912
using UnityEngine;
1013

1114
namespace UnityBuilderAction
@@ -17,47 +20,9 @@ public static void BuildProject()
1720
// Gather values from args
1821
var options = ArgumentsParser.GetValidatedOptions();
1922

20-
// Gather values from project
21-
var scenes = EditorBuildSettings.scenes.Where(scene => scene.enabled).Select(s => s.path).ToArray();
22-
23-
// Get all buildOptions from options
24-
BuildOptions buildOptions = BuildOptions.None;
25-
foreach (string buildOptionString in Enum.GetNames(typeof(BuildOptions))) {
26-
if (options.ContainsKey(buildOptionString)) {
27-
BuildOptions buildOptionEnum = (BuildOptions) Enum.Parse(typeof(BuildOptions), buildOptionString);
28-
buildOptions |= buildOptionEnum;
29-
}
30-
}
31-
32-
#if UNITY_2021_2_OR_NEWER
33-
// Determine subtarget
34-
StandaloneBuildSubtarget buildSubtarget;
35-
if (!options.TryGetValue("standaloneBuildSubtarget", out var subtargetValue) || !Enum.TryParse(subtargetValue, out buildSubtarget)) {
36-
buildSubtarget = default;
37-
}
38-
#endif
39-
40-
// Define BuildPlayer Options
41-
var buildPlayerOptions = new BuildPlayerOptions {
42-
scenes = scenes,
43-
locationPathName = options["customBuildPath"],
44-
target = (BuildTarget) Enum.Parse(typeof(BuildTarget), options["buildTarget"]),
45-
options = buildOptions,
46-
#if UNITY_2021_2_OR_NEWER
47-
subtarget = (int) buildSubtarget
48-
#endif
49-
};
50-
5123
// Set version for this build
5224
VersionApplicator.SetVersion(options["buildVersion"]);
53-
54-
// Apply Android settings
55-
if (buildPlayerOptions.target == BuildTarget.Android)
56-
{
57-
VersionApplicator.SetAndroidVersionCode(options["androidVersionCode"]);
58-
AndroidSettings.Apply(options);
59-
}
60-
25+
6126
// Execute default AddressableAsset content build, if the package is installed.
6227
// Version defines would be the best solution here, but Unity 2018 doesn't support that,
6328
// so we fall back to using reflection instead.
@@ -78,6 +43,72 @@ public static void BuildProject()
7843
}
7944
}
8045

46+
// Get all buildOptions from options
47+
BuildOptions buildOptions = BuildOptions.None;
48+
foreach (string buildOptionString in Enum.GetNames(typeof(BuildOptions))) {
49+
if (options.ContainsKey(buildOptionString)) {
50+
BuildOptions buildOptionEnum = (BuildOptions) Enum.Parse(typeof(BuildOptions), buildOptionString);
51+
buildOptions |= buildOptionEnum;
52+
}
53+
}
54+
55+
// Depending on whether the build is using a build profile, `buildPlayerOptions` will an instance
56+
// of either `UnityEditor.BuildPlayerOptions` or `UnityEditor.BuildPlayerWithProfileOptions`
57+
dynamic buildPlayerOptions;
58+
59+
if (options["customBuildProfile"] != "") {
60+
61+
#if UNITY_6000_0_OR_NEWER
62+
// Load build profile from Assets folder
63+
BuildProfile buildProfile = AssetDatabase.LoadAssetAtPath<BuildProfile>(options["customBuildProfile"]);
64+
65+
// Set it as active
66+
BuildProfile.SetActiveBuildProfile(buildProfile);
67+
68+
// Define BuildPlayerWithProfileOptions
69+
buildPlayerOptions = new BuildPlayerWithProfileOptions {
70+
buildProfile = buildProfile,
71+
locationPathName = options["customBuildPath"],
72+
options = buildOptions,
73+
};
74+
#else
75+
throw new Exception("Build profiles are not supported by this version of Unity (" + Application.unityVersion +")");
76+
#endif
77+
78+
} else {
79+
80+
// Gather values from project
81+
var scenes = EditorBuildSettings.scenes.Where(scene => scene.enabled).Select(s => s.path).ToArray();
82+
83+
#if UNITY_2021_2_OR_NEWER
84+
// Determine subtarget
85+
StandaloneBuildSubtarget buildSubtarget;
86+
if (!options.TryGetValue("standaloneBuildSubtarget", out var subtargetValue) || !Enum.TryParse(subtargetValue, out buildSubtarget)) {
87+
buildSubtarget = default;
88+
}
89+
#endif
90+
91+
BuildTarget buildTarget = (BuildTarget) Enum.Parse(typeof(BuildTarget), options["buildTarget"]);
92+
93+
// Define BuildPlayerOptions
94+
buildPlayerOptions = new BuildPlayerOptions {
95+
scenes = scenes,
96+
locationPathName = options["customBuildPath"],
97+
target = buildTarget,
98+
options = buildOptions,
99+
#if UNITY_2021_2_OR_NEWER
100+
subtarget = (int) buildSubtarget
101+
#endif
102+
};
103+
104+
// Apply Android settings
105+
if (buildTarget == BuildTarget.Android) {
106+
VersionApplicator.SetAndroidVersionCode(options["androidVersionCode"]);
107+
AndroidSettings.Apply(options);
108+
}
109+
110+
}
111+
81112
// Perform build
82113
BuildReport buildReport = BuildPipeline.BuildPlayer(buildPlayerOptions);
83114

dist/index.js

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/platforms/mac/steps/build.sh

+18
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,23 @@ echo "Using build name \"$BUILD_NAME\"."
1919

2020
echo "Using build target \"$BUILD_TARGET\"."
2121

22+
#
23+
# Display the build profile
24+
#
25+
26+
if [ -z "$BUILD_PROFILE" ]; then
27+
# User has not provided a build profile
28+
#
29+
echo "Doing a default \"$BUILD_TARGET\" platform build."
30+
#
31+
else
32+
# User has provided a path to a build profile `.asset` file
33+
#
34+
echo "Using build profile \"$BUILD_PROFILE\" relative to \"$UNITY_PROJECT_PATH\"."
35+
#
36+
fi
37+
38+
2239
#
2340
# Display build path and file
2441
#
@@ -139,6 +156,7 @@ echo ""
139156
-buildTarget "$BUILD_TARGET" \
140157
-customBuildTarget "$BUILD_TARGET" \
141158
-customBuildPath "$CUSTOM_BUILD_PATH" \
159+
-customBuildProfile "$BUILD_PROFILE" \
142160
-executeMethod "$BUILD_METHOD" \
143161
-buildVersion "$VERSION" \
144162
-androidVersionCode "$ANDROID_VERSION_CODE" \

dist/platforms/ubuntu/steps/build.sh

+17
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,22 @@ echo "Using build name \"$BUILD_NAME\"."
1919

2020
echo "Using build target \"$BUILD_TARGET\"."
2121

22+
#
23+
# Display the build profile
24+
#
25+
26+
if [ -z "$BUILD_PROFILE" ]; then
27+
# User has not provided a build profile
28+
#
29+
echo "Doing a default \"$BUILD_TARGET\" platform build."
30+
#
31+
else
32+
# User has provided a path to a build profile `.asset` file
33+
#
34+
echo "Using build profile \"$BUILD_PROFILE\" relative to \"$UNITY_PROJECT_PATH\"."
35+
#
36+
fi
37+
2238
#
2339
# Display build path and file
2440
#
@@ -112,6 +128,7 @@ unity-editor \
112128
-buildTarget "$BUILD_TARGET" \
113129
-customBuildTarget "$BUILD_TARGET" \
114130
-customBuildPath "$CUSTOM_BUILD_PATH" \
131+
-customBuildProfile "$BUILD_PROFILE" \
115132
-executeMethod "$BUILD_METHOD" \
116133
-buildVersion "$VERSION" \
117134
-androidVersionCode "$ANDROID_VERSION_CODE" \

dist/platforms/windows/build.ps1

+20
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,25 @@ Write-Output "$('Using build name "')$($Env:BUILD_NAME)$('".')"
1616

1717
Write-Output "$('Using build target "')$($Env:BUILD_TARGET)$('".')"
1818

19+
#
20+
# Display the build profile
21+
#
22+
23+
if ($Env:BUILD_PROFILE)
24+
{
25+
# User has provided a path to a build profile `.asset` file
26+
#
27+
Write-Output "$('Using build profile "')$($Env:BUILD_PROFILE)$('" relative to "')$($Env:UNITY_PROJECT_PATH)$('".')"
28+
#
29+
}
30+
else
31+
{
32+
# User has not provided a build profile
33+
#
34+
Write-Output "$('Doing a default "')$($Env:BUILD_TARGET)$('" platform build.')"
35+
#
36+
}
37+
1938
#
2039
# Display build path and file
2140
#
@@ -143,6 +162,7 @@ $unityArgs = @(
143162
"-buildTarget", "`"$Env:BUILD_TARGET`"",
144163
"-customBuildTarget", "`"$Env:BUILD_TARGET`"",
145164
"-customBuildPath", "`"$Env:CUSTOM_BUILD_PATH`"",
165+
"-customBuildProfile", "`"$Env:BUILD_PROFILE`"",
146166
"-buildVersion", "`"$Env:VERSION`"",
147167
"-androidVersionCode", "`"$Env:ANDROID_VERSION_CODE`"",
148168
"-androidKeystorePass", "`"$Env:ANDROID_KEYSTORE_PASS`"",

src/model/build-parameters.test.ts

+6
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ describe('BuildParameters', () => {
7171
await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ projectPath: mockValue }));
7272
});
7373

74+
it('returns the build profile', async () => {
75+
const mockValue = 'path/to/build_profile.asset';
76+
jest.spyOn(Input, 'buildProfile', 'get').mockReturnValue(mockValue);
77+
await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ buildProfile: mockValue }));
78+
});
79+
7480
it('returns the build name', async () => {
7581
const mockValue = 'someBuildName';
7682
jest.spyOn(Input, 'buildName', 'get').mockReturnValue(mockValue);

src/model/build-parameters.ts

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class BuildParameters {
2626
public runnerTempPath!: string;
2727
public targetPlatform!: string;
2828
public projectPath!: string;
29+
public buildProfile!: string;
2930
public buildName!: string;
3031
public buildPath!: string;
3132
public buildFile!: string;
@@ -152,6 +153,7 @@ class BuildParameters {
152153
runnerTempPath: Input.runnerTempPath,
153154
targetPlatform: Input.targetPlatform,
154155
projectPath: Input.projectPath,
156+
buildProfile: Input.buildProfile,
155157
buildName: Input.buildName,
156158
buildPath: `${Input.buildsPath}/${Input.targetPlatform}`,
157159
buildFile,

src/model/image-environment-factory.ts

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class ImageEnvironmentFactory {
3636
value: process.env.USYM_UPLOAD_AUTH_TOKEN,
3737
},
3838
{ name: 'PROJECT_PATH', value: parameters.projectPath },
39+
{ name: 'BUILD_PROFILE', value: parameters.buildProfile },
3940
{ name: 'BUILD_TARGET', value: parameters.targetPlatform },
4041
{ name: 'BUILD_NAME', value: parameters.buildName },
4142
{ name: 'BUILD_PATH', value: parameters.buildPath },

src/model/input.test.ts

+13
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,19 @@ describe('Input', () => {
5959
});
6060
});
6161

62+
describe('buildProfile', () => {
63+
it('returns the default value', () => {
64+
expect(Input.buildProfile).toStrictEqual('');
65+
});
66+
67+
it('takes input from the users workflow', () => {
68+
const mockValue = 'path/to/build_profile.asset';
69+
const spy = jest.spyOn(core, 'getInput').mockReturnValue(mockValue);
70+
expect(Input.buildProfile).toStrictEqual(mockValue);
71+
expect(spy).toHaveBeenCalledTimes(1);
72+
});
73+
});
74+
6275
describe('buildName', () => {
6376
it('returns the default value', () => {
6477
expect(Input.buildName).toStrictEqual(Input.targetPlatform);

src/model/input.ts

+4
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ class Input {
107107
return rawProjectPath.replace(/\/$/, '');
108108
}
109109

110+
static get buildProfile(): string {
111+
return Input.getInput('buildProfile') ?? '';
112+
}
113+
110114
static get runnerTempPath(): string {
111115
return Input.getInput('RUNNER_TEMP') ?? '';
112116
}

0 commit comments

Comments
 (0)