From ed36f423dabf8e2a8a1384f5db8a6754e8ef8bda Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Thu, 28 May 2026 22:56:54 -0700 Subject: [PATCH] fix(ci): bound manual git fetches (#87839) * fix(ci): bound manual git fetches * fix(ci): cover platform fetch guards * fix(ci): fail timed out target fetches * fix(ci): repair typecheck regressions * fix(ci): refresh CI expectations * fix(ci): preserve main cron coverage --- .github/actions/ensure-base-commit/action.yml | 10 +- .../workflows/ci-build-artifacts-testbox.yml | 5 +- .github/workflows/ci-check-testbox.yml | 5 +- .github/workflows/ci.yml | 111 ++++++++++++++++-- .github/workflows/crabbox-hydrate.yml | 29 ++++- .github/workflows/workflow-sanity.yml | 15 ++- test/scripts/ci-workflow-guards.test.ts | 77 +++++++++++- .../package-acceptance-workflow.test.ts | 16 ++- test/vitest/vitest.unit-support.config.ts | 1 + 9 files changed, 242 insertions(+), 27 deletions(-) diff --git a/.github/actions/ensure-base-commit/action.yml b/.github/actions/ensure-base-commit/action.yml index 5a66566e871..ec05a4d6415 100644 --- a/.github/actions/ensure-base-commit/action.yml +++ b/.github/actions/ensure-base-commit/action.yml @@ -38,9 +38,15 @@ runs: exit 0 fi + fetch_base_ref() { + timeout --signal=TERM --kill-after=10s 30s git \ + -c protocol.version=2 \ + fetch "$@" + } + for deepen_by in 25 100 300; do echo "Base commit missing; deepening $FETCH_REF by $deepen_by." - if ! git fetch --no-tags --deepen="$deepen_by" origin -- "$FETCH_REF"; then + if ! fetch_base_ref --no-tags --deepen="$deepen_by" origin -- "$FETCH_REF"; then echo "::warning title=ensure-base-commit fetch failed::Failed to deepen $FETCH_REF by $deepen_by while looking for $BASE_SHA" fi if git rev-parse --verify "$BASE_SHA^{commit}" >/dev/null 2>&1; then @@ -50,7 +56,7 @@ runs: done echo "Base commit still missing; fetching full history for $FETCH_REF." - if ! git fetch --no-tags origin -- "$FETCH_REF"; then + if ! fetch_base_ref --no-tags origin -- "$FETCH_REF"; then echo "::warning title=ensure-base-commit fetch failed::Failed to fetch full history for $FETCH_REF while looking for $BASE_SHA" fi if git rev-parse --verify "$BASE_SHA^{commit}" >/dev/null 2>&1; then diff --git a/.github/workflows/ci-build-artifacts-testbox.yml b/.github/workflows/ci-build-artifacts-testbox.yml index d6e314c3000..dd9cee2bd1c 100644 --- a/.github/workflows/ci-build-artifacts-testbox.yml +++ b/.github/workflows/ci-build-artifacts-testbox.yml @@ -188,7 +188,10 @@ jobs: run: | set -euo pipefail - git fetch --no-tags --depth=50 origin "+refs/heads/main:refs/remotes/origin/main" + timeout --signal=TERM --kill-after=10s 30s git \ + -c protocol.version=2 \ + fetch --no-tags --prune --no-recurse-submodules --depth=50 origin \ + "+refs/heads/main:refs/remotes/origin/main" node_bin="$(dirname "$(node -p 'process.execPath')")" sudo ln -sf "$node_bin/node" /usr/local/bin/node diff --git a/.github/workflows/ci-check-testbox.yml b/.github/workflows/ci-check-testbox.yml index 09d8cda8518..eff7a685bed 100644 --- a/.github/workflows/ci-check-testbox.yml +++ b/.github/workflows/ci-check-testbox.yml @@ -89,7 +89,10 @@ jobs: run: | set -euo pipefail - git fetch --no-tags --depth=50 origin "+refs/heads/main:refs/remotes/origin/main" + timeout --signal=TERM --kill-after=10s 30s git \ + -c protocol.version=2 \ + fetch --no-tags --prune --no-recurse-submodules --depth=50 origin \ + "+refs/heads/main:refs/remotes/origin/main" node_bin="$(dirname "$(node -p 'process.execPath')")" sudo ln -sf "$node_bin/node" /usr/local/bin/node diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index acdc0d7789e..0cb82057114 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,12 +86,26 @@ jobs: git init "$GITHUB_WORKSPACE" git -C "$GITHUB_WORKSPACE" config gc.auto 0 git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git" - if ! git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_REF}:refs/remotes/origin/checkout"; then + fetch_checkout_ref() { + local ref="$1" + timeout --signal=TERM --kill-after=10s 30s git -C "$GITHUB_WORKSPACE" \ + -c protocol.version=2 \ + fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \ + "+${ref}:refs/remotes/origin/checkout" + } + if fetch_checkout_ref "$CHECKOUT_REF"; then + : + else + fetch_status="$?" + if [ "$fetch_status" = "124" ] || [ "$fetch_status" = "137" ]; then + echo "::error::checkout fetch for '$CHECKOUT_REF' timed out" + exit "$fetch_status" + fi if [ "$GITHUB_EVENT_NAME" != "workflow_dispatch" ] || [ "$CHECKOUT_REF" = "$CHECKOUT_FALLBACK_REF" ]; then - exit 1 + exit "$fetch_status" fi echo "::warning::workflow_dispatch target_ref '$CHECKOUT_REF' is unavailable; falling back to head SHA '$CHECKOUT_FALLBACK_REF'" - git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_FALLBACK_REF}:refs/remotes/origin/checkout" + fetch_checkout_ref "$CHECKOUT_FALLBACK_REF" fi git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout @@ -321,12 +335,26 @@ jobs: git init "$GITHUB_WORKSPACE" git -C "$GITHUB_WORKSPACE" config gc.auto 0 git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git" - if ! git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_REF}:refs/remotes/origin/checkout"; then + fetch_checkout_ref() { + local ref="$1" + timeout --signal=TERM --kill-after=10s 30s git -C "$GITHUB_WORKSPACE" \ + -c protocol.version=2 \ + fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \ + "+${ref}:refs/remotes/origin/checkout" + } + if fetch_checkout_ref "$CHECKOUT_REF"; then + : + else + fetch_status="$?" + if [ "$fetch_status" = "124" ] || [ "$fetch_status" = "137" ]; then + echo "::error::checkout fetch for '$CHECKOUT_REF' timed out" + exit "$fetch_status" + fi if [ "$GITHUB_EVENT_NAME" != "workflow_dispatch" ] || [ "$CHECKOUT_REF" = "$CHECKOUT_FALLBACK_REF" ]; then - exit 1 + exit "$fetch_status" fi echo "::warning::workflow_dispatch target_ref '$CHECKOUT_REF' is unavailable; falling back to head SHA '$CHECKOUT_FALLBACK_REF'" - git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_FALLBACK_REF}:refs/remotes/origin/checkout" + fetch_checkout_ref "$CHECKOUT_FALLBACK_REF" fi git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout @@ -1555,7 +1583,10 @@ jobs: git init "$GITHUB_WORKSPACE" git -C "$GITHUB_WORKSPACE" config gc.auto 0 git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git" - git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_SHA}:refs/remotes/origin/checkout" + timeout --signal=TERM --kill-after=10s 30s git -C "$GITHUB_WORKSPACE" \ + -c protocol.version=2 \ + fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \ + "+${CHECKOUT_SHA}:refs/remotes/origin/checkout" git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout - name: Setup Python @@ -1603,7 +1634,27 @@ jobs: git init "$GITHUB_WORKSPACE" git -C "$GITHUB_WORKSPACE" config gc.auto 0 git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git" - git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_SHA}:refs/remotes/origin/checkout" + fetch_checkout_ref() { + git -C "$GITHUB_WORKSPACE" \ + -c protocol.version=2 \ + fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \ + "+${CHECKOUT_SHA}:refs/remotes/origin/checkout" & + local fetch_pid="$!" + local elapsed=0 + while kill -0 "$fetch_pid" 2>/dev/null; do + if [ "$elapsed" -ge 30 ]; then + kill -TERM "$fetch_pid" 2>/dev/null || true + sleep 10 + kill -KILL "$fetch_pid" 2>/dev/null || true + wait "$fetch_pid" || true + return 124 + fi + sleep 1 + elapsed=$((elapsed + 1)) + done + wait "$fetch_pid" + } + fetch_checkout_ref git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout - name: Try to exclude workspace from Windows Defender (best-effort) @@ -1703,7 +1754,27 @@ jobs: git init "$GITHUB_WORKSPACE" git -C "$GITHUB_WORKSPACE" config gc.auto 0 git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git" - git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_SHA}:refs/remotes/origin/checkout" + fetch_checkout_ref() { + git -C "$GITHUB_WORKSPACE" \ + -c protocol.version=2 \ + fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \ + "+${CHECKOUT_SHA}:refs/remotes/origin/checkout" & + local fetch_pid="$!" + local elapsed=0 + while kill -0 "$fetch_pid" 2>/dev/null; do + if [ "$elapsed" -ge 30 ]; then + kill -TERM "$fetch_pid" 2>/dev/null || true + sleep 10 + kill -KILL "$fetch_pid" 2>/dev/null || true + wait "$fetch_pid" || true + return 124 + fi + sleep 1 + elapsed=$((elapsed + 1)) + done + wait "$fetch_pid" + } + fetch_checkout_ref git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout - name: Setup Node environment @@ -1749,7 +1820,27 @@ jobs: git init "$GITHUB_WORKSPACE" git -C "$GITHUB_WORKSPACE" config gc.auto 0 git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git" - git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_SHA}:refs/remotes/origin/checkout" + fetch_checkout_ref() { + git -C "$GITHUB_WORKSPACE" \ + -c protocol.version=2 \ + fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \ + "+${CHECKOUT_SHA}:refs/remotes/origin/checkout" & + local fetch_pid="$!" + local elapsed=0 + while kill -0 "$fetch_pid" 2>/dev/null; do + if [ "$elapsed" -ge 30 ]; then + kill -TERM "$fetch_pid" 2>/dev/null || true + sleep 10 + kill -KILL "$fetch_pid" 2>/dev/null || true + wait "$fetch_pid" || true + return 124 + fi + sleep 1 + elapsed=$((elapsed + 1)) + done + wait "$fetch_pid" + } + fetch_checkout_ref git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout - name: Install XcodeGen / SwiftLint / SwiftFormat diff --git a/.github/workflows/crabbox-hydrate.yml b/.github/workflows/crabbox-hydrate.yml index f2cdadcf309..d49b50e69fe 100644 --- a/.github/workflows/crabbox-hydrate.yml +++ b/.github/workflows/crabbox-hydrate.yml @@ -137,7 +137,10 @@ jobs: set -euo pipefail if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then - git fetch --no-tags --depth=50 origin "+refs/heads/main:refs/remotes/origin/main" + timeout --signal=TERM --kill-after=10s 30s git \ + -c protocol.version=2 \ + fetch --no-tags --prune --no-recurse-submodules --depth=50 origin \ + "+refs/heads/main:refs/remotes/origin/main" fi - name: Prepare Crabbox shell @@ -318,7 +321,24 @@ jobs: $ErrorActionPreference = "Stop" if (git rev-parse --is-inside-work-tree 2>$null) { - git fetch --no-tags --depth=50 origin "+refs/heads/main:refs/remotes/origin/main" + $fetch = Start-Process git -NoNewWindow -PassThru -ArgumentList @( + "-c", + "protocol.version=2", + "fetch", + "--no-tags", + "--prune", + "--no-recurse-submodules", + "--depth=50", + "origin", + "+refs/heads/main:refs/remotes/origin/main" + ) + if (-not $fetch.WaitForExit(30000)) { + Stop-Process -Id $fetch.Id -Force -ErrorAction SilentlyContinue + throw "git fetch timed out after 30 seconds" + } + if ($fetch.ExitCode -ne 0) { + throw "git fetch failed with exit code $($fetch.ExitCode)" + } } - name: Setup pnpm and dependencies @@ -513,7 +533,10 @@ jobs: set -euo pipefail if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then - git fetch --no-tags --depth=50 origin "+refs/heads/main:refs/remotes/origin/main" + timeout --signal=TERM --kill-after=10s 30s git \ + -c protocol.version=2 \ + fetch --no-tags --prune --no-recurse-submodules --depth=50 origin \ + "+refs/heads/main:refs/remotes/origin/main" fi node_bin="$(dirname "$(node -p 'process.execPath')")" diff --git a/.github/workflows/workflow-sanity.yml b/.github/workflows/workflow-sanity.yml index e23ded1010f..f4a75b4ec36 100644 --- a/.github/workflows/workflow-sanity.yml +++ b/.github/workflows/workflow-sanity.yml @@ -34,7 +34,10 @@ jobs: git init "$GITHUB_WORKSPACE" git -C "$GITHUB_WORKSPACE" config gc.auto 0 git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git" - git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_SHA}:refs/remotes/origin/checkout" + timeout --signal=TERM --kill-after=10s 30s git -C "$GITHUB_WORKSPACE" \ + -c protocol.version=2 \ + fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \ + "+${CHECKOUT_SHA}:refs/remotes/origin/checkout" git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout - name: Fail on tabs in workflow files @@ -75,7 +78,10 @@ jobs: git init "$GITHUB_WORKSPACE" git -C "$GITHUB_WORKSPACE" config gc.auto 0 git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git" - git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_SHA}:refs/remotes/origin/checkout" + timeout --signal=TERM --kill-after=10s 30s git -C "$GITHUB_WORKSPACE" \ + -c protocol.version=2 \ + fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \ + "+${CHECKOUT_SHA}:refs/remotes/origin/checkout" git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout - name: Install actionlint @@ -116,7 +122,10 @@ jobs: git init "$GITHUB_WORKSPACE" git -C "$GITHUB_WORKSPACE" config gc.auto 0 git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git" - git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_SHA}:refs/remotes/origin/checkout" + timeout --signal=TERM --kill-after=10s 30s git -C "$GITHUB_WORKSPACE" \ + -c protocol.version=2 \ + fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \ + "+${CHECKOUT_SHA}:refs/remotes/origin/checkout" git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout - name: Setup Node environment diff --git a/test/scripts/ci-workflow-guards.test.ts b/test/scripts/ci-workflow-guards.test.ts index 10642d210b0..4fe50d73b2d 100644 --- a/test/scripts/ci-workflow-guards.test.ts +++ b/test/scripts/ci-workflow-guards.test.ts @@ -10,21 +10,92 @@ describe("ci workflow guards", () => { it("kills timed manual checkout fetches after the grace period", () => { const workflowPaths = [ ".github/workflows/ci.yml", + ".github/workflows/workflow-sanity.yml", ".github/workflows/ci-check-testbox.yml", ".github/workflows/ci-build-artifacts-testbox.yml", + ".github/workflows/crabbox-hydrate.yml", ]; for (const workflowPath of workflowPaths) { const workflow = readFileSync(workflowPath, "utf8"); - const fetchTimeouts = workflow.match(/timeout --signal=TERM[^\n]* 30s git -C "\$workdir"/g); + const fetchTimeouts = workflow.match( + /timeout --signal=TERM[^\n]* 30s git(?: -C "(?:\$workdir|\$GITHUB_WORKSPACE|clawhub-source)")?/g, + ); expect(fetchTimeouts?.length, workflowPath).toBeGreaterThan(0); - expect(fetchTimeouts, workflowPath).toEqual( - fetchTimeouts?.map(() => 'timeout --signal=TERM --kill-after=10s 30s git -C "$workdir"'), + expect( + fetchTimeouts?.every((line) => + line.startsWith("timeout --signal=TERM --kill-after=10s 30s git"), + ), + workflowPath, + ).toBe(true); + } + }); + + it("bounds shared base commit fetches", () => { + const action = readFileSync(".github/actions/ensure-base-commit/action.yml", "utf8"); + + expect(action).toContain("fetch_base_ref()"); + expect(action).toContain("timeout --signal=TERM --kill-after=10s 30s git"); + expect(action).toContain("-c protocol.version=2"); + expect(action).not.toContain("if ! git fetch --no-tags"); + }); + + it("bounds early unauthenticated checkout fetches", () => { + const workflow = readCiWorkflow(); + + for (const jobName of ["preflight", "security-fast", "skills-python"]) { + const checkoutStep = workflow.jobs[jobName].steps.find((step) => step.name === "Checkout"); + + expect(checkoutStep.run, jobName).toContain( + 'timeout --signal=TERM --kill-after=10s 30s git -C "$GITHUB_WORKSPACE"', + ); + expect(checkoutStep.run, jobName).toContain("-c protocol.version=2"); + expect(checkoutStep.run, jobName).toContain( + "fetch --no-tags --prune --no-recurse-submodules --depth=1 origin", + ); + if (jobName !== "skills-python") { + expect(checkoutStep.run, jobName).toContain('if [ "$fetch_status" = "124" ]'); + expect(checkoutStep.run, jobName).toContain("timed out"); + } + expect(checkoutStep.run, jobName).not.toContain( + 'git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1', ); } }); + it("bounds platform checkout fetches without GNU timeout", () => { + const workflow = readCiWorkflow(); + + for (const jobName of ["checks-windows", "macos-node", "macos-swift"]) { + const checkoutStep = workflow.jobs[jobName].steps.find((step) => step.name === "Checkout"); + + expect(checkoutStep.run, jobName).toContain("fetch_checkout_ref()"); + expect(checkoutStep.run, jobName).toContain("-c protocol.version=2"); + expect(checkoutStep.run, jobName).toContain( + "fetch --no-tags --prune --no-recurse-submodules --depth=1 origin", + ); + expect(checkoutStep.run, jobName).toContain('kill -TERM "$fetch_pid"'); + expect(checkoutStep.run, jobName).toContain('kill -KILL "$fetch_pid"'); + expect(checkoutStep.run, jobName).not.toContain( + 'git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1', + ); + } + }); + + it("bounds the Windows Crabbox hydrate main fetch", () => { + const workflow = readFileSync(".github/workflows/crabbox-hydrate.yml", "utf8"); + + expect(workflow).toContain("$fetch = Start-Process git"); + expect(workflow).toContain('"protocol.version=2"'); + expect(workflow).toContain('"--no-recurse-submodules"'); + expect(workflow).toContain("$fetch.WaitForExit(30000)"); + expect(workflow).toContain('throw "git fetch timed out after 30 seconds"'); + expect(workflow).not.toContain( + 'git fetch --no-tags --depth=50 origin "+refs/heads/main:refs/remotes/origin/main"', + ); + }); + it("runs dependency policy guards in PR CI preflight", () => { const workflow = readFileSync(".github/workflows/ci.yml", "utf8"); const preflightGuards = workflow.slice( diff --git a/test/scripts/package-acceptance-workflow.test.ts b/test/scripts/package-acceptance-workflow.test.ts index 54ec3f971f5..67600f7033b 100644 --- a/test/scripts/package-acceptance-workflow.test.ts +++ b/test/scripts/package-acceptance-workflow.test.ts @@ -141,7 +141,13 @@ describe("package acceptance workflow", () => { expect(hydratePnpm.run).toContain('corepack enable --install-directory "$PNPM_HOME"'); expect(hydratePnpm.run).toContain("COREPACK_HOME"); expect(workflowStep(hydrate, "Fetch main ref").run).toContain( - 'git fetch --no-tags --depth=50 origin "+refs/heads/main:refs/remotes/origin/main"', + "timeout --signal=TERM --kill-after=10s 30s git", + ); + expect(workflowStep(hydrate, "Fetch main ref").run).toContain( + "fetch --no-tags --prune --no-recurse-submodules --depth=50 origin", + ); + expect(workflowStep(hydrate, "Fetch main ref").run).toContain( + '"+refs/heads/main:refs/remotes/origin/main"', ); expect(workflowStep(hydrate, "Prepare Crabbox shell").if).toBeUndefined(); expect(workflowStep(hydrate, "Ensure Docker is running").if).toBeUndefined(); @@ -178,9 +184,11 @@ describe("package acceptance workflow", () => { ); const hydrateWindowsFetch = workflowStep(hydrateWindowsDaemon, "Fetch main ref"); expect(hydrateWindowsFetch.shell).toBe("powershell"); - expect(hydrateWindowsFetch.run).toContain( - 'git fetch --no-tags --depth=50 origin "+refs/heads/main:refs/remotes/origin/main"', - ); + expect(hydrateWindowsFetch.run).toContain("Start-Process git"); + expect(hydrateWindowsFetch.run).toContain("WaitForExit(30000)"); + expect(hydrateWindowsFetch.run).toContain('"fetch"'); + expect(hydrateWindowsFetch.run).toContain('"--depth=50"'); + expect(hydrateWindowsFetch.run).toContain('"+refs/heads/main:refs/remotes/origin/main"'); expect(workflowStep(hydrateWindowsDaemon, "Mark Crabbox ready").shell).toBe("powershell"); expect(workflowStep(hydrateWindowsDaemon, "Mark Crabbox ready").run).toContain('"NODE_BIN"'); expect(workflowStep(hydrateWindowsDaemon, "Mark Crabbox ready").run).toContain('"PNPM_HOME"'); diff --git a/test/vitest/vitest.unit-support.config.ts b/test/vitest/vitest.unit-support.config.ts index db333cd673a..06f4752538a 100644 --- a/test/vitest/vitest.unit-support.config.ts +++ b/test/vitest/vitest.unit-support.config.ts @@ -9,6 +9,7 @@ export default createUnitVitestConfigWithOptions(process.env, { // The gateway-protocol package rides with gateway-client because the client // package owns the browser/runtime protocol compatibility lane. "packages/gateway-protocol/src/**/*.test.ts", + "packages/gateway-client/src/**/*.test.ts", ], passWithNoTests: true, });