diff --git a/.github/actions/clone/action.yml b/.github/actions/clone/action.yml index 6db8238f68..406219d175 100644 --- a/.github/actions/clone/action.yml +++ b/.github/actions/clone/action.yml @@ -2,6 +2,10 @@ name: 'Clone Repositories' description: 'Clone self and upstream repositories' inputs: + setup-node: + description: 'Set to false to keep a caller-provided Node.js with native TypeScript support (for example, on Alpine)' + required: false + default: 'true' ecosystem-ci-project: description: 'The ecosystem ci project to clone' required: false @@ -15,6 +19,17 @@ outputs: runs: using: 'composite' steps: + # Run the bootstrap scripts with native TypeScript support before installing dependencies. + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + if: ${{ inputs.setup-node != 'false' }} + with: + node-version-file: .node-version + package-manager-cache: false + + - name: Validate bootstrap Node.js + shell: bash + run: node -e "require('node:assert/strict').ok(process.features.typescript, 'Clone bootstrap requires native TypeScript support')" + - name: Output rolldown and vite hash shell: bash id: upstream-versions @@ -48,11 +63,10 @@ runs: persist-credentials: false # Match the manifests used by sync-remote when it generated the root lockfile. - # setup-node installs with --frozen-lockfile, so this must run before it. - # The runner's preinstalled Node may not support direct TypeScript execution. + # The later dependency installation uses --frozen-lockfile, so alignment must run first. - name: Align vendored Vite's Vitest dependencies shell: bash - run: npx tsx packages/tools/src/vendored-vitest.ts + run: node packages/tools/src/vendored-vitest.ts # Disable autocrlf to preserve LF line endings on Windows # This prevents prettier/eslint from failing with "Delete ␍" errors @@ -64,6 +78,6 @@ runs: - name: Clone ecosystem ci project if: ${{ inputs.ecosystem-ci-project != '' }} shell: bash - run: npx tsx ecosystem-ci/clone.ts ${INPUTS_ECOSYSTEM_CI_PROJECT} + run: node ecosystem-ci/clone.ts ${INPUTS_ECOSYSTEM_CI_PROJECT} env: INPUTS_ECOSYSTEM_CI_PROJECT: ${{ inputs.ecosystem-ci-project }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0af1fc32c9..be3932bae1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -289,7 +289,19 @@ jobs: run: apk add --no-cache bash curl git just musl-dev gcc g++ python3 cmake make - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 + + - name: Record Alpine Node.js runtime + run: node -p "'ALPINE_NODE=' + process.execPath" >> "$GITHUB_ENV" + - uses: ./.github/actions/clone + with: + # setup-node's Linux binaries require glibc; keep the container's musl build. + setup-node: 'false' + + - name: Verify clone preserves the Alpine Node.js runtime + run: | + node -e "require('node:assert/strict').equal(process.execPath, process.env.ALPINE_NODE)" + node --version - name: Install rustup run: | diff --git a/packages/tools/src/vendored-vitest.ts b/packages/tools/src/vendored-vitest.ts index d068690afe..29223bb6b4 100644 --- a/packages/tools/src/vendored-vitest.ts +++ b/packages/tools/src/vendored-vitest.ts @@ -2,7 +2,7 @@ import { existsSync, readFileSync, readdirSync, realpathSync, writeFileSync } fr import { join } from 'node:path'; import { fileURLToPath } from 'node:url'; -// This module runs before dependency installation and Node.js setup in CI. +// This module runs before dependency installation in CI. // Keep it independent of installed project dependencies, with only built-in imports. // These official packages share the runner version selected by upgrade-deps.ts. // Community packages, such as browser-webdriverio, have independent versions.