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
18 changes: 14 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
manager: ["pnpm@12.14.0", "yarn@1.22.22", "npm@11.6.2", "bun@1.4.2"]
runs-on: ${{ matrix.os }}
timeout-minutes: 10
env:
VP_PR_VERSION: ""
TEST_PACKAGE_MANAGER: ${{ matrix.manager }}
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- name: Select a fresh installation directory
Expand All @@ -43,12 +45,12 @@ jobs:
import { appendFileSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
import { join } from "node:path";
// Both jobs use the same absolute paths, but separate fresh runners.
const home = join(process.env.RUNNER_TEMP, `setup-vp-toolchain-${process.env.GITHUB_RUN_ID}-${process.env.GITHUB_RUN_ATTEMPT}`);
const home = join(process.env.RUNNER_TEMP, `setup-vp-toolchain-${process.env.GITHUB_RUN_ID}-${process.env.GITHUB_RUN_ATTEMPT}-${process.env.TEST_PACKAGE_MANAGER}`);
if (existsSync(home)) throw new Error("Expected a fresh installation");
appendFileSync(process.env.GITHUB_ENV, `VP_HOME=${home}\n`);
const project = join(process.env.RUNNER_TEMP, "setup-vp-toolchain-project");
mkdirSync(project, { recursive: true });
writeFileSync(join(project, "package.json"), JSON.stringify({ private: true }));
writeFileSync(join(project, "package.json"), JSON.stringify({ private: true, packageManager: process.env.TEST_PACKAGE_MANAGER }));
NODE
- name: Setup Vite+ with a cache miss
id: setup
Expand All @@ -65,25 +67,30 @@ jobs:
working-directory: ${{ runner.temp }}/setup-vp-toolchain-project
env:
CACHE_HIT: ${{ steps.setup.outputs.toolchain-cache-hit }}
PM_CACHE_HIT: ${{ steps.setup.outputs.package-manager-cache-hit }}
VP_VERSION: ${{ steps.setup.outputs.version }}
run: |
test "$CACHE_HIT" = "false"
test "$PM_CACHE_HIT" = "false"
test "$VP_VERSION" = "1.3.0"
test "$(node --version)" = "v22.23.1"
vp_binary=vp
if [ "$RUNNER_OS" = "Windows" ]; then vp_binary=vp.exe; fi
"$vp_binary" fmt --version
"$vp_binary" install --ignore-scripts

test-toolchain-cache-hit:
needs: test-toolchain-cache-miss
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
manager: ["pnpm@12.14.0", "yarn@1.22.22", "npm@11.6.2", "bun@1.4.2"]
runs-on: ${{ matrix.os }}
timeout-minutes: 10
env:
VP_PR_VERSION: ""
TEST_PACKAGE_MANAGER: ${{ matrix.manager }}
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- name: Select a fresh installation directory
Expand All @@ -93,12 +100,12 @@ jobs:
import { appendFileSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
import { join } from "node:path";
// Both jobs use the same absolute paths, but separate fresh runners.
const home = join(process.env.RUNNER_TEMP, `setup-vp-toolchain-${process.env.GITHUB_RUN_ID}-${process.env.GITHUB_RUN_ATTEMPT}`);
const home = join(process.env.RUNNER_TEMP, `setup-vp-toolchain-${process.env.GITHUB_RUN_ID}-${process.env.GITHUB_RUN_ATTEMPT}-${process.env.TEST_PACKAGE_MANAGER}`);
if (existsSync(home)) throw new Error("Expected a fresh installation");
appendFileSync(process.env.GITHUB_ENV, `VP_HOME=${home}\n`);
const project = join(process.env.RUNNER_TEMP, "setup-vp-toolchain-project");
mkdirSync(project, { recursive: true });
writeFileSync(join(project, "package.json"), JSON.stringify({ private: true }));
writeFileSync(join(project, "package.json"), JSON.stringify({ private: true, packageManager: process.env.TEST_PACKAGE_MANAGER }));
NODE
- name: Setup Vite+ with a cache hit
id: setup
Expand All @@ -116,14 +123,17 @@ jobs:
working-directory: ${{ runner.temp }}/setup-vp-toolchain-project
env:
CACHE_HIT: ${{ steps.setup.outputs.toolchain-cache-hit }}
PM_CACHE_HIT: ${{ steps.setup.outputs.package-manager-cache-hit }}
VP_VERSION: ${{ steps.setup.outputs.version }}
run: |
test "$CACHE_HIT" = "true"
test "$PM_CACHE_HIT" = "true"
test "$VP_VERSION" = "1.3.0"
test "$(node --version)" = "v22.23.1"
vp_binary=vp
if [ "$RUNNER_OS" = "Windows" ]; then vp_binary=vp.exe; fi
"$vp_binary" fmt --version
"$vp_binary" install --ignore-scripts

zizmor:
name: Audit GitHub Actions
Expand Down
70 changes: 54 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ jobs:
| `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-toolchain` | Cache the Vite+ payload and managed Node.js runtime in GitHub Actions. Requires exact versions | No | `false` |
| `cache-toolchain` | Cache Vite+, managed Node.js, and the selected package manager in GitHub Actions. Requires exact versions | No | `false` |
| `cache-save` | Save enabled dependency and toolchain caches in the post action | No | `true` |
| `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 | |
Expand Down Expand Up @@ -377,14 +377,15 @@ Separate package-manager modes require Vite+ 0.3.1+. Any explicit configuration,

## Outputs

| Output | Description |
| ------------------------- | ------------------------------------------------------------------------------------ |
| `version` | The installed version of Vite+ |
| `cache-hit` | Boolean indicating if cache was restored |
| `toolchain-cache-hit` | Whether an exact toolchain cache passed validation (`true` or `false`, when enabled) |
| `node-version` | The Node.js version Vite+ resolved, such as `24.20.0` |
| `package-manager` | The package manager Vite+ resolved, such as `pnpm` or `bun` |
| `package-manager-version` | The version of that package manager, such as `10.33.0` |
| Output | Description |
| --------------------------- | ------------------------------------------------------------------------------------ |
| `version` | The installed version of Vite+ |
| `cache-hit` | Boolean indicating if cache was restored |
| `toolchain-cache-hit` | Whether an exact toolchain cache passed validation (`true` or `false`, when enabled) |
| `package-manager-cache-hit` | Whether the selected package manager passed cache validation (when enabled) |
| `node-version` | The Node.js version Vite+ resolved, such as `24.20.0` |
| `package-manager` | The package manager Vite+ resolved, such as `pnpm` or `bun` |
| `package-manager-version` | The version of that package manager, such as `10.33.0` |

The last three come from `vp env current --json` in `working-directory` at the end of setup. They require Vite+ 0.3.1+ and are `unknown` on older versions or when Vite+ reports no value. With `node-manager: false`, `node-version` is the version of the Node.js found on `PATH`.

Expand All @@ -406,7 +407,8 @@ does not restore an installation onto a fresh runner.
### Toolchain cache (GitHub Actions)

Set `cache-toolchain: true` to cache the versioned Vite+ payload and the selected
Node.js runtime. This cache is independent of the project dependency cache. It
Node.js runtime. It also caches the package manager selected for `working-directory`.
This cache is independent of the project dependency cache. It
can restore these files onto a fresh runner before the installer runs.

Use an exact Vite+ version with native self-setup support, or a preview version
Expand All @@ -418,10 +420,12 @@ declarations described above. Moving versions such as `latest`, `lts`, and `22`,
disabled Node.js management, and local installer overrides skip this cache.

The cache key includes the OS, architecture, Linux libc, both versions, installation
path, npm registry, and Node.js mirror. There are no fallback keys. The installer
still runs after restoration to create the active links and apply the current
configuration. Configuration, credentials, project dependencies, package stores,
and other Node.js versions are not in this cache.
path, npm registry, and Node.js mirror. There are no fallback keys. On a validated
cache hit with no active installation, the cached CLI runs its native setup to
create links and apply the current configuration. This avoids downloading and
running a shell installer. Other cases use the normal installer, including a
failed native setup. Configuration, credentials, project dependencies, package
stores, and other Node.js versions are not in this cache.

The action checks restored versions, installation paths, dependencies, and the
native binding. An invalid or unavailable cache falls back to installation. If
Expand All @@ -432,6 +436,24 @@ time for short jobs; measure both setup and the post action for your workload.
This input is available only in the GitHub Action. GitLab and Azure retain their
existing dependency cache behavior.

The selected managed `pnpm`, `yarn`, `npm`, or `bun` installation uses a separate
archive under the same `cache-toolchain` input. The action asks
`vp env current --json` for the exact version and installation path after setup,
then restores the archive before dependency cache discovery or `vp install`.
A package-manager version change can reuse the Vite+/Node.js archive.

The package-manager key includes the toolchain identity, manager name, resolved
version, and a hash of npm configuration. Configuration files and credentials
are not in the archive. System managers, Node.js bundled npm, unresolved versions,
and unsupported layouts skip this archive. Bundled npm is already in the Node.js
runtime archive. An existing installation is preserved. Invalid archives fall
back to normal installation. The post action saves only complete installations;
`run-install: false` does not install a manager just to fill its cache.

`toolchain-cache-hit` continues to report the Vite+/Node.js archive.
`package-manager-cache-hit` reports the separate manager archive. Both archives
follow `cache-save`, and uploads run in parallel with dependency cache uploads.

#### Toolchain cache storage

For Vite+ `1.3.0` and Node.js `22.23.1`, the
Expand All @@ -447,10 +469,26 @@ show these compressed archive sizes per cache entry:
One entry for each platform totals about **244 MiB (0.24 GiB)**. These figures
describe storage in GitHub's cache service. Extracted files require more disk
space on the runner. Sizes vary with the toolchain versions and platform.
The selected package manager adds one archive per key; its size depends on the
manager, version, and platform. The figures above exclude that archive.

For `pnpm@12.7.0`, the
[hosted measurements](https://github.com/voidzero-dev/setup-vp/actions/runs/39227680298)
show these additional compressed archive sizes:

| Runner | Package manager archive |
| ----------------- | ----------------------: |
| Linux x64 (glibc) | 20.6 MiB |
| macOS ARM64 | 17.8 MiB |
| Windows x64 | 20.1 MiB |

One entry per platform adds about **59 MiB**. Other managers and versions can
have different sizes. A package-manager key change creates a new manager
archive and can reuse the existing Vite+/Node.js archive.

A cache hit reuses an existing entry without uploading another copy. Each new
cache key stores a complete archive of both Vite+ and Node.js, even when only one
version changes. Different keys and GitHub branch or pull request scopes can
Vite+/Node.js cache key stores a complete archive of both tools, even when only
one version changes. Different keys and GitHub branch or pull request scopes can
retain separate entries. See [GitHub's cache scope rules](https://docs.github.com/en/actions/reference/workflows-and-actions/dependency-caching#restrictions-for-accessing-a-cache).

The project dependency cache (`cache: true`) uses additional storage that depends
Expand Down
4 changes: 3 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ inputs:
required: false
default: "true"
cache-toolchain:
description: "Cache the Vite+ installation and managed Node.js runtime before setup. Requires exact Vite+ and Node.js versions. Independent of the project dependency cache."
description: "Cache Vite+, the managed Node.js runtime, and the selected managed package manager. Requires exact Vite+ and Node.js versions. Independent of the project dependency cache."
required: false
default: "false"
cache-dependency-path:
Expand All @@ -66,6 +66,8 @@ outputs:
description: "Boolean indicating if cache was restored"
toolchain-cache-hit:
description: "Whether an exact toolchain cache passed validation before installation"
package-manager-cache-hit:
description: "Whether the selected package manager passed cache validation (when cache-toolchain is enabled)"
node-version:
description: "The Node.js version Vite+ resolved for working-directory, from `vp env current` (0.3.1+). `unknown` on older versions or when Vite+ reports none."
package-manager:
Expand Down
Loading
Loading