mirror of
https://github.com/game-ci/unity-builder.git
synced 2026-09-29 12:07:05 -07:00
fix: replicate the original action's test-project auto-detection
Real gap caught by live CI (Builds - MacOS's 6000.0.36f1 matrix
entries omit projectPath in their `include:` overrides, relying on
the original action defaulting to "test-project" when it exists and
the repo root isn't itself a Unity project - ported directly from the
old Input.projectPath getter). Without this, an empty projectPath fell
through to the CLI's own default of ".", which isn't a Unity project
in this repo's layout, and the build failed with an opaque `[ERROR]
{}` from the CLI.
resolve-project-path.ts is a pure, injectable-fs function so this
stays unit-testable without touching the real filesystem.
This commit is contained in:
+32
-1
@@ -279,10 +279,13 @@ exports.run = void 0;
|
|||||||
// UNITY_LICENSE, UNITY_LICENSING_SERVER) are read by the CLI itself from
|
// UNITY_LICENSE, UNITY_LICENSING_SERVER) are read by the CLI itself from
|
||||||
// its own process environment - never passed as CLI arguments, since argv
|
// its own process environment - never passed as CLI arguments, since argv
|
||||||
// can leak through process listings and command-logging.
|
// can leak through process listings and command-logging.
|
||||||
|
const fs = __importStar(__nccwpck_require__(7561));
|
||||||
|
const path = __importStar(__nccwpck_require__(9411));
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const exec = __importStar(__nccwpck_require__(1514));
|
const exec = __importStar(__nccwpck_require__(1514));
|
||||||
const build_args_1 = __nccwpck_require__(89);
|
const build_args_1 = __nccwpck_require__(89);
|
||||||
const download_cli_1 = __nccwpck_require__(3431);
|
const download_cli_1 = __nccwpck_require__(3431);
|
||||||
|
const resolve_project_path_1 = __nccwpck_require__(2833);
|
||||||
async function run() {
|
async function run() {
|
||||||
try {
|
try {
|
||||||
const unityVersion = core.getInput('unityVersion') || 'auto';
|
const unityVersion = core.getInput('unityVersion') || 'auto';
|
||||||
@@ -293,7 +296,14 @@ async function run() {
|
|||||||
}
|
}
|
||||||
const cliVersion = core.getInput('cliVersion') || 'latest';
|
const cliVersion = core.getInput('cliVersion') || 'latest';
|
||||||
const cliPath = await (0, download_cli_1.downloadCli)(cliVersion);
|
const cliPath = await (0, download_cli_1.downloadCli)(cliVersion);
|
||||||
const args = (0, build_args_1.buildCliArgs)({ getInput: (name) => core.getInput(name) });
|
const projectPath = (0, resolve_project_path_1.resolveProjectPath)({
|
||||||
|
input: core.getInput('projectPath'),
|
||||||
|
existsSync: fs.existsSync,
|
||||||
|
joinPath: path.join,
|
||||||
|
});
|
||||||
|
const args = (0, build_args_1.buildCliArgs)({
|
||||||
|
getInput: (name) => (name === 'projectPath' ? projectPath : core.getInput(name)),
|
||||||
|
});
|
||||||
const exitCode = await exec.exec(cliPath, args, { ignoreReturnCode: true });
|
const exitCode = await exec.exec(cliPath, args, { ignoreReturnCode: true });
|
||||||
// Matches the original action's engineExitCode output: 0 on success,
|
// Matches the original action's engineExitCode output: 0 on success,
|
||||||
// otherwise the exit code of whichever step (activation or build)
|
// otherwise the exit code of whichever step (activation or build)
|
||||||
@@ -317,6 +327,27 @@ if (process.env.NODE_ENV !== 'test') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 2833:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.resolveProjectPath = void 0;
|
||||||
|
function resolveProjectPath({ input, existsSync, joinPath }) {
|
||||||
|
if (input)
|
||||||
|
return input.replace(/\/$/, '');
|
||||||
|
const hasTestProject = existsSync(joinPath('test-project', 'ProjectSettings', 'ProjectVersion.txt'));
|
||||||
|
const hasRootProject = existsSync(joinPath('ProjectSettings', 'ProjectVersion.txt'));
|
||||||
|
if (hasTestProject && !hasRootProject)
|
||||||
|
return 'test-project';
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
exports.resolveProjectPath = resolveProjectPath;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 7799:
|
/***/ 7799:
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
+12
-1
@@ -8,10 +8,13 @@
|
|||||||
// UNITY_LICENSE, UNITY_LICENSING_SERVER) are read by the CLI itself from
|
// UNITY_LICENSE, UNITY_LICENSING_SERVER) are read by the CLI itself from
|
||||||
// its own process environment - never passed as CLI arguments, since argv
|
// its own process environment - never passed as CLI arguments, since argv
|
||||||
// can leak through process listings and command-logging.
|
// can leak through process listings and command-logging.
|
||||||
|
import * as fs from 'node:fs';
|
||||||
|
import * as path from 'node:path';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
import { buildCliArgs } from './build-args';
|
import { buildCliArgs } from './build-args';
|
||||||
import { downloadCli } from './download-cli';
|
import { downloadCli } from './download-cli';
|
||||||
|
import { resolveProjectPath } from './resolve-project-path';
|
||||||
|
|
||||||
export async function run() {
|
export async function run() {
|
||||||
try {
|
try {
|
||||||
@@ -27,7 +30,15 @@ export async function run() {
|
|||||||
const cliVersion = core.getInput('cliVersion') || 'latest';
|
const cliVersion = core.getInput('cliVersion') || 'latest';
|
||||||
const cliPath = await downloadCli(cliVersion);
|
const cliPath = await downloadCli(cliVersion);
|
||||||
|
|
||||||
const args = buildCliArgs({ getInput: (name) => core.getInput(name) });
|
const projectPath = resolveProjectPath({
|
||||||
|
input: core.getInput('projectPath'),
|
||||||
|
existsSync: fs.existsSync,
|
||||||
|
joinPath: path.join,
|
||||||
|
});
|
||||||
|
|
||||||
|
const args = buildCliArgs({
|
||||||
|
getInput: (name) => (name === 'projectPath' ? projectPath : core.getInput(name)),
|
||||||
|
});
|
||||||
|
|
||||||
const exitCode = await exec.exec(cliPath, args, { ignoreReturnCode: true });
|
const exitCode = await exec.exec(cliPath, args, { ignoreReturnCode: true });
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { resolveProjectPath } from './resolve-project-path';
|
||||||
|
|
||||||
|
function fsOf(existingPaths: string[]) {
|
||||||
|
return {
|
||||||
|
joinPath: (...segments: string[]) => segments.join('/'),
|
||||||
|
existsSync: (candidate: string) => existingPaths.includes(candidate),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('resolveProjectPath', () => {
|
||||||
|
it('returns the explicit input unchanged when given', () => {
|
||||||
|
const result = resolveProjectPath({
|
||||||
|
input: 'my-project',
|
||||||
|
...fsOf(['test-project/ProjectSettings/ProjectVersion.txt']),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toBe('my-project');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('strips a trailing slash from an explicit input', () => {
|
||||||
|
const result = resolveProjectPath({ input: 'my-project/', ...fsOf([]) });
|
||||||
|
|
||||||
|
expect(result).toBe('my-project');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('defaults to "test-project" when it looks like a Unity project and the repo root does not', () => {
|
||||||
|
const result = resolveProjectPath({
|
||||||
|
input: '',
|
||||||
|
...fsOf(['test-project/ProjectSettings/ProjectVersion.txt']),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toBe('test-project');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not default to "test-project" when the repo root is itself a Unity project', () => {
|
||||||
|
const result = resolveProjectPath({
|
||||||
|
input: '',
|
||||||
|
...fsOf([
|
||||||
|
'test-project/ProjectSettings/ProjectVersion.txt',
|
||||||
|
'ProjectSettings/ProjectVersion.txt',
|
||||||
|
]),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns empty (letting the cli default to ".") when neither location looks like a Unity project', () => {
|
||||||
|
const result = resolveProjectPath({ input: '', ...fsOf([]) });
|
||||||
|
|
||||||
|
expect(result).toBe('');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Replicates the original action's projectPath auto-detection: when
|
||||||
|
* projectPath isn't given explicitly, and a test-project/ directory looks
|
||||||
|
* like a Unity project while the current directory doesn't, default to
|
||||||
|
* "test-project" instead of the repo root. See the original
|
||||||
|
* Input.projectPath getter this is ported from.
|
||||||
|
*/
|
||||||
|
export interface ResolveProjectPathOptions {
|
||||||
|
input: string;
|
||||||
|
existsSync(path: string): boolean;
|
||||||
|
joinPath(...segments: string[]): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolveProjectPath({
|
||||||
|
input,
|
||||||
|
existsSync,
|
||||||
|
joinPath,
|
||||||
|
}: ResolveProjectPathOptions): string {
|
||||||
|
if (input) return input.replace(/\/$/, '');
|
||||||
|
|
||||||
|
const hasTestProject = existsSync(
|
||||||
|
joinPath('test-project', 'ProjectSettings', 'ProjectVersion.txt'),
|
||||||
|
);
|
||||||
|
const hasRootProject = existsSync(joinPath('ProjectSettings', 'ProjectVersion.txt'));
|
||||||
|
|
||||||
|
if (hasTestProject && !hasRootProject) return 'test-project';
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user