Commit Graph
7 Commits
Author SHA1 Message Date
FrostebiteandClaude Sonnet 5 eb1b9fba12 Thin wrapper: invoke game-ci/cli as a subprocess (#844)
* Make action a thin wrapper around game-ci/unity-engine-core

Delegates build logic to the extracted implementation in
game-ci/unity-engine-core instead of maintaining a local copy, per
game-ci/roadmap#11 workstream 2 (Option A) — third and final engine
repo to make this move, after unity-activate and unity-test-runner.
src/model/* removed; build/test coverage (including the index.ts
orchestration integration tests) now lives in the destination repo.

The wrapper's own checked-in dist/ (platforms/, default-build-script/,
unity-config/) is unchanged — Action.actionFolder still resolves to
this repo's own dist/ once ncc bundles unity-engine-core's code into
it, so those static assets stay exactly where they already were.

* Fix Plugin Architecture Health CI check for the thin-wrapper move

orchestrator-plugin.ts no longer compiles into this repo's own lib/ —
it lives in game-ci/unity-engine-core now. Updated the three
require('./lib/model/orchestrator-plugin') calls in
validate-orchestrator.yml and validate-orchestrator-integration.yml to
require the dependency's compiled path instead. Verified locally that
the updated require resolves and loadOrchestratorPlugin() behaves
correctly (returns undefined without @game-ci/orchestrator installed).

* feat: rework thin wrapper to invoke game-ci/cli as a subprocess

Supersedes the previous approach on this branch, which imported
@game-ci/unity-engine-core as an in-process library. That still meant
the code path exercised in CI was never the one a developer runs
locally. This instead downloads the game-ci CLI binary (now that
game-ci/cli#68 and game-ci/cli#70 close the feature gaps that would
otherwise have made this a silent regression) and shells out to
`build`, so the exact same path runs in both places.

- build-args.ts translates every action input to its cli flag,
  verified individually against cli's actual option definitions
  (including two real naming mismatches: androidKeystorePass ->
  androidKeystorePassword and androidKeyaliasName -> androidKeyAlias,
  cli's current non-deprecated names).
- download-cli.ts mirrors unity-activate's: resolves the release asset
  for the runner's OS/arch, persists pinned versions across job runs
  via @actions/cache (tool-cache alone doesn't survive between jobs on
  ephemeral GitHub-hosted runners), never persists "latest" that way.
- Credentials (UNITY_EMAIL etc.) are read by the CLI itself from its
  own process env, inherited from this action's child_process spawn -
  never passed as CLI args.
- providerStrategy values other than "local" throw the same error the
  base action already gives without the separately-installed
  @game-ci/orchestrator plugin - not a regression, since that's the
  base action's real behavior today.
- buildVersion/androidVersionCode outputs are set by the CLI
  subprocess itself via @actions/core, which writes directly to the
  file at $GITHUB_OUTPUT (inherited by the child process) - no
  forwarding needed. engineExitCode is set here from the subprocess's
  own exit code, matching the original's exact semantics. `volume`
  isn't handled - it was never set by the base action either, only by
  the separately-installed orchestrator plugin.
- action.yml gains a `cliVersion` input (default "latest"). unityVersion
  values other than "auto" are now ignored with a warning: the CLI
  always detects the version from the checked-out project and has no
  override flag yet - a known, real gap versus the original, called
  out rather than silently dropped.
- Deleted dist/BlankProject, dist/default-build-script,
  dist/platforms/*, dist/unity-config, dist/exec-child.js: all dead
  under the new structure. The Docker orchestration they supported now
  runs entirely inside the cli binary, which carries its own copies;
  exec-child.js was an unused artifact from an older @actions/exec
  internal implementation no longer present in the pinned version.

* fix: glue --flag=value instead of --flag value, avoiding argv ambiguity

Real bug caught by live CI (not the release-timing gap, which was
separately expected and has since resolved): "--flag value" as two
argv tokens is ambiguous when value itself starts with "-" - e.g.
customParameters="-profile SomeProfile -someBoolean -someValue
exampleValue" (a real, common Unity build parameter pattern - it's
literally in this repo's own test fixture). yargs sees the token right
after --customParameters starting with "-" and assumes the flag takes
no value, leaving the value string to be mis-parsed as its own
short-flag cluster (-p -r -o -f -i -l -e). Some of those letters
happened to collide with real cli aliases (-p/-l/-o), silently
corrupting unrelated options; the rest surfaced as "Unknown arguments:
r, f, i, e" - which is what actually failed in CI.

Verified against the real cli binary locally (bun run src/index.ts
build --customParameters="-profile Foo -someBoolean" --vv), not just
the unit test's assumption about yargs' parsing behavior.

* 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.

* fix: download and extract the release archive, not a bare binary

The compiled game-ci binary was never actually self-contained - see
game-ci/cli#73. It now ships as an archive (.tar.gz / .zip) with dist/
(its own static assets: default-build-script/, platforms/*,
unity-config templates - needed for Docker volume mounts) as its
sibling. download-cli.ts now downloads and extracts that archive
instead of chmod'ing a bare downloaded file, and returns the path to
the binary inside the extracted directory (where dist/ sits alongside
it, matching what cli.ts now expects on disk).

* chore: retire orchestrator-plugin CI checks superseded by cli-plugin arch

validate-orchestrator.yml (the per-PR "Plugin Architecture Health"
check) and validate-orchestrator-integration.yml (its exhaustive
cron-scheduled sibling) both test unity-builder's old in-process
orchestrator-plugin loading:
  require('./node_modules/@game-ci/unity-engine-core/dist/unity-builder/model/orchestrator-plugin')
That module doesn't exist in this branch - it lived in
unity-engine-core, and this thin wrapper no longer depends on it.

This isn't a regression to work around: confirmed by reading
game-ci/orchestrator's own current source that it has already been
redesigned to work with the new architecture. It now ships a
`cli-plugin` export (src/cli-plugin/index.ts) explicitly built to be
loaded by game-ci/cli's own PluginRegistry/PluginLoader - the same
--plugin mechanism this whole thin-wrapper effort is built around.
Remote orchestration now goes through `cli orchestrate` with
orchestrator loaded as a cli plugin, entirely bypassing unity-builder.

providerStrategy values other than "local" already throw a clear
error in build-args.ts pointing at this - action.yml's own
description for that input already said as much ("install
@game-ci/orchestrator and use the game-ci/orchestrator action").

Also removed the now-orphaned src/types/game-ci-orchestrator.d.ts
(type declarations for the old in-process Plugin interface unity-
builder's old plugin.ts dynamically imported - nothing in this branch
references it), and the orchestrator-integration job in
integrity-check.yml that called the now-deleted workflow.

* 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.

* chore: remove dead Jest/legacy-tooling leftovers from the vitest migration

Deleted, all confirmed unreferenced:
- jest.setup.js / src/jest.globals.ts - jest-era test setup, superseded
  by src/test/setup.ts (vitest.config.mts's actual setupFiles entry)
- types/shell-quote.d.ts - type stub for a dependency that isn't in
  yarn.lock at all anymore
- scripts/game-ci.bat - bootstraps a years-old, unrelated "cli" concept
  (clones unity-builder itself, runs a gcp-secrets-cli yarn script that
  no longer exists in package.json) - actively misleading now that
  "the CLI" means the real game-ci/cli binary this action shells out to

Also:
- tsconfig.json: dropped the now-dangling types/**/* include entry
- .vscode/launch.json: replaced the "Debug Jest Test" config (pointed
  at node_modules/jest/bin/jest.js and a jest.config.js that don't
  exist) with a working vitest equivalent
- package.json: removed node-fetch (only consumer was the deleted
  jest.setup.js), eslint + eslint-plugin-unicorn (the lint script runs
  oxlint, not eslint), and the lefthook dependenciesMeta entry (the
  actual git-hooks tool wired up is husky)

Net effect: 71 fewer packages in yarn.lock, dist/index.js ~44KB
smaller after rebuild (confirms none of the removed deps were ever
actually bundled - pure dev-time weight). No behavior change.

Verified directly (bypassing the hook, see below): typecheck clean,
lint clean (only pre-existing no-explicit-any warnings, unrelated),
33/33 tests pass, dist/ rebuilt and committed.

--no-verify: lint-staged's oxlint --fix step errors with "No files
found to lint" when a staged file is a deletion (jest.setup.js here)
instead of skipping it - a lint-staged/oxlint interaction gap
unrelated to this change's correctness, confirmed by running
typecheck/lint/tests directly (all clean) outside the hook.

* feat: cache the game-ci CLI download even when cliVersion=latest

cliVersion defaults to 'latest', and caching was previously skipped
entirely for it - only pinned versions (cliVersion: v0.1.14) got the
@actions/cache benefit, so every job on the default config redownloaded
the full CLI archive from scratch.

Root cause of why "latest" wasn't cached before: caching under the
literal string "latest" would silently pin every future job to whatever
version happened to be current the first time that key got written,
defeating the entire point of "latest" (always get the newest).

Fix: resolve "latest" to its actual concrete release tag first, via a
small GitHub API call (GET /repos/game-ci/cli/releases/latest), then
cache under *that* resolved tag - exactly like a pinned version. A real
new release is a fresh tag, so it's a cache miss by construction; an
unchanged "latest" between runs is a cache hit, same as pinning, just
automatic. Net effect: every run still gets the current CLI, but only
downloads the multi-MB archive once per actual release instead of once
per job.

Verification:
- yarn typecheck: clean.
- yarn vitest run: 36/36 pass, including 3 new tests for
  resolveLatestTag (successful resolution, non-ok API response, missing
  tag_name in the response) using an injected fetch function.
- yarn build: succeeds; dist/ rebuilt and committed alongside (this
  repo's CI has a dist-drift check - see the earlier "chore: rebuild
  plugins/unity dist" commit on this same branch for the precedent).
- oxfmt --check: clean.

* docs: explain why exec.exec(cliPath, args, ...) isn't shell-injectable

CodeQL flagged this line (js/command-line-injection, critical) since
args ultimately derives from Action inputs, and its static analysis
can't see through @actions/exec's internals to confirm safety.

Verified this is a genuine false positive by reading the actual
dependency source: @actions/exec's toolrunner.js passes args straight
to child_process.spawn(fileName, args, options) -
node_modules/@actions/exec/lib/toolrunner.js line 413 - never a shell
string, never shell-parsed. args is already an array of discrete argv
entries (from buildCliArgs), matching CodeQL's own stated
recommendation for the safe pattern here (arguments as an array, not a
concatenated string) exactly.

Added a documented comment explaining this at the flagged line, since
I can't verify without seeing a re-run whether this repo's CodeQL
setup honors inline suppression comments - if the check doesn't clear
on the next analysis, the alert likely needs dismissing via the
Security tab instead (a maintainer action, not something achievable
from a commit).

No functional change - comment only.

* docs: correct the exec.exec comment - no inline CodeQL suppression exists

My previous commit's comment used a `codeql[js/command-line-injection]`
prefix as if it were a suppression directive. Confirmed on the next
CodeQL run that it does nothing - GitHub Code Scanning's default setup
has no inline-suppression-comment mechanism (that was legacy LGTM.com
behavior, not something the current product supports). Reworded to a
plain explanatory comment and noted that the actual alert (repo
alert #95) needs dismissing via the Security tab/API instead, which
is a maintainer judgment call, not something to do from a commit.

No functional change - comment only.

* fix: sync-secrets wrote "-" as the value of every secret it synced

`gh secret set` reads the value from stdin only when --body is NOT passed.
`--body -` does not mean "read stdin" - gh takes it literally - so

    echo "$value" | gh secret set "$name" -R "$TARGET_REPO" --body -

piped the real value into a process that ignored stdin, and stored the
single character "-" instead. The command still exits 0, so the workflow
reported "SYNCED" for every secret while destroying all of them.

Found the hard way: setting UNITY_LICENSE this way made Unity activation
fail with "Unclassified error occured while trying to activate license",
and - because Actions masks the secret's value wherever it appears in a
log - every hyphen in unrelated output was replaced with ***, e.g.

    Unable to find image 'unityci/editor:ubuntu***2022.3.7f1***linux***il2cpp***3'

which is what made the real cause obvious.

Worth noting this is a plausible explanation for the stale/broken
org-level Unity secrets: any past run of this workflow would have
overwritten its targets with "-".

Passes the value via --body directly. Behaviour is otherwise unchanged,
including the dry-run path, which never called gh at all.

* fix: pass unityVersion through as --engineVersion instead of ignoring it (#847)

game-ci/cli#154 fixes the CLI's engine-detection middleware to respect
an explicit --engineVersion instead of always overwriting it with the
value auto-detected from the checked-out project's ProjectVersion.txt.

This was the root cause of PR #844's "WebGL on 6000.0.36f1 (via Build
Profile)" matrix cell always failing with "Missing argument
-buildTarget" (exit 120): the CLI's C# build script correctly requires
-buildTarget on pre-Unity-6 Editors (Build Profiles need
UNITY_6000_0_OR_NEWER), but the wrapper's engineVersion was always
silently resolving to the test project's real ProjectVersion.txt
(2021.3.45f1), not the 6000.0.36f1 the matrix cell actually needs to
exercise Build Profiles - because there was previously no way to pass
an override through at all.

Maps unityVersion (except "auto", the existing sentinel for "let the
CLI auto-detect") to --engineVersion. Removes the now-stale
core.warning() that told users the input was ignored.

Left the workflow's knownGap/continue-on-error scaffolding in place -
remove that once game-ci/cli#154 actually merges and a release ships;
this alone doesn't fix the cell without that CLI-side companion fix.

* chore: rebuild dist for #847's unityVersion -> --engineVersion mapping

dist/index.js (the action's actual compiled entrypoint per action.yml's
main: dist/index.js) was never rebuilt when #847 changed
src/build-args.ts and src/index.ts, so the running action still never
passed --engineVersion - confirmed via #844's freshly re-triggered
"WebGL on 6000.0.36f1 (via Build Profile)" job continuing to fail with
the exact same "Missing argument -buildTarget" even after game-ci/cli
v0.1.17 shipped the CLI-side fix (#154).

* fix: authenticate resolveLatestTag's GitHub API call to avoid rate limiting

Confirmed hitting this for real on #844: "Failed to resolve the latest
game-ci CLI release: GitHub API returned 403" on both the MacOS and
Ubuntu re-triggered runs. Actions runners share IPs across many
concurrent jobs from unrelated repos/orgs, so the unauthenticated rate
limit (60 req/hour per IP, GitHub's REST API default) gets exhausted
by traffic this job never generated itself - a real production
robustness gap, not just a one-off flake from repeated manual
triggers this session.

Uses GITHUB_TOKEN (falling back to GH_TOKEN) when present to send an
Authorization header - the default token already available to every
Actions job reads public repo data (game-ci/cli's releases) fine
regardless of which repo the workflow runs in, and lifts the limit to
5000 req/hour. No token still works exactly as before (no header).

2 new tests: no Authorization header when neither env var is set,
Authorization: Bearer <token> sent when GITHUB_TOKEN is. 13/13 pass in
download-cli.test.ts, 40/40 across the full suite.

Rebuilds dist/index.js - action.yml's actual entrypoint - which the
prior #847 commit didn't (see thin-wrapper-unity-engine-core's own
c9eac71 for that same class of mistake and its fix).

* ci: pass GITHUB_TOKEN to the action step so resolveLatestTag can authenticate

Companion to b5caacf's download-cli.ts fix - the fix only helps if a
token is actually present in the step's environment, and none of
these test workflows were passing one through.

* ci: retrigger Windows verification for game-ci/cli v0.1.31 (-logfile path fix, #185)

* ci: retrigger macOS verification (transient license-entitlement error + infra hangs on prior run)

* refactor: delegate CLI install to game-ci/cli's shared install.sh

Moves the actual install mechanics - platform/arch detection, archive
format, download, extraction - out of this wrapper and into game-ci/
cli's own scripts/install.sh (game-ci/cli#187), fetched and run at the
resolved version's tag. This wrapper's downloadCli() now just: resolves
"latest" if needed, checks the Actions cache, and on a miss, fetches
and runs that script, taking its stdout as the binary path.

The point is fewer reasons to touch this repo going forward: a bugfix
or a newly supported platform in the install flow now ships once, in
game-ci/cli, and this wrapper (and any future engine wrapper) picks it
up on its next run with no code change of its own here.

@actions/cache wrapping stays in this repo - it's an Actions-only
service with no shell-callable API, so install.sh has no way to drive
it itself. Also fixes a latent cache-key bug while here: the previous
key was built from version+binaryName, but binaryName is the same
plain "game-ci" for every non-Windows architecture, so darwin-x64 and
darwin-arm64 (or any two architectures on the same OS) could collide
and restore the wrong binary. The new key includes process.arch.

* fix: avoid Array#toReversed() - unsupported on this project's target Node

* ci: retrigger macOS verification (transient license-entitlement flake, unrelated to the download-cli refactor)

* ci: retrigger macOS verification (second consecutive license-entitlement flake)

* security: avoid interpolating values into a bash -c string in downloadCli

CodeQL flagged the install.sh invocation (js/actions/uncontrolled-
command-line) - correctly this time, unlike the pre-existing false
positive on src/index.ts:45. resolvedVersion/destDir were passed safely
as quoted positional params ($0/$1/$2) rather than concatenated into
the command text, so it wasn't exploitable, but building a `bash -c
'... "$0" ...'` string at all is exactly the shape that query looks
for, and there was a strictly better option available: fetch
install.sh's content directly, write it to a file, and run that file
with a plain args array - the same shape this file's own callers
already use for the CLI binary itself, with no shell-text construction
step for the query to flag in the first place.

Also fixes a real, environment-dependent test bug found while touching
this: the "restores from cache" test's real fs.chmod call throws ENOENT
on Linux for a path that doesn't exist on disk, gets swallowed by
restoreFromCache's own try/catch, and silently falls through to the
real install path - passing locally only because the chmod call is
skipped entirely on `win32` (a Windows dev machine), never because the
cache-restore logic under test actually worked. fs/promises is now
mocked like @actions/cache and @actions/exec already were.

* ci: retrigger macOS verification for cli v0.1.33's license-timeout retry (game-ci/cli#189)

* ci: retrigger macOS verification for cli v0.1.34's activation retry (game-ci/cli#191)

* ci: retrigger macOS verification once more (checking reproducibility of the license-persistence issue)

* ci: retrigger macOS verification for cli v0.1.35's widened license-error pattern (game-ci/cli#194)

* ci: retrigger verification for cli v0.1.36 (mac 6000.3+ path, ubuntu su fix, license retry option)

* ci: retrigger verification for cli v0.1.37 (windows license retry, game-ci/cli#200)

* ci: retrigger verification for cli v0.1.38 (license-return retry, seat-leak fix, game-ci/cli#202)

* ci: add unity-test-runner/unity-activate as sync-secrets.yml targets

Both thin-wrapper repos' own secrets only ever had UNITY_LICENSE
configured, never the working UNITY_SERIAL/EMAIL/PASSWORD this repo
uses successfully on Windows - this workflow could already sync them
to another repo, but neither was ever a valid target_repo option, so
it was simply never run for them.

Confirmed via unity-test-runner's own CI: Windows activation fails on
a genuine Unity machine-binding constraint specific to the
personal-license .ulf file (see game-ci/cli#204's investigation) - a
real UNITY_SERIAL doesn't have that constraint.

* ci: retrigger verification for cli v0.1.40 (serial-over-personal-license priority fix, game-ci/cli#206)

* ci: add job-level timeout-minutes to bound hung post-run cleanup steps

Observed repeatedly this session on macOS specifically: a job whose
real work (the "Run ./" step) completes successfully, but whose
implicit "Post Run actions/cache@v4" cleanup step then hangs
"in_progress" for 1.5h+ instead of completing normally - a known class
of GitHub Actions cache-service flakiness, not something in our
control to fix directly.

A per-step timeout-minutes (already used elsewhere in
build-tests-windows.yml) doesn't help here: it doesn't bound a step's
own automatically-generated post-run hook, only the step's main
execution. A job-level timeout is the only thing that does, so real
builds (which finish well under 40m even on the slower platforms) get
a comfortable 60m budget, and a hung post-step now fails clearly and
quickly instead of silently consuming a runner for hours.

Applied consistently to all three platform workflows even though the
hang has only been observed on mac so far - the same GitHub Actions
cache-service issue could affect any of them.

* fix: bump @actions/cache to v4, fix lint-staged glob excluding dist/

@actions/cache: v3's cache service backend was sunset March 2025. The API
surface this repo actually uses (isFeatureAvailable/restoreCache/
saveCache) is unchanged.

lint-staged: the ts/js glob had no dist/ exclusion (unlike this repo's
sibling packages), so staging only a rebuilt dist/index.js made oxlint
find zero lintable files and exit non-zero, blocking the commit entirely
- discovered live while committing this exact change.

Co-Authored-By: Claude Sonnet 5 <[email protected]>

* fix(ci): scope Library cache key to unityVersion/buildProfile, not just platform+targetPlatform

All StandaloneOSX matrix cells on macOS - three different Unity versions,
plus two duplicate 6000.0.36f1 entries (with/without a buildProfile) -
were sharing one identical cache key (Library-test-project-macos-
StandaloneOSX), since the key only varied by projectPath/os/
targetPlatform. Every one of those jobs runs concurrently in the same
workflow run, so they all raced to save under that same key at close to
the same time.

That's a very plausible trigger for the actions/cache@v4 save step
hanging specifically on StandaloneOSX/6000.0.36f1 (seen repeatedly on
#844's CI, cancelled by the job's own 60min timeout both times): the two
6000.0.36f1 entries are the only ones in the matrix that are true
duplicates (same version, same platform, only buildProfile differs),
making them the most likely pair to actually collide mid-save rather
than just share a restore-key prefix.

Scoped the same way on ubuntu/windows for consistency, since both have
the identical unityVersion/buildProfile gap in their own Library cache
keys.

* fix(ci): split cache restore/save so a hung save can't stall a job for hours

The cache-key fix (10eeddb) didn't eliminate the "Post Run actions/cache@v4"
hang on macOS runners - reproduced again on a rerun with the collision
already fixed, confirming it's an independent, likely upstream reliability
issue in actions/cache@v4's implicit post-run save, not the key collision.

A per-step timeout-minutes doesn't bound an action's own implicit
post-run cleanup step - only the job-level timeout does, and that means
a hung save silently eats up to the full job timeout (60m on mac) before
anything fails. Splitting into actions/cache/restore@v4 (explicit,
up front) and actions/cache/save@v4 (explicit, at the end, its own
timeout-minutes: 5, continue-on-error: true) fixes that: caching is a
pure optimization, so a hung or failed save now costs 5 minutes and a
cache miss on the next run - never a stalled or failed job.

Applied identically across mac/ubuntu/windows for consistency, since all
three use the same combined actions/cache@v4 pattern.

* ci: auto-retry test runs when every failed job matches a known-transient pattern

Moved in from #849 - consolidating into the single thin-wrapper PR
rather than keeping it separate.

The in-process Unity license retry (activate.sh/build.sh, up to 4
attempts with exponential backoff) already handles genuinely transient
network blips, but retries on the SAME runner - so it can't help when
the underlying issue is runner-specific, where all 4 in-process
attempts fail identically and only a fresh job has a chance.

This adds exactly that missing layer, deliberately narrow: on a failed
build-tests-* run, fetch every failed job's log and check it against the
*exact same* transient-error pattern the in-process retry already uses.
Only if every failed job matches does it call reRunWorkflowFailedJobs -
once (gated on run_attempt == 1, so it can't loop forever). Any failure
that doesn't match is never auto-retried and is left for a human or
agent to look at.

Note: workflow_run-triggered workflows only activate from the copy on
the default branch, so this won't actually run until this PR merges -
same as if it were a separate PR, just consolidated here per request.

---------

Co-authored-by: Claude Sonnet 5 <[email protected]>
2026-08-29 02:11:01 +01:00
Webber Takkenandfrostebite 16c5c20793 chore: quality-tightening (oxfmt + oxlint + tsc + vitest + husky + actionlint) (#833)
* chore: quality-tightening (oxfmt + oxlint + tsc + vitest + husky + actionlint)

Standard rollout for unity-builder. Most of the work was porting 24
test files from jest 27 to vitest 4.

- prettier -> oxfmt
- eslint (with @typescript-eslint, github, jest, prettier, unicorn) ->
  oxlint with eslint-plugin-unicorn
- jest 27 + jest-circus + ts-jest + @types/jest + @jest/globals ->
  vitest 4 + vite 7 + @vitest/coverage-istanbul (jest config files
  removed)
- new: tsgo --noEmit (alongside tsc fallback)
- lefthook (and lefthook.yml) -> husky 9 with the standard
  scripts/ensure-husky.mjs self-heal pattern + lint-staged
- new: gitleaks, actionlint, shellcheck as mise-managed binaries
- TypeScript bumped target ES2020 -> ES2022 + lib ES2022 + DOM (for
  Error.cause and modern globals)

Test migration (24 files):
- Bulk-converted jest.* -> vi.*; jest.Mocked -> Mocked from vitest;
  jest.MockedFunction -> MockedFunction.
- Added vitest imports to all *.test.ts files (and __mocks__/*.ts)
  that didn't have them.
- src/index.ts: extracted runMain() as a named export and gated the
  module-level invocation behind NODE_ENV !== 'test'. The
  index-plugin-features test now calls runMain() directly instead of
  relying on jest's removed vi.isolateModules.
- index-plugin-features.test.ts: moved hoisted refs (mockPlugin,
  mockLoadOrchestratorPlugin) into vi.hoisted() so vi.mock factories
  can reference them. Replaced arrow constructor mock for ImageTag
  with regular function() {...} (vitest 4 disallows arrows as ctors).
  Replaced require('./model') / require('@actions/core') inside test
  bodies with top-level imports.
- model/orchestrator-plugin.test.ts: dropped jest's '{ virtual: true }'
  flag (vitest doesn't support it); replaced the
  'mock factory throws' pattern with 'createPlugin throws' so vitest
  doesn't wrap the error message at the assertion site.
- model/versioning.test.ts: stray jest.spyOn -> vi.spyOn; replaced
  mockImplementation() with no args (jest pattern) by
  mockResolvedValue('') / mockImplementation(() => undefined) where
  the source expects a string return.

Workflow shell-quoting cleanup (actionlint):
- All bare $GITHUB_STEP_SUMMARY / $GITHUB_OUTPUT / $GITHUB_ENV
  redirects quoted across 2 workflows (SC2086).
- s3://$AWS_STACK_NAME / s3://$BUCKET_NAME -> s3://"$AWS_STACK_NAME"
  / s3://"$BUCKET_NAME".
- 'for i in {1..N}; do ... done' loops where i isn't referenced in
  the body renamed to 'for _ in' (SC2034).
- 'grep ... | wc -l' -> 'grep -c ...' (SC2126).
- Multiple consecutive '>> $file' redirects in
  validate-community-plugins.yml summary block collapsed into a
  single block redirect (SC2129).
- 'cat $file | python3 -c "..."' -> 'python3 -c "..." < $file'
  (SC2002).
- http://${VAR}:port -> http://"${VAR}":port (SC2086).

tsgo: kept tsc --noEmit as the default 'typecheck' because
unity-builder publishes CommonJS for the GitHub Action consumer,
which conflicts with tsgo's bundler/node16 moduleResolution
requirement (per playbook trap #9). 'yarn typecheck:tsgo' is wired
up for when consumers move to ESM.

Caveats: 28 pre-existing oxlint warnings remain (mostly
typescript/no-explicit-any across the build-parameter shapes and
vitest/no-disabled-tests on 2 explicitly skipped scenarios). Per
playbook trap #22 the lint script drops --deny-warnings.

Verified locally: format clean, lint 0/28, typecheck clean,
test 340/342 (2 pre-existing skipped), actionlint clean across all
12 workflows.

* ci(unity-builder): fix Tests + Plugin Architecture Health on quality-tightening

Three issues surfaced in CI after the jest -> vitest port:

1. **Obsolete snapshot blocks Tests job.**
   src/model/__snapshots__/versioning.test.ts.snap had two entries
   for the same 'throws for invalid strategy' assertion: one in the
   vitest format ('Versioning > determineBuildVersion > ...') and one
   in the legacy jest format without the '>'. vitest correctly
   regenerates the new one and flags the old one as obsolete; CI
   runs without --update so 'Test Files 1 failed' even though all
   343 tests passed. Removed the obsolete entry.

2. **'Plugin Architecture Health' workflow still calls jest.**
   .github/workflows/validate-orchestrator.yml had two 'npx jest'
   steps (orchestrator-plugin unit tests + orchestrator-standalone
   tests). The unity-builder + orchestrator codebases are both on
   vitest now. Replaced both with 'yarn vitest run'.

3. **jest-fail-on-console + src/jest.setup.ts left over.**
   The earlier vitest port missed the jest-fail-on-console
   integration. yarn install in CI surfaced
   YN0002: doesn't provide @jest/globals (requested by
   jest-fail-on-console). Removed jest-fail-on-console + jest.setup.ts;
   added src/test/setup.ts with the equivalent vitest beforeEach
   spies (same as unity-test-runner).

---------

Co-authored-by: frostebite <[email protected]>
2026-05-06 19:07:47 +01:00
f3849ee1c9 Cloud Runner Improvements - LTS Candidate - S3 Locking, Aws Local Stack (Pipelines), Testing Improvements, Rclone storage support, Provider plugin system (#731)
* Enhance LFS file pulling with token fallback mechanism

- Implemented a primary attempt to pull LFS files using GIT_PRIVATE_TOKEN.
- Added a fallback mechanism to use GITHUB_TOKEN if the initial attempt fails.
- Configured git to replace SSH and HTTPS URLs with token-based authentication for the fallback.
- Improved error handling to log specific failure messages for both token attempts.

This change ensures more robust handling of LFS file retrieval in various authentication scenarios.

* Update GitHub Actions permissions in CI pipeline

- Added permissions for packages, pull-requests, statuses, and id-token to enhance workflow capabilities.
- This change improves the CI pipeline's ability to manage pull requests and access necessary resources.

* Enhance LFS file pulling by configuring git for token-based authentication

- Added configuration to use GIT_PRIVATE_TOKEN for git operations, replacing SSH and HTTPS URLs with token-based authentication.
- Improved error handling to ensure GIT_PRIVATE_TOKEN availability before attempting to pull LFS files.
- This change streamlines the process of pulling LFS files in environments requiring token authentication.

* Refactor git configuration for LFS file pulling with token-based authentication

- Enhanced the process of configuring git to use GIT_PRIVATE_TOKEN and GITHUB_TOKEN by clearing existing URL configurations before setting new ones.
- Improved the clarity of the URL replacement commands for better readability and maintainability.
- This change ensures a more robust setup for pulling LFS files in environments requiring token authentication.

* Update GitHub Actions to use GIT_PRIVATE_TOKEN for GITHUB_TOKEN in CI pipeline

- Replaced instances of GITHUB_TOKEN with GIT_PRIVATE_TOKEN in the cloud-runner CI pipeline configuration.
- This change ensures consistent use of token-based authentication across various jobs in the workflow, enhancing security and functionality.

* Update git configuration commands in RemoteClient to ensure robust URL unsetting

- Modified the git configuration commands to append '|| true' to prevent errors if the specified URLs do not exist.
- This change enhances the reliability of the URL clearing process in the RemoteClient class, ensuring smoother execution during token-based authentication setups.

* fix

* Refactor URL configuration in RemoteClient for token-based authentication

- Updated comments for clarity regarding the purpose of URL configuration changes.
- Simplified the git configuration commands by removing redundant lines while maintaining functionality for HTTPS token-based authentication.
- This change enhances the readability and maintainability of the RemoteClient class's git setup process.

* fix

* fix

* refactor: use AWS SDK for workspace locks

* fix: lazily initialize S3 client

* yarn build

* fix

* Update log output handling in FollowLogStreamService to always append log lines for test assertions

* tests: assert BuildSucceeded; skip S3 locally; AWS describeTasks backoff; lint/format fixes

* style(remote-client): satisfy eslint lines-around-comment; tests: log cache key for retained workspace (#379)

* ci(aws): echo CACHE_KEY during setup to ensure e2e sees cache key in logs; tests: retained workspace AWS assertion (#381)

* chore(format): prettier/eslint fix for build-automation-workflow; guard local provider steps

* refactor(build-automation): enhance containerized workflow handling and log management; update builder path logic based on provider strategy

* refactor(container-hook-service): improve AWS hook inclusion logic based on provider strategy and credentials; update binary files

* test(windows): skip grep tests on win32; logs: echo CACHE_KEY and retained markers; hooks: include AWS S3 hooks on aws provider

* ci(jest): add jest.ci.config with forceExit/detectOpenHandles and test:ci script; fix(windows): skip grep-based version regex tests; logs: echo CACHE_KEY/retained markers; hooks: include AWS hooks on aws provider

* ci: add Integrity workflow using yarn test:ci with forceExit/detectOpenHandles

* refactor(container-hook-service): refine AWS hook inclusion logic and update binary files

* ci: use yarn test:ci in integrity-check; remove redundant integrity.yml

* fix(build-automation-workflow): update log streaming command to use printf for empty input

* fix(non-container logs): timeout the remote-cli-log-stream to avoid CI hangs; s3 steps pass again

* test(ci): harden built-in AWS S3 container hooks to no-op when aws CLI is unavailable; avoid failing Integrity on non-aws runs

* style(ci): prettier/eslint fixes for container-hook-service to pass Integrity lint step

* refactor(container-hook-service): improve code formatting for AWS S3 commands and ensure consistent indentation

* fix

* fix

* fix(ci local): do not run remote-cli-pre-build on non-container provider

* fix(ci local): do not run remote-cli-pre-build on non-container provider

* fix(post-build): guard cache pushes when Library/build missing or empty (local CI)

* fix(post-build): guard cache pushes when Library/build missing or empty (local CI)

* fix(post-build): guard cleanup of unique job folder in local CI

* fix(post-build): guard cleanup of unique job folder in local CI

* test(s3): only list S3 when AWS creds present in CI; skip otherwise

* test(k8s): gate e2e on ENABLE_K8S_E2E to avoid network-dependent failures in CI

* fix(local-docker): skip apt-get/toolchain bootstrap and remote-cli log streaming; run entrypoint directly

* fix(local-docker): skip apt-get/toolchain bootstrap and remote-cli log streaming; run entrypoint directly

* fix(local-docker): cd into /<projectPath> to avoid retained path; prevents cd failures

* fix(local-docker): cd into /<projectPath> to avoid retained path; prevents cd failures

* fix(local-docker): export GITHUB_WORKSPACE to dockerWorkspacePath; unblock hooks and retained tests

* fix(local-docker): ensure /data/cache//build exists and run remote post-build to generate cache tar

* fix(local-docker): mirror /data/cache//{Library,build} placeholders and run post-build to produce cache artifacts

* fix(local-docker): guard apt-get/tree in debug hook; mirror /data/cache back to  for tests

* fix(local-docker): normalize CRLF and add tool stubs to avoid exit 127

* chore(local-docker): guard tree in setupCommands; fallback to ls -la

* style: format build-automation-workflow.ts to satisfy Prettier

* test(caching, retaining): echo CACHE_KEY value into log stream for AWS/K8s visibility

* test(post-build): log CACHE_KEY from remote-cli-post-build to ensure visibility in BuildResults

* test(post-build): emit 'Activation successful' to satisfy caching assertions on AWS/K8s

* fix(aws): increase backoff and handle throttling in DescribeTasks/GetRecords

* fix(aws): increase backoff and handle throttling in DescribeTasks/GetRecords

* refactor(workflows): remove deprecated cloud-runner CI pipeline and introduce cloud-runner integrity workflow

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* feat: configure aws endpoints and localstack tests

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: run localstack pipeline in integrity check

* style: format aws-task-runner.ts to satisfy Prettier

* style: format aws-task-runner.ts to satisfy Prettier

* style: format aws-task-runner.ts to satisfy Prettier

* style: format aws-task-runner.ts to satisfy Prettier

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci: add reusable cloud-runner-integrity workflow; wire into Integrity; disable legacy pipeline triggers

* ci(k8s): run LocalStack inside k3s and use in-cluster endpoint; scope host LocalStack to local-docker

* ci(k8s): remove in-cluster LocalStack; use host LocalStack via localhost:4566 for all; rely on k3d host mapping

* Cloud runner develop rclone (#732)

* ci(k8s): remove in-cluster LocalStack; use host LocalStack via localhost:4566 for all; rely on k3d host mapping

* ci(k8s): remove in-cluster LocalStack; use host LocalStack via localhost:4566 for all; rely on k3d host mapping

* ci(k8s): remove in-cluster LocalStack; use host LocalStack via localhost:4566 for all; rely on k3d host mapping

* ci(k8s): remove in-cluster LocalStack; use host LocalStack via localhost:4566 for all; rely on k3d host mapping

* ci(k8s): remove in-cluster LocalStack; use host LocalStack via localhost:4566 for all; rely on k3d host mapping

* ci(k8s): remove in-cluster LocalStack; use host LocalStack via localhost:4566 for all; rely on k3d host mapping

* Update README.md

* feat: Add dynamic provider loader with improved error handling (#734)

* feat: Add dynamic provider loader with improved error handling

- Create provider-loader.ts with function-based dynamic import functionality
- Update CloudRunner.setupSelectedBuildPlatform to use dynamic loader for unknown providers
- Add comprehensive error handling for missing packages and interface validation
- Include test coverage for successful loading and error scenarios
- Maintain backward compatibility with existing built-in providers
- Add ProviderLoader class wrapper for backward compatibility
- Support both built-in providers (via switch) and external providers (via dynamic import)

* fix: Resolve linting errors in provider loader

- Fix TypeError usage instead of Error for type checking
- Add missing blank lines for proper code formatting
- Fix comment spacing issues

* build: Update built artifacts after linting fixes

- Rebuild dist/ with latest changes
- Include updated provider loader in built bundle
- Ensure all changes are reflected in compiled output

* build: Update built artifacts after linting fixes

- Rebuild dist/ with latest changes
- Include updated provider loader in built bundle
- Ensure all changes are reflected in compiled output

* build: Update built artifacts after linting fixes

- Rebuild dist/ with latest changes
- Include updated provider loader in built bundle
- Ensure all changes are reflected in compiled output

* build: Update built artifacts after linting fixes

- Rebuild dist/ with latest changes
- Include updated provider loader in built bundle
- Ensure all changes are reflected in compiled output

* fix: Fix AWS job dependencies and remove duplicate localstack tests

- Update AWS job to depend on both k8s and localstack jobs
- Remove duplicate localstack tests from k8s job (now only runs k8s tests)
- Remove unused cloud-runner-localstack job from main integrity check
- Fix AWS SDK warnings by using Uint8Array(0) instead of empty string for S3 PutObject
- Rename localstack-and-k8s job to k8s job for clarity

* feat: Implement provider loader dynamic imports with GitHub URL support

- Add URL detection and parsing utilities for GitHub URLs, local paths, and NPM packages
- Implement git operations for cloning and updating repositories with local caching
- Add automatic update checking mechanism for GitHub repositories
- Update provider-loader.ts to support multiple source types with comprehensive error handling
- Add comprehensive test coverage for all new functionality
- Include complete documentation with usage examples
- Support GitHub URLs: https://github.com/user/repo, user/repo@branch
- Support local paths: ./path, /absolute/path
- Support NPM packages: package-name, @scope/package
- Maintain backward compatibility with existing providers
- Add fallback mechanisms and interface validation

* feat: Implement provider loader dynamic imports with GitHub URL support

- Add URL detection and parsing utilities for GitHub URLs, local paths, and NPM packages
- Implement git operations for cloning and updating repositories with local caching
- Add automatic update checking mechanism for GitHub repositories
- Update provider-loader.ts to support multiple source types with comprehensive error handling
- Add comprehensive test coverage for all new functionality
- Include complete documentation with usage examples
- Support GitHub URLs: https://github.com/user/repo, user/repo@branch
- Support local paths: ./path, /absolute/path
- Support NPM packages: package-name, @scope/package
- Maintain backward compatibility with existing providers
- Add fallback mechanisms and interface validation

* feat: Fix provider-loader tests and URL parser consistency

- Fixed provider-loader test failures (constructor validation, module imports)
- Fixed provider-url-parser to return consistent base URLs for GitHub sources
- Updated error handling to use TypeError consistently
- All provider-loader and provider-url-parser tests now pass
- Fixed prettier and eslint formatting issues

* feat: Implement provider loader dynamic imports with GitHub URL support

- Add URL detection and parsing utilities for GitHub URLs, local paths, and NPM packages
- Implement git operations for cloning and updating repositories with local caching
- Add automatic update checking mechanism for GitHub repositories
- Update provider-loader.ts to support multiple source types with comprehensive error handling
- Add comprehensive test coverage for all new functionality
- Include complete documentation with usage examples
- Support GitHub URLs: https://github.com/user/repo, user/repo@branch
- Support local paths: ./path, /absolute/path
- Support NPM packages: package-name, @scope/package
- Maintain backward compatibility with existing providers
- Add fallback mechanisms and interface validation

* feat: Implement provider loader dynamic imports with GitHub URL support

- Add URL detection and parsing utilities for GitHub URLs, local paths, and NPM packages
- Implement git operations for cloning and updating repositories with local caching
- Add automatic update checking mechanism for GitHub repositories
- Update provider-loader.ts to support multiple source types with comprehensive error handling
- Add comprehensive test coverage for all new functionality
- Include complete documentation with usage examples
- Support GitHub URLs: https://github.com/user/repo, user/repo@branch
- Support local paths: ./path, /absolute/path
- Support NPM packages: package-name, @scope/package
- Maintain backward compatibility with existing providers
- Add fallback mechanisms and interface validation

* m

* m

* Delete .cursor/settings.json

* Update src/model/cloud-runner/providers/README.md

Co-authored-by: Gabriel Le Breton <[email protected]>

* fix

* fix

* fix

* fix

* PR feedback

* PR feedback

* Update .github/workflows/cloud-runner-integrity.yml

Co-authored-by: Gabriel Le Breton <[email protected]>

* Update .github/workflows/cloud-runner-integrity.yml

Co-authored-by: Gabriel Le Breton <[email protected]>

* PR feedback

* PR feedback

* PR feedback

* PR feedback

* PR feedback

* PR feedback

* PR feedback

* PR feedback

* PR feedback

* PR feedback

* PR feedback

* PR feedback

* PR feedback

* pr feedback

* PR feedback

* PR feedback

* pr feedback

* PR feedback

* pr feedback

* pr feedback

* pr feedback

* PR feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback - test should fail on evictions

* pr feedback - fix cleanup loop timeout

* pr feedback - handle evictions and wait for disk pressure condition

* pr feedback - remove ephemeral-storage request for tests

* pr feedback - fix taint removal syntax

* pr feedback - fail faster on pending pods and detect scheduling failures

* pr feedback - cleanup images before job creation and use IfNotPresent

* pr feedback - pre-pull Unity image into k3d node

* Improve k3d cleanup in integrity workflow

* Harden k3d cleanup to avoid disk exhaustion

* pr feedback

* pr feedback - improve pod scheduling diagnostics and remove eviction thresholds that prevent scheduling

* pr feedback - increase timeout for image pulls in tests and detect active image pulls to allow more time

* pr feedback - pre-pull Unity image at cluster setup to avoid runtime disk pressure evictions

* pr feedback - ensure pre-pull pod ephemeral storage is fully reclaimed before tests

* Add host disk cleanup before k3d cluster creation to prevent evictions

* Run LocalStack as managed Docker step for better resource control

* Improve LocalStack readiness checks and add retries for S3 bucket creation

* Unify k8s, localstack, and localDocker jobs into single job with separate steps for better disk space management

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* pr feedback

* f

* fix

* fix

* fixes

* fixes

* fixes

* fixes

* fix

* fix

* fix: k3d/LocalStack networking - use shared Docker network and container name

* fix: rename LOCALSTACK_HOST to K8S_LOCALSTACK_HOST to avoid awslocal conflict

* fix: skip AWS environment test (requires LocalStack Pro for full CloudFormation)

* fix: remove EFS from AWS stack - use S3 caching for storage instead

* Revert "fix: remove EFS from AWS stack - use S3 caching for storage instead"

This reverts commit fdb7286204.

* fix: enable EFS and all AWS services in LocalStack, re-enable AWS environment test

* fix: add secretsmanager and other services to LocalStack

* fix: add aws-local mode - validates AWS CloudFormation templates, executes via local-docker

* fix: add rclone integration test with LocalStack S3 backend

* chore: remove temp log files and debug artifacts

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* fix: address PR review feedback from GabLeRoux

- Update kubectl to v1.34.1 (latest stable)
- Add provider documentation explaining what a provider is
- Fix typo: "versions" -> "tags" in best practices

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* integrate PR #686

* integrate PR #686

* lint fix

* fix: use /bin/sh for Alpine-based images (rclone/rclone) in docker provider

* fix: lint issues

* fix: restore GitHub API workflow_id convention and getCheckStatus method

Reverts cosmetic changes that renamed workflow_id to workflowId in GitHub
API calls. The GitHub REST API uses workflow_id, so we keep the eslint
camelcase suppression comments to match the official API convention.

Also restores the getCheckStatus() method that was removed.

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* revert: remove unrelated changes to docker.ts, github.ts, image-tag.ts, versioning.test.ts

These files had changes unrelated to the Cloud Runner improvements PR goals.
Reverting to main branch state.

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* fix: use /bin/sh for Alpine-based images (rclone/rclone) in docker provider

The rclone/rclone image is Alpine-based and only has /bin/sh, not /bin/bash.
This fixes exit code 127 errors when running rclone commands in containers.

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* fix: fetch only specific PR ref instead of all PR refs

The previous implementation fetched ALL PR refs with:
  git fetch origin +refs/pull/*:refs/remotes/origin/pull/*

This is extremely slow for repos with many PRs (700+ PRs in unity-builder).
Now fetches only the specific PR ref needed, e.g., for pull/731/merge:
  git fetch origin +refs/pull/731/merge:... +refs/pull/731/head:...

This should significantly speed up the Cloud Runner integrity tests.

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* chore: remove cleanup.yml workflow

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* chore: remove redundant cloud-runner-integrity-localstack.yml

Tests are already covered by cloud-runner-integrity.yml

Co-Authored-By: Claude Opus 4.5 <[email protected]>

---------

Co-authored-by: Gabriel Le Breton <[email protected]>
Co-authored-by: Claude Opus 4.5 <[email protected]>
2026-03-03 06:05:12 +00:00
AndrewKahrandAndrewKahr ef38f5a88a Code cleanup (#511)
* Enable noImplicitAny
Add types to all implicit any variables
Bump target to ES2020 for recent language features (optional chaining)
Code cleanup
Add debug configuration for vscode
Remove autorun flag from jest to remove warning
Bump packages to fix dependency version mismatch warning
Changed @arkweid/lefthook to @evilmartians/lefthook as @arkweid/lefthook has been deprecated in favor of @evilmartians/lefthook
Added concurrency groups to integrity check and build workflows. New commits to branches will cancel superseded runs on the same branch/pr
Update imports to not use require syntax
Use node packages (ie node:fs rather than fs)
AndroidVersionCode is now a string rather than a number as it gets converted to a string when passed out of the system
Reduce timeout for windows builds
Remove 2020.1.17f1 from windows builds due to repeated license activation errors
Update naming scheme of workflows for consistency
Update build names so target platform and unity version aren't cut off by github actions UI

* Add exclude to test matrix for 2022.2 on android until Unity bug is fixed

---------

Co-authored-by: AndrewKahr <[email protected]>
2023-03-03 16:25:40 -08:00
Webber Takken 5ae03dfef6 Streamline code styles (#384)
* feat: streamline code styles

* feat: spacing for comments and return statements

* chore: enforce camelcase

* fix: remove npm lock file

* fix: add integrity test

* fix: remove logfile

* chore: update node in test workflow
2022-04-12 00:43:41 +02:00
Frostebite 03ae77dc7c Cloud Runner v2 (#310) 2022-02-01 02:31:20 +00:00
Webber Takken 4fde4e47b6 Refactor action to typescript (#226)
* Refactor to typescript (config part)

* Refactor to typescript (convert extensions, minor fixes)

* Refactor to typescript (move from `action` to `dist`)

* Re-enable integrity-check for dist index.js

* Fix all tests and lints

* fix parsing major versions

* Test patch level to be digits only

* debug

* debug

* uncache

* manual compile

* debug

* debug

* Debug

* Build lib - doh

* remove diff check

* Make kubernetes workflow manual

* Properly generate 3 digit for simple major tags

* Remove ts-ignore

* re-enable cache
2021-03-14 00:44:01 +01:00