Compare commits

...

3 Commits

Author SHA1 Message Date
Frostebite
a38ec6caef Merge branch 'main' into linux-extension-rebased 2026-05-06 22:33:44 +01:00
Christian Tellefsen
2240bedf08 fix: update action runtime from Node.js 20 to Node.js 24 (#827)
GitHub is deprecating Node.js 20 on Actions runners:
- June 2, 2026: Node.js 24 forced as default
- September 16, 2026: Node.js 20 removed

Ref: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
Closes #826

Co-authored-by: Frostebite <jas.f.ukcmti@gmail.com>
2026-05-06 22:25:02 +01:00
frostebite
37ce35f1a5 feat: add linux64RemoveExecutableExtension parameter (default: false)
Adds configurable control over the `.x86_64` file extension for
StandaloneLinux64 builds. Default is `false` (keep the extension),
matching Unity's native behavior.

Set `linux64RemoveExecutableExtension: true` to restore the
extensionless behavior from v4.

Rebased from kitlith's original PR #726. Default flipped for v5.

Closes #722

Co-Authored-By: kitlith <kitlith@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-06 22:05:23 +01:00
5 changed files with 52 additions and 10 deletions

View File

@@ -178,6 +178,11 @@ inputs:
default: 'false' default: 'false'
required: false required: false
description: 'Skip the activation/deactivation of Unity. This assumes Unity is already activated.' description: 'Skip the activation/deactivation of Unity. This assumes Unity is already activated.'
linux64RemoveExecutableExtension:
default: 'false'
required: false
description:
'When building for StandaloneLinux64, remove the default file extension of `.x86_64`. Set to true to restore the extensionless behavior from v4.'
outputs: outputs:
volume: volume:
@@ -195,5 +200,5 @@ branding:
icon: 'box' icon: 'box'
color: 'gray-dark' color: 'gray-dark'
runs: runs:
using: 'node20' using: 'node24'
main: 'dist/index.js' main: 'dist/index.js'

View File

@@ -117,18 +117,21 @@ describe('BuildParameters', () => {
}); });
test.each` test.each`
targetPlatform | expectedExtension | androidExportType targetPlatform | expectedExtension | androidExportType | linux64RemoveExecutableExtension
${Platform.types.Android} | ${'.apk'} | ${'androidPackage'} ${Platform.types.Android} | ${'.apk'} | ${'androidPackage'} | ${false}
${Platform.types.Android} | ${'.aab'} | ${'androidAppBundle'} ${Platform.types.Android} | ${'.aab'} | ${'androidAppBundle'} | ${true}
${Platform.types.Android} | ${''} | ${'androidStudioProject'} ${Platform.types.Android} | ${''} | ${'androidStudioProject'} | ${false}
${Platform.types.StandaloneWindows} | ${'.exe'} | ${'n/a'} ${Platform.types.StandaloneWindows} | ${'.exe'} | ${'n/a'} | ${true}
${Platform.types.StandaloneWindows64} | ${'.exe'} | ${'n/a'} ${Platform.types.StandaloneWindows64} | ${'.exe'} | ${'n/a'} | ${false}
${Platform.types.StandaloneLinux64} | ${'.x86_64'} | ${'n/a'} | ${false}
${Platform.types.StandaloneLinux64} | ${''} | ${'n/a'} | ${true}
`( `(
'appends $expectedExtension for $targetPlatform with androidExportType $androidExportType', 'appends $expectedExtension for $targetPlatform with linux64RemoveExecutableExtension=$linux64RemoveExecutableExtension',
async ({ targetPlatform, expectedExtension, androidExportType }) => { async ({ targetPlatform, expectedExtension, androidExportType, linux64RemoveExecutableExtension }) => {
vi.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(targetPlatform); vi.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(targetPlatform);
vi.spyOn(Input, 'buildName', 'get').mockReturnValue(targetPlatform); vi.spyOn(Input, 'buildName', 'get').mockReturnValue(targetPlatform);
vi.spyOn(Input, 'androidExportType', 'get').mockReturnValue(androidExportType); vi.spyOn(Input, 'androidExportType', 'get').mockReturnValue(androidExportType);
vi.spyOn(Input, 'linux64RemoveExecutableExtension', 'get').mockReturnValue(linux64RemoveExecutableExtension);
await expect(BuildParameters.create()).resolves.toEqual( await expect(BuildParameters.create()).resolves.toEqual(
expect.objectContaining({ buildFile: `${targetPlatform}${expectedExtension}` }), expect.objectContaining({ buildFile: `${targetPlatform}${expectedExtension}` }),
); );

View File

@@ -73,6 +73,7 @@ class BuildParameters {
Input.buildName, Input.buildName,
Input.targetPlatform, Input.targetPlatform,
Input.androidExportType, Input.androidExportType,
Input.linux64RemoveExecutableExtension,
); );
const editorVersion = UnityVersioning.determineUnityVersion( const editorVersion = UnityVersioning.determineUnityVersion(
Input.projectPath, Input.projectPath,
@@ -188,7 +189,12 @@ class BuildParameters {
}; };
} }
static parseBuildFile(filename: string, platform: string, androidExportType: string): string { static parseBuildFile(
filename: string,
platform: string,
androidExportType: string,
linux64RemoveExecutableExtension: boolean,
): string {
if (Platform.isWindows(platform)) { if (Platform.isWindows(platform)) {
return `${filename}.exe`; return `${filename}.exe`;
} }
@@ -208,6 +214,10 @@ class BuildParameters {
} }
} }
if (platform === Platform.types.StandaloneLinux64 && !linux64RemoveExecutableExtension) {
return `${filename}.x86_64`;
}
return filename; return filename;
} }

View File

@@ -353,4 +353,22 @@ describe('Input', () => {
expect(spy).toHaveBeenCalledTimes(1); expect(spy).toHaveBeenCalledTimes(1);
}); });
}); });
describe('linux64RemoveExecutableExtension', () => {
it('returns the default value', () => {
expect(Input.linux64RemoveExecutableExtension).toStrictEqual(false);
});
it('returns true when string true is passed', () => {
const spy = vi.spyOn(core, 'getInput').mockReturnValue('true');
expect(Input.linux64RemoveExecutableExtension).toStrictEqual(true);
expect(spy).toHaveBeenCalledTimes(1);
});
it('returns false when string false is passed', () => {
const spy = vi.spyOn(core, 'getInput').mockReturnValue('false');
expect(Input.linux64RemoveExecutableExtension).toStrictEqual(false);
expect(spy).toHaveBeenCalledTimes(1);
});
});
}); });

View File

@@ -284,6 +284,12 @@ class Input {
return Input.getInput('skipActivation')?.toLowerCase() ?? 'false'; return Input.getInput('skipActivation')?.toLowerCase() ?? 'false';
} }
static get linux64RemoveExecutableExtension(): boolean {
const input = Input.getInput('linux64RemoveExecutableExtension') ?? 'false';
return input === 'true';
}
public static ToEnvVarFormat(input: string) { public static ToEnvVarFormat(input: string) {
if (input.toUpperCase() === input) { if (input.toUpperCase() === input) {
return input; return input;