Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,84 @@ jobs:
echo "$ACTUAL" | grep -q "^v${{ matrix.node-version }}\." || (echo "Expected Node.js v${{ matrix.node-version }}.x but got $ACTUAL" && exit 1)
fi

# End-to-end check of node-manager: false. The installer must skip
# node/npm/npx/corepack shim creation (VP_NODE_MANAGER=no) and the action
# must run `vp env off`, so vp commands resolve the Node.js already on the
# runner instead of a managed one. Records the preinstalled Node.js binary,
# runs a real `vp install`, then asserts the binary is unchanged, no shims
# exist, and `vp exec` resolves the system Node.js. $VP_HOME/js_runtime is
# NOT asserted empty: the installer always downloads a managed Node LTS
# there to install vp's own production deps with a deterministic runtime
# (vite_setup install_production_deps), independent of VP_NODE_MANAGER.
test-node-manager-off:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2

- name: Record preinstalled Node.js
id: before
shell: bash
run: |
echo "path=$(command -v node)" >> "$GITHUB_OUTPUT"
echo "version=$(node --version)" >> "$GITHUB_OUTPUT"

- name: Create test project
shell: bash
run: |
DIR="${RUNNER_TEMP//\\//}/test-project"
mkdir -p "$DIR"
echo '{"name":"test-project","private":true}' > "$DIR/package.json"

- name: Setup Vite+ without Node.js manager
uses: ./
with:
node-manager: false
run-install: |
- cwd: ${{ runner.temp }}/test-project
cache: false

- name: Verify installation
run: vp --version

- name: Verify system Node.js is untouched
shell: bash
run: |
ACTUAL_PATH=$(command -v node)
ACTUAL_VERSION=$(node --version)
echo "node before: ${{ steps.before.outputs.path }} (${{ steps.before.outputs.version }})"
echo "node after: $ACTUAL_PATH ($ACTUAL_VERSION)"
if [ "$ACTUAL_PATH" != "${{ steps.before.outputs.path }}" ]; then
echo "::error::node resolves to $ACTUAL_PATH; expected ${{ steps.before.outputs.path }}"
exit 1
fi
if [ "$ACTUAL_VERSION" != "${{ steps.before.outputs.version }}" ]; then
echo "::error::node is $ACTUAL_VERSION; expected ${{ steps.before.outputs.version }}"
exit 1
fi

- name: Verify no Node.js shims were created
shell: bash
run: |
SHIMS=$(ls "$HOME/.vite-plus/bin" | grep -E '^(node|npm|npx|corepack)' || true)
if [ -n "$SHIMS" ]; then
echo "::error::unexpected Node.js shims in $HOME/.vite-plus/bin: $SHIMS"
exit 1
fi

- name: Verify vp commands use the system Node.js
shell: bash
run: |
EXEC_VERSION=$(vp exec node --version | tr -d '\r')
echo "vp exec node --version: $EXEC_VERSION"
if [ "$EXEC_VERSION" != "${{ steps.before.outputs.version }}" ]; then
echo "::error::vp resolved Node.js $EXEC_VERSION; expected system ${{ steps.before.outputs.version }}"
exit 1
fi

test-default-version:
# End-to-end check of the default version-resolution logic: with no `version`
# or `version-file` input, the action auto-detects the vite-plus version from
Expand Down
50 changes: 36 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,23 @@ steps:
node-version-file: ".node-version"
```

### Keep the Runner's Node.js

The Vite+ installer enables its own Node.js version manager on CI. When
Node.js is managed elsewhere (`actions/setup-node`, Flox, mise, or the runner
image), disable it so `vp` and its shims use that Node.js:

```yaml
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v5
with:
node-version: 24
- uses: voidzero-dev/setup-vp@v1.16.1
with:
node-manager: false
```

### With Working Directory

```yaml
Expand Down Expand Up @@ -311,22 +328,25 @@ jobs:

## Inputs

