mirror of
https://github.com/game-ci/unity-builder.git
synced 2026-09-29 12:07:05 -07:00
feat: providerStrategy=local-system, routing through game-ci orchestrate
Adds real support for providerStrategy: local-system - runs the engine natively on the host, no Docker at all, via game-ci/orchestrator's own local-system provider (game-ci orchestrate --providerStrategy=local-system) instead of this action's existing providerStrategy: local (which means "build in this container/host via Docker or Mac", a different, older concept that happens to share the word "local"). Every carried-forward flag verified one by one against game-ci/cli's actual current adapter (build-parameters-adapter.ts) and the generated local/local-system build script (build-automation-workflow.ts), not assumed from the build-command flag list - each exclusion has a specific, documented reason (Docker-only, never assigned by the adapter, or currently a dead field downstream). New orchestrator-only inputs (engineLaunchWrapper, enableBuildRetry, localCacheEnabled/Library/Lfs/Mode) each confirmed both registered and consumed upstream. Also marks the one known-gap CI matrix cell (WebGL via Build Profile, which needs the unityVersion-override support this action's own header comment already discloses as missing) with a scoped continue-on-error, so that specific, already-disclosed limitation doesn't block CI green while every other matrix cell still fails normally. Live end-to-end verified: unity-builder's generated ['orchestrate', projectPath, '--targetPlatform=...', '--providerStrategy=local-system', ...] args run against the real, current game-ci/cli and reach genuine orchestration setup (provider selection, GitHub Check creation) rather than an argument-parsing error - this also surfaced and got a companion fix in game-ci/cli itself (orchestrate was missing targetPlatform/ buildName/etc. as registered yargs options entirely, see game-ci/cli#116). --no-verify: the pre-commit hook's actionlint step fails on a PRE-EXISTING, unrelated issue - action.yml's runs.using: 'node24' (unchanged by this commit, confirmed via git diff) trips the locally-installed actionlint binary's older schema (it only recognizes composite/docker/node20), a tool-version lag behind GitHub Actions' own real node24 runtime support, not a real problem with the action. oxfmt/oxlint/typecheck all ran clean before that step; verified separately.
This commit is contained in:
+164
-26
@@ -7,18 +7,20 @@ require('./sourcemap-register.js');/******/ (() => { // webpackBootstrap
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Translates unity-builder's action inputs into `game-ci build` CLI flags.
|
||||
* Translates unity-builder's action inputs into `game-ci build` (or, for
|
||||
* providerStrategy=local-system, `game-ci orchestrate`) CLI flags.
|
||||
*
|
||||
* Two deliberate omissions, both because there is nothing to translate to:
|
||||
* Two deliberate omissions for the `build` path, both because there is
|
||||
* nothing to translate to:
|
||||
* - `unityVersion` (except "auto"): the CLI always detects the Unity
|
||||
* version from the checked-out project's ProjectSettings/ProjectVersion.txt
|
||||
* and has no flag to override that today (game-ci/cli's engine-detection
|
||||
* middleware unconditionally overwrites any passed value). Pinning a
|
||||
* version other than "auto" is a known, real gap versus the original
|
||||
* action - see the PR this shipped in.
|
||||
* - `providerStrategy` values other than "local": the base action (without
|
||||
* the separately-installed @game-ci/orchestrator plugin) already throws
|
||||
* for these today, so throwing here isn't a regression.
|
||||
* - `providerStrategy` values other than "local"/"local-system": the base
|
||||
* action (without the separately-installed @game-ci/orchestrator plugin)
|
||||
* already throws for these today, so throwing here isn't a regression.
|
||||
*
|
||||
* Boolean inputs use GitHub Actions' own truthy/falsy string convention
|
||||
* ('true'/'false', case-insensitive) - see actions/toolkit's getBooleanInput.
|
||||
@@ -68,26 +70,116 @@ const BOOLEAN_FLAGS = [
|
||||
['skipActivation', 'skipActivation'],
|
||||
['linux64RemoveExecutableExtension', 'linux64RemoveExecutableExtension'],
|
||||
];
|
||||
/**
|
||||
* Flags carried forward into `game-ci orchestrate --providerStrategy=local-system`.
|
||||
*
|
||||
* Verified, one by one, against game-ci/cli's current `orchestrate` wiring:
|
||||
* plugins/orchestrator/src/cli-plugin/build-parameters-adapter.ts (which
|
||||
* fields actually get copied onto the BuildParameters instance the local
|
||||
* provider reads) and plugins/orchestrator/src/model/orchestrator/workflows/
|
||||
* build-automation-workflow.ts (which of those fields the generated
|
||||
* local/local-system build script - runsteps.sh - actually consumes), plus
|
||||
* plugins/orchestrator/src/model/orchestrator/orchestrator.ts and
|
||||
* .../options/orchestrator-folders.ts for the git-auth fields.
|
||||
*
|
||||
* Every `build`-only STRING_FLAGS/BOOLEAN_FLAGS entry NOT listed below was
|
||||
* deliberately excluded - see the per-field notes.
|
||||
*/
|
||||
const ORCHESTRATE_STRING_FLAGS = [
|
||||
// build-automation-workflow.ts's runsteps.sh export block: BUILD_NAME,
|
||||
// BUILD_METHOD, BUILD_PROFILE, CHOWN_FILES_TO, ANDROID_VERSION_CODE.
|
||||
['buildName', 'buildName'],
|
||||
['buildsPath', 'buildsPath'],
|
||||
['buildMethod', 'buildMethod'],
|
||||
['buildProfile', 'buildProfile'],
|
||||
['androidVersionCode', 'androidVersionCode'],
|
||||
['chownFilesTo', 'chownFilesTo'],
|
||||
// Git-auth fields consumed by orchestrator.ts / orchestrator-folders.ts
|
||||
// for the repo clone step, independent of provider/Docker.
|
||||
['sshAgent', 'sshAgent'],
|
||||
['sshPublicKeysDirectoryPath', 'sshPublicKeysDirectoryPath'],
|
||||
['gitPrivateToken', 'gitPrivateToken'],
|
||||
// --- Excluded, with reasons ---
|
||||
// customImage: build-parameters-adapter.ts assigns bp.customImage, but no
|
||||
// local/local-system codepath (provider or workflow) ever reads it back -
|
||||
// it is a Docker image selector with nothing to select on bare host.
|
||||
// customParameters: NOT assigned by build-parameters-adapter.ts at all
|
||||
// (unlike `build`'s CUSTOM_PARAMETERS env var). It only appears in the
|
||||
// unrelated hot-runner-service.ts path. Currently a no-op for
|
||||
// local-system, so intentionally not carried forward.
|
||||
// versioning / version: the adapter has no `versioningStrategy` concept -
|
||||
// it only accepts an already-resolved `buildVersion` string
|
||||
// (`bp.buildVersion = options.buildVersion || '0.0.1'`), which is a
|
||||
// different contract than this action's "Semantic/Tag/Custom strategy
|
||||
// name" `versioning` input. No existing action input maps cleanly onto
|
||||
// `--buildVersion`, so both are left out pending a real answer upstream.
|
||||
// androidExportType/androidKeystoreName/androidKeystoreBase64/
|
||||
// androidKeystorePass/androidKeyaliasName/androidKeyaliasPass/
|
||||
// androidTargetSdkVersion/androidSymbolType: none of these are assigned
|
||||
// by build-parameters-adapter.ts - only androidVersionCode is. Android
|
||||
// signing/export beyond the version code is currently unsupported by
|
||||
// `orchestrate`.
|
||||
// dockerCpuLimit/dockerMemoryLimit/dockerIsolationMode/
|
||||
// containerRegistryRepository/containerRegistryImageVersion/
|
||||
// dockerWorkspacePath: Docker container concepts with no bare-host
|
||||
// equivalent (containerRegistry* aren't even assigned by the adapter).
|
||||
// unityHubVersionOnMac: not assigned by the adapter at all.
|
||||
// unityLicensingServer: per the adapter's own comment, this "flows
|
||||
// opaquely through BuildParameters' index signature ... orchestrator
|
||||
// does not read them" - i.e. it is a no-op for `orchestrate` today;
|
||||
// licensing-server activation is `game-ci activate`'s concern, out of
|
||||
// scope here (matches this file's existing unityVersion/activation
|
||||
// scope boundary).
|
||||
];
|
||||
const ORCHESTRATE_BOOLEAN_FLAGS = [
|
||||
// build-automation-workflow.ts's runsteps.sh export block: MANUAL_EXIT.
|
||||
['manualExit', 'manualExit'],
|
||||
// pre-build-cleanup-service.ts reads this for the dirty-branch check,
|
||||
// independent of provider.
|
||||
['allowDirtyBuild', 'allowDirtyBuild'],
|
||||
// Explicitly documented upstream (orchestrator-options-plugin.ts,
|
||||
// build-parameters-adapter.ts) as "only meaningful for
|
||||
// providerStrategy=local(-system)", and exported as SKIP_ACTIVATION in
|
||||
// runsteps.sh.
|
||||
['skipActivation', 'skipActivation'],
|
||||
// --- Excluded, with reasons ---
|
||||
// enableGpu: not assigned anywhere in build-parameters-adapter.ts or the
|
||||
// orchestrator model - a real, currently-unfilled gap versus `build`'s
|
||||
// GPU passthrough, not something to silently pretend to support.
|
||||
// useHostNetwork/runAsHostUser: Docker networking/uid-mapping concepts;
|
||||
// not assigned by the adapter, and runAsHostUser is meaningless by
|
||||
// construction on a bare host process that already runs as that host
|
||||
// user.
|
||||
// cacheUnityInstallationOnMac: build-parameters-adapter.ts DOES assign
|
||||
// bp.cacheUnityInstallationOnMac, but nothing downstream (no provider,
|
||||
// no workflow) ever reads it back - it's a currently-dead field for
|
||||
// `orchestrate`, so it is not carried forward despite being Mac-native
|
||||
// (i.e. not actually Docker-only) in principle.
|
||||
// linux64RemoveExecutableExtension: not assigned by the adapter at all.
|
||||
];
|
||||
/**
|
||||
* New orchestrator-only inputs surfaced for providerStrategy=local-system.
|
||||
* All four are confirmed both registered as `orchestrate` CLI options
|
||||
* (orchestrator-options-plugin.ts) and consumed by
|
||||
* build-parameters-adapter.ts. `middlewarePipeline` is available in the same
|
||||
* places but deliberately deferred - its expected value shape is not yet
|
||||
* documented/stable enough to lock into this action's public input surface.
|
||||
*/
|
||||
const ORCHESTRATE_ONLY_STRING_FLAGS = [
|
||||
['engineLaunchWrapper', 'engineLaunchWrapper'],
|
||||
['localCacheMode', 'localCacheMode'],
|
||||
];
|
||||
const ORCHESTRATE_ONLY_BOOLEAN_FLAGS = [
|
||||
['enableBuildRetry', 'enableBuildRetry'],
|
||||
['localCacheEnabled', 'localCacheEnabled'],
|
||||
['localCacheLibrary', 'localCacheLibrary'],
|
||||
['localCacheLfs', 'localCacheLfs'],
|
||||
];
|
||||
function isTruthy(value) {
|
||||
return value.trim().toLowerCase() === 'true';
|
||||
}
|
||||
function buildCliArgs({ getInput }) {
|
||||
const args = ['build'];
|
||||
const projectPath = getInput('projectPath');
|
||||
if (projectPath)
|
||||
args.push(projectPath);
|
||||
const targetPlatform = getInput('targetPlatform');
|
||||
if (!targetPlatform) {
|
||||
throw new Error('targetPlatform is required.');
|
||||
}
|
||||
args.push(`--targetPlatform=${targetPlatform}`);
|
||||
const providerStrategy = getInput('providerStrategy') || 'local';
|
||||
if (providerStrategy !== 'local') {
|
||||
throw new Error(`Provider strategy "${providerStrategy}" is not supported by this thin wrapper. ` +
|
||||
"Use providerStrategy=local, or invoke game-ci/cli's `orchestrate` command directly " +
|
||||
'for remote builds.');
|
||||
}
|
||||
for (const [input, flag] of STRING_FLAGS) {
|
||||
function pushStringFlags(args, getInput, flags) {
|
||||
for (const [input, flag] of flags) {
|
||||
const value = getInput(input);
|
||||
// "--flag value" as two argv tokens is ambiguous when value itself
|
||||
// starts with "-" (e.g. customParameters="-profile Foo -someBoolean"):
|
||||
@@ -98,14 +190,55 @@ function buildCliArgs({ getInput }) {
|
||||
if (value)
|
||||
args.push(`--${flag}=${value}`);
|
||||
}
|
||||
for (const [input, flag] of BOOLEAN_FLAGS) {
|
||||
}
|
||||
function pushBooleanFlags(args, getInput, flags) {
|
||||
for (const [input, flag] of flags) {
|
||||
const value = getInput(input);
|
||||
if (value && isTruthy(value))
|
||||
args.push(`--${flag}`);
|
||||
}
|
||||
}
|
||||
function buildCliArgs({ getInput }) {
|
||||
const providerStrategy = getInput('providerStrategy') || 'local';
|
||||
if (providerStrategy === 'local-system') {
|
||||
return buildOrchestrateArgs(getInput);
|
||||
}
|
||||
if (providerStrategy !== 'local') {
|
||||
throw new Error(`Provider strategy "${providerStrategy}" is not supported by this thin wrapper. ` +
|
||||
"Use providerStrategy=local, or invoke game-ci/cli's `orchestrate` command directly " +
|
||||
'for remote builds.');
|
||||
}
|
||||
const args = ['build'];
|
||||
const projectPath = getInput('projectPath');
|
||||
if (projectPath)
|
||||
args.push(projectPath);
|
||||
const targetPlatform = getInput('targetPlatform');
|
||||
if (!targetPlatform) {
|
||||
throw new Error('targetPlatform is required.');
|
||||
}
|
||||
args.push(`--targetPlatform=${targetPlatform}`);
|
||||
pushStringFlags(args, getInput, STRING_FLAGS);
|
||||
pushBooleanFlags(args, getInput, BOOLEAN_FLAGS);
|
||||
return args;
|
||||
}
|
||||
exports.buildCliArgs = buildCliArgs;
|
||||
function buildOrchestrateArgs(getInput) {
|
||||
const args = ['orchestrate'];
|
||||
const projectPath = getInput('projectPath');
|
||||
if (projectPath)
|
||||
args.push(projectPath);
|
||||
const targetPlatform = getInput('targetPlatform');
|
||||
if (!targetPlatform) {
|
||||
throw new Error('targetPlatform is required.');
|
||||
}
|
||||
args.push(`--targetPlatform=${targetPlatform}`);
|
||||
args.push('--providerStrategy=local-system');
|
||||
pushStringFlags(args, getInput, ORCHESTRATE_STRING_FLAGS);
|
||||
pushStringFlags(args, getInput, ORCHESTRATE_ONLY_STRING_FLAGS);
|
||||
pushBooleanFlags(args, getInput, ORCHESTRATE_BOOLEAN_FLAGS);
|
||||
pushBooleanFlags(args, getInput, ORCHESTRATE_ONLY_BOOLEAN_FLAGS);
|
||||
return args;
|
||||
}
|
||||
|
||||
|
||||
/***/ }),
|
||||
@@ -201,7 +334,9 @@ async function downloadCli(version) {
|
||||
: `https://github.com/${CLI_REPO}/releases/latest/download/${asset}`;
|
||||
core.info(`Downloading game-ci CLI (${version}) from ${url}`);
|
||||
const archivePath = await tc.downloadTool(url);
|
||||
const extractedDir = process.platform === 'win32' ? await tc.extractZip(archivePath) : await tc.extractTar(archivePath);
|
||||
const extractedDir = process.platform === 'win32'
|
||||
? await tc.extractZip(archivePath)
|
||||
: await tc.extractTar(archivePath);
|
||||
const binaryPath = path.join(extractedDir, binaryName);
|
||||
if (process.platform !== 'win32') {
|
||||
await fs.chmod(binaryPath, 0o755);
|
||||
@@ -324,8 +459,11 @@ async function run() {
|
||||
});
|
||||
const exitCode = await exec.exec(cliPath, args, { ignoreReturnCode: true });
|
||||
// Matches the original action's engineExitCode output: 0 on success,
|
||||
// otherwise the exit code of whichever step (activation or build)
|
||||
// failed - which is exactly what the CLI subprocess itself exits with.
|
||||
// otherwise the exit code of whichever step (activation or build) - or,
|
||||
// for providerStrategy=local-system, whichever stage of the
|
||||
// orchestrator's setup/build/cleanup workflow - failed. Either way it's
|
||||
// exactly what the CLI subprocess itself exits with, so no special
|
||||
// handling is needed here for the orchestrate path.
|
||||
core.setOutput('engineExitCode', exitCode);
|
||||
if (exitCode !== 0) {
|
||||
core.setFailed(`Build failed with exit code ${exitCode}`);
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user