| Input | Description | Required | Default |
| ----------------------- | ----------------------------------------------------------------------------------------------------------- | -------- | --------------- |
| `version` | Version of Vite+ to install. Takes precedence over `version-file` | No | auto / `latest` |
| `version-file` | Path to a file to resolve the Vite+ version from (`package.json`, `pnpm-workspace.yaml`, or `.yarnrc.yml`) | No | |
| `node-version` | Node.js version to install via `vp env use` | No | Latest LTS |
| `node-version-file` | Path to file containing Node.js version (`.nvmrc`, `.node-version`, `.tool-versions`, `package.json`) | No | |
| `working-directory` | Project directory used for relative paths, lockfile auto-detection, environment checks, and default install | No | Workspace root |
| `run-install` | Run `vp install` after setup. Accepts boolean or YAML object with `cwd`/`args` | No | `true` |
| `sfw` | Wrap `vp install` with [Socket Firewall Free](https://docs.socket.dev/docs/socket-firewall-free) (`sfw`) | No | `false` |
| `cache` | Enable caching of project dependencies | No | `false` |
| `cache-dependency-path` | Path to lock file for cache key generation | No | Auto-detected |
| `registry-url` | Optional registry to set up for auth. Sets the registry in `.npmrc` and reads auth from `NODE_AUTH_TOKEN` | No | |
| `scope` | Optional scope for scoped registries. Falls back to repo owner for GitHub Packages | No | |
| Input | Description | Required | Default |
| ----------------------- | ----------------------------------------------------------------------------------------------------------- | -------- | ---------------- |
| `version` | Version of Vite+ to install. Takes precedence over `version-file` | No | auto / `latest` |
| `version-file` | Path to a file to resolve the Vite+ version from (`package.json`, `pnpm-workspace.yaml`, or `.yarnrc.yml`) | No | |
| `node-version` | Node.js version to install via `vp env use` | No | Latest LTS |
| `node-version-file` | Path to file containing Node.js version (`.nvmrc`, `.node-version`, `.tool-versions`, `package.json`) | No | |
| `node-manager` | Control Vite+'s Node.js manager: `false` keeps the runner's Node.js, `true` force-enables the managed one | No | Auto (on for CI) |
| `working-directory` | Project directory used for relative paths, lockfile auto-detection, environment checks, and default install | No | Workspace root |
| `run-install` | Run `vp install` after setup. Accepts boolean or YAML object with `cwd`/`args` | No | `true` |
| `sfw` | Wrap `vp install` with [Socket Firewall Free](https://docs.socket.dev/docs/socket-firewall-free) (`sfw`) | No | `false` |
| `cache` | Enable caching of project dependencies | No | `false` |
| `cache-dependency-path` | Path to lock file for cache key generation | No | Auto-detected |
| `registry-url` | Optional registry to set up for auth. Sets the registry in `.npmrc` and reads auth from `NODE_AUTH_TOKEN` | No | |
| `scope` | Optional scope for scoped registries. Falls back to repo owner for GitHub Packages | No | |

When `working-directory` is set, relative `run-install.cwd`, `node-version-file`, `version-file`, and `cache-dependency-path` values are resolved from that directory.

`node-manager: false` skips Node.js shim creation and runs `vp env off`, so `vp` commands prefer the Node.js already on `PATH`. It cannot be combined with `node-version` or `node-version-file`.

## Outputs

| Output | Description |
Expand Down Expand Up @@ -484,6 +504,7 @@ test:
| `working-directory` | Project directory used for relative paths and default `vp install` execution | `.` |
| `run-install` | String input for `vp install` after setup. Use `"true"`/`"false"` or a YAML object/list with `cwd`/`args` | `true` |
| `sfw` | Wrap `vp install` with [Socket Firewall Free](https://docs.socket.dev/docs/socket-firewall-free) | `false` |
| `node-manager` | String input: `"false"` keeps the runner image's Node.js (skips shims and runs `vp env off`); `"true"` force-enables the managed Node.js; empty lets the installer decide (enabled on CI) | |
| `registry-url` | Optional registry URL to write to a temporary `.npmrc` | |
| `scope` | Optional scope for authenticating against scoped registries | |
| `setup-ref` | setup-vp ref used to download the GitLab bootstrap and compiled runtime. Always set it to the same tag as the remote URL; the default is the latest release when the template was published | `v1.16.1` |
Expand All @@ -496,7 +517,7 @@ test:
- GitLab 17.9+ users can add `integrity` to pin the remote file hash.
- The template expects a Unix-like runner image with Node.js, `bash`, and either `curl` or `wget`.
- The GitLab runtime source is TypeScript under `src/gitlab/`, but the template downloads and runs the `vp pack` generated JavaScript bundle from `dist/gitlab/index.mjs`.
- The GitLab template does not set up Node.js. Use a Node image such as `node:24`, or install Node.js before extending `.setup-vp`.
- The GitLab template does not set up Node.js. Use a Node image such as `node:24`, or install Node.js before extending `.setup-vp`. The Vite+ installer still enables its own Node.js manager on CI; set `node-manager: "false"` to keep the image's Node.js for `vp` commands.
- The GitLab template intentionally does not expose `cache` or `cache-dependency-path` inputs. GitLab restores job cache before `before_script`, so this template cannot compute cache paths during setup and restore them for the same job. Configure GitLab `cache:` directly on the job when needed.

## Azure Pipelines
Expand Down Expand Up @@ -548,6 +569,7 @@ Pin `ref` and `setupRef` to the same exact tag or commit SHA. Do not use the `v1
| `scope` | | Optional npm registry scope. |
| `setupRef` | `v1.16.1` | Ref used to download bootstrap scripts and `dist/azure/index.mjs`. Always set it to the same tag as `ref`; the default is the latest release when the template was published. |
| `nodeVersion` | `24.x` | Passed to `UseNode@1`; an empty string skips Node setup. |
| `nodeManager` | | Control Vite+'s Node.js manager: `false` keeps the agent's Node.js (e.g. from `UseNode@1`); `true` force-enables the managed one; empty lets the installer decide. |
| `cache` | `false` | Enable Azure `Cache@2` around the package-manager cache directory. |
| `cacheDependencyPath` | | Explicit lock file relative to `workingDirectory`; otherwise auto-detect. |

Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ inputs:
node-version-file:
description: "Path to file containing the Node.js version spec (.nvmrc, .node-version, .tool-versions, package.json). Ignored when node-version is specified."
required: false
node-manager:
description: "Control Vite+'s Node.js version manager. When unset, the Vite+ installer decides (enabled on CI). Set to `false` to keep the Node.js already on the runner (e.g. from actions/setup-node or the runner image): shim creation is skipped and vp commands prefer the system Node.js. Set to `true` to force-enable the managed Node.js. Cannot be `false` together with node-version or node-version-file."
required: false
working-directory:
description: "Project directory to use for relative paths, lockfile auto-detection, environment checks, and default `vp install` execution."
required: false
Expand Down
5 changes: 5 additions & 0 deletions azure/setup-vp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ parameters:
- name: nodeVersion
type: string
default: 24.x
- name: nodeManager
type: string
default: ""
- name: cache
type: boolean
default: false
Expand Down Expand Up @@ -50,6 +53,7 @@ steps:
SETUP_VP_WORKING_DIRECTORY: ${{ parameters.workingDirectory }}
SETUP_VP_RUN_INSTALL: ${{ convertToJson(parameters.runInstall) }}
SETUP_VP_SFW: ${{ iif(eq(parameters.sfw, true), 'true', 'false') }}
SETUP_VP_NODE_MANAGER: ${{ parameters.nodeManager }}
SETUP_VP_REGISTRY_URL: ${{ parameters.registryUrl }}
SETUP_VP_SCOPE: ${{ parameters.scope }}
SETUP_VP_SETUP_REF: ${{ parameters.setupRef }}
Expand All @@ -71,6 +75,7 @@ steps:
SETUP_VP_WORKING_DIRECTORY: ${{ parameters.workingDirectory }}
SETUP_VP_RUN_INSTALL: ${{ convertToJson(parameters.runInstall) }}
SETUP_VP_SFW: ${{ iif(eq(parameters.sfw, true), 'true', 'false') }}
SETUP_VP_NODE_MANAGER: ${{ parameters.nodeManager }}
SETUP_VP_REGISTRY_URL: ${{ parameters.registryUrl }}
SETUP_VP_SCOPE: ${{ parameters.scope }}
SETUP_VP_SETUP_REF: ${{ parameters.setupRef }}
Expand Down
Loading
Loading