mirror of
https://github.com/pnpm/action-setup.git
synced 2026-08-14 05:52:09 +08:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e9503d0fb | ||
|
|
c753b811d8 |
@@ -1 +0,0 @@
|
|||||||
* @zkochan
|
|
||||||
@@ -19,7 +19,7 @@ jobs:
|
|||||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||||
with:
|
with:
|
||||||
run_install: true
|
run_install: true
|
||||||
version: 11
|
version: 9
|
||||||
|
|
||||||
- name: Update dist/index.js
|
- name: Update dist/index.js
|
||||||
run: pnpm run build
|
run: pnpm run build
|
||||||
|
|||||||
+114
-328
@@ -1,174 +1,86 @@
|
|||||||
name: Test Action
|
name: Test Action
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
- push
|
||||||
push:
|
- pull_request
|
||||||
branches:
|
- workflow_dispatch
|
||||||
- master
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
smoke:
|
test_default_inputs:
|
||||||
# Cross-OS coverage. Exercises the bootstrap install + PATH on each platform,
|
name: Test with default inputs
|
||||||
# the version-respects-request regression (#225 / #230 — Windows PATH shadow),
|
|
||||||
# and the bin_dest output regression (#247). Multi-version coverage on Linux
|
|
||||||
# so we don't pay 3x for major-version differences.
|
|
||||||
name: 'Smoke (${{ matrix.name }})'
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
pnpm:
|
||||||
- name: 'ubuntu / v9.15.5'
|
- 9.15.5
|
||||||
os: ubuntu-latest
|
os:
|
||||||
version: '9.15.5'
|
- ubuntu-latest
|
||||||
- name: 'ubuntu / v10.33.0'
|
- macos-latest
|
||||||
os: ubuntu-latest
|
- windows-latest
|
||||||
version: '10.33.0'
|
|
||||||
- name: 'ubuntu / v9.15.5 / custom-dest'
|
|
||||||
os: ubuntu-latest
|
|
||||||
version: '9.15.5'
|
|
||||||
dest: '~/test/pnpm'
|
|
||||||
- name: 'macos / v9.15.5'
|
|
||||||
os: macos-latest
|
|
||||||
version: '9.15.5'
|
|
||||||
- name: 'windows / v9.15.5'
|
|
||||||
os: windows-latest
|
|
||||||
version: '9.15.5'
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
||||||
|
|
||||||
- id: pnpm
|
|
||||||
name: Run the action
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
version: ${{ matrix.version }}
|
|
||||||
dest: ${{ matrix.dest || '~/setup-pnpm' }}
|
|
||||||
|
|
||||||
- name: 'Test: pnpm/pnpx on PATH report the requested version (incl. via bin_dest)'
|
|
||||||
# Pass paths via env, not template interpolation, so Windows
|
|
||||||
# backslashes in `bin_dest` aren't eaten by bash's escape handling.
|
|
||||||
env:
|
|
||||||
BIN_DEST: ${{ steps.pnpm.outputs.bin_dest }}
|
|
||||||
REQUIRED: ${{ matrix.version }}
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
which pnpm
|
|
||||||
which pnpx
|
|
||||||
actual="$(pnpm --version)"
|
|
||||||
echo "pnpm --version: ${actual}"
|
|
||||||
if [ "${actual}" != "${REQUIRED}" ]; then
|
|
||||||
echo "Expected pnpm version ${REQUIRED}, but got ${actual}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
bin_dest_version="$("$BIN_DEST/pnpm" --version)"
|
|
||||||
echo "bin_dest pnpm --version: ${bin_dest_version}"
|
|
||||||
if [ "${bin_dest_version}" != "${REQUIRED}" ]; then
|
|
||||||
echo "Expected ${REQUIRED} via bin_dest, but got ${bin_dest_version}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: 'Test: install in a fresh project'
|
|
||||||
run: |
|
|
||||||
mkdir /tmp/test-project
|
|
||||||
cd /tmp/test-project
|
|
||||||
pnpm init
|
|
||||||
pnpm add is-odd
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
manifest_pin:
|
|
||||||
# Folds the old test_package_manager_field, test_dev_engines, and
|
|
||||||
# test_dev_engines_on_fail_error jobs. The action's manifest handling is
|
|
||||||
# OS-independent, so ubuntu-only is sufficient.
|
|
||||||
name: 'Manifest pin: ${{ matrix.label }}'
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- label: 'packageManager pnpm@9.15.5 (#227)'
|
|
||||||
manifest: '{"packageManager":"pnpm@9.15.5"}'
|
|
||||||
version: '9.15.5'
|
|
||||||
- label: 'packageManager pnpm@10.33.0'
|
|
||||||
manifest: '{"packageManager":"pnpm@10.33.0"}'
|
|
||||||
version: '10.33.0'
|
|
||||||
- label: 'devEngines onFail=download, exact'
|
|
||||||
manifest: '{"devEngines":{"packageManager":{"name":"pnpm","version":"9.15.5","onFail":"download"}}}'
|
|
||||||
version: '9.15.5'
|
|
||||||
- label: 'devEngines onFail=download, range'
|
|
||||||
manifest: '{"devEngines":{"packageManager":{"name":"pnpm","version":">=9.15.0","onFail":"download"}}}'
|
|
||||||
version: '>=9.15.0'
|
|
||||||
- label: 'devEngines onFail=error, exact (#252)'
|
|
||||||
manifest: '{"devEngines":{"packageManager":{"name":"pnpm","version":"9.15.5","onFail":"error"}}}'
|
|
||||||
version: '9.15.5'
|
|
||||||
- label: 'devEngines onFail=error, range (#252)'
|
|
||||||
manifest: '{"devEngines":{"packageManager":{"name":"pnpm","version":">=9.15.0","onFail":"error"}}}'
|
|
||||||
version: '>=9.15.0'
|
|
||||||
- label: 'explicit version: pnpm_config_pm_on_fail not exported'
|
|
||||||
# Regression guard for the af8e203 scope fix: when the user passes an
|
|
||||||
# explicit `version:` input, the action must NOT export
|
|
||||||
# pnpm_config_pm_on_fail=download, so the user's strict onFail policy
|
|
||||||
# is preserved. Asserted directly on the env var rather than pnpm
|
|
||||||
# runtime behavior — different pnpm majors read devEngines
|
|
||||||
# differently (v10 ignores it, v11+ honors it).
|
|
||||||
manifest: '{"devEngines":{"packageManager":{"name":"pnpm","version":"9.15.5","onFail":"error"}}}'
|
|
||||||
explicit_version: '10.33.0'
|
|
||||||
expect_pm_on_fail_unset: true
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
||||||
|
|
||||||
- name: Set up package.json
|
|
||||||
run: echo '${{ matrix.manifest }}' > package.json
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Run the action
|
- name: Run the action
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
version: ${{ matrix.explicit_version }}
|
version: 9.15.5
|
||||||
|
|
||||||
- name: 'Test: pnpm reports the pinned version'
|
- name: 'Test: which'
|
||||||
if: ${{ !matrix.expect_pm_on_fail_unset }}
|
run: which pnpm; which pnpx
|
||||||
env:
|
|
||||||
REQUIRED: ${{ matrix.version }}
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
actual="$(pnpm --version)"
|
|
||||||
echo "pnpm version: ${actual}"
|
|
||||||
if [ "${REQUIRED}" = ">=9.15.0" ]; then
|
|
||||||
min="9.15.0"
|
|
||||||
if [ "$(printf '%s\n' "${min}" "${actual}" | sort -V | head -n1)" != "${min}" ]; then
|
|
||||||
echo "Expected pnpm version >= ${min}, but got ${actual}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [ "${actual}" != "${REQUIRED}" ]; then
|
|
||||||
echo "Expected pnpm version ${REQUIRED}, but got ${actual}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: 'Test: pnpm_config_pm_on_fail not exported (explicit version preserves strict policy)'
|
- name: 'Test: install'
|
||||||
if: ${{ matrix.expect_pm_on_fail_unset }}
|
run: pnpm install
|
||||||
run: |
|
|
||||||
if [ -n "${pnpm_config_pm_on_fail:-}" ]; then
|
|
||||||
echo "Expected pnpm_config_pm_on_fail to be unset, but got: '${pnpm_config_pm_on_fail}'"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "pnpm_config_pm_on_fail is unset, as expected"
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
standalone:
|
test_dest:
|
||||||
name: Standalone mode
|
name: Test with dest
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
pnpm:
|
||||||
|
- 9.15.5
|
||||||
|
os:
|
||||||
|
- ubuntu-latest
|
||||||
|
- macos-latest
|
||||||
|
- windows-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
||||||
|
|
||||||
|
- name: Run the action
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
version: 9.15.5
|
||||||
|
dest: ~/test/pnpm
|
||||||
|
|
||||||
|
- name: 'Test: which'
|
||||||
|
run: which pnpm && which pnpx
|
||||||
|
|
||||||
|
- name: 'Test: install'
|
||||||
|
run: pnpm install
|
||||||
|
|
||||||
|
test_standalone:
|
||||||
|
name: Test with standalone
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
# macos is excluded from this test because node 12 is no longer available on this platform
|
||||||
|
- ubuntu-latest
|
||||||
|
- windows-latest
|
||||||
|
|
||||||
|
standalone:
|
||||||
|
- true
|
||||||
|
- false
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
||||||
@@ -177,130 +89,59 @@ jobs:
|
|||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
version: 9.15.0
|
version: 9.15.0
|
||||||
standalone: true
|
standalone: ${{ matrix.standalone }}
|
||||||
|
|
||||||
- name: 'Test: pnpm works'
|
- name: install Node.js
|
||||||
run: |
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
set -e
|
|
||||||
which pnpm
|
|
||||||
actual="$(pnpm --version)"
|
|
||||||
if [ "${actual}" != "9.15.0" ]; then
|
|
||||||
echo "Expected 9.15.0, got ${actual}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
mkdir /tmp/test-standalone
|
|
||||||
cd /tmp/test-standalone
|
|
||||||
pnpm init
|
|
||||||
pnpm add is-odd
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
standalone_windows_self_update:
|
|
||||||
# Regression guard for the patchPnpmEnv PATH-shadow bug. When
|
|
||||||
# standalone: true on Windows AND the requested pnpm differs from the
|
|
||||||
# bootstrap, the previous patchPnpmEnv prepended node_modules/.bin to
|
|
||||||
# PATH; that directory contains an npm-created pnpm.cmd shim pointing
|
|
||||||
# at the BOOTSTRAP pnpm, which shadowed the self-updated pnpm at
|
|
||||||
# $PNPM_HOME/bin and caused `pnpm install` inside the action to run
|
|
||||||
# under the bootstrap version. Exercising a newer-pnpm-only flag
|
|
||||||
# (`--no-runtime`, added in 11.1.0) makes the regression assertable:
|
|
||||||
# if the bootstrap (11.0.4) handles the install, it errors with
|
|
||||||
# "Unknown option: 'runtime'".
|
|
||||||
name: 'Standalone Windows self-update (PATH regression)'
|
|
||||||
runs-on: windows-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
||||||
|
|
||||||
- name: Set up package.json with a minimal manifest
|
|
||||||
# run_install needs a manifest to install against. Removing the
|
|
||||||
# repo's existing pnpm-lock.yaml avoids frozen-lockfile mismatch.
|
|
||||||
run: |
|
|
||||||
rm -f pnpm-lock.yaml
|
|
||||||
echo '{"name":"sw","private":true,"packageManager":"pnpm@11.1.0"}' > package.json
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Run the action
|
|
||||||
uses: ./
|
|
||||||
with:
|
with:
|
||||||
version: 11.1.0
|
# pnpm@7.0.0 is not compatible with Node.js 12
|
||||||
standalone: true
|
node-version: 12.22.12
|
||||||
run_install: |
|
|
||||||
args: ['--no-runtime']
|
|
||||||
|
|
||||||
- name: 'Test: pnpm install completed under the self-updated pnpm'
|
- name: 'Test: which (pnpm)'
|
||||||
# If the bug recurs, the previous step's run_install will have failed
|
run: which pnpm
|
||||||
# the job with "Unknown option: 'runtime'", so reaching this step
|
|
||||||
# implies success. Still verify the version on PATH matches request.
|
- name: 'Test: which (pnpx)'
|
||||||
env:
|
if: matrix.standalone == false
|
||||||
REQUIRED: '11.1.0'
|
run: which pnpx
|
||||||
run: |
|
|
||||||
set -e
|
- name: 'Test: install when standalone is true'
|
||||||
actual="$(pnpm --version)"
|
if: matrix.standalone
|
||||||
echo "pnpm --version: ${actual}"
|
run: pnpm install
|
||||||
if [ "${actual}" != "${REQUIRED}" ]; then
|
|
||||||
echo "Expected pnpm ${REQUIRED}, got ${actual}"
|
- name: 'Test: install when standalone is false'
|
||||||
exit 1
|
if: matrix.standalone == false
|
||||||
fi
|
# Since the default shell on windows runner is pwsh, we specify bash explicitly
|
||||||
shell: bash
|
shell: bash
|
||||||
|
run: |
|
||||||
|
if pnpm install; then
|
||||||
|
echo "pnpm install should fail"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "pnpm install failed as expected"
|
||||||
|
fi
|
||||||
|
|
||||||
cache_store_path:
|
test_run_install:
|
||||||
# Regression guard for #233. When package.json pins a pnpm major that
|
name: 'Test with run_install (${{ matrix.run_install.name }}, ${{ matrix.os }})'
|
||||||
# differs from the bootstrap pnpm's major, the bootstrap reports its
|
|
||||||
# own STORE_VERSION from `pnpm store path` (the `store` command skips
|
|
||||||
# pnpm's auto-switch). The user's actual `pnpm install` runs under the
|
|
||||||
# pinned version and writes to a different STORE_VERSION, so the post
|
|
||||||
# step's saveCache then fails with "Path Validation Error". The fix is
|
|
||||||
# to self-update the bootstrap to the pinned version up front.
|
|
||||||
name: 'Cache store path matches install (#233): ${{ matrix.label }}'
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- label: 'packageManager pnpm@10.33.0'
|
|
||||||
manifest: '{"packageManager":"pnpm@10.33.0","dependencies":{"is-odd":"3.0.1"}}'
|
|
||||||
- label: 'devEngines exact pnpm@10.33.0'
|
|
||||||
manifest: '{"devEngines":{"packageManager":{"name":"pnpm","version":"10.33.0"}},"dependencies":{"is-odd":"3.0.1"}}'
|
|
||||||
- label: 'devEngines range >=10 <11'
|
|
||||||
manifest: '{"devEngines":{"packageManager":{"name":"pnpm","version":">=10 <11"}},"dependencies":{"is-odd":"3.0.1"}}'
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
||||||
|
|
||||||
- name: Set up package.json
|
|
||||||
run: echo '${{ matrix.manifest }}' > package.json
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- id: pnpm
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
cache: true
|
|
||||||
run_install: |
|
|
||||||
- args: [--no-frozen-lockfile]
|
|
||||||
|
|
||||||
- name: 'Test: store path computed by the action exists on disk'
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
actual="$(pnpm store path --silent)"
|
|
||||||
echo "pnpm store path: ${actual}"
|
|
||||||
if [ ! -d "${actual}" ]; then
|
|
||||||
echo "Expected store path to exist on disk; cache save would fail"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
run_install:
|
|
||||||
name: 'run_install (${{ matrix.run_install.name }})'
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
|
pnpm:
|
||||||
|
- 9.15.5
|
||||||
|
os:
|
||||||
|
- ubuntu-latest
|
||||||
|
- macos-latest
|
||||||
|
- windows-latest
|
||||||
run_install:
|
run_install:
|
||||||
- name: 'null'
|
- name: 'null'
|
||||||
value: 'null'
|
value: 'null'
|
||||||
|
- name: 'empty object'
|
||||||
|
value: '{}'
|
||||||
|
- name: 'recursive'
|
||||||
|
value: |
|
||||||
|
recursive: true
|
||||||
- name: 'global'
|
- name: 'global'
|
||||||
value: |
|
value: |
|
||||||
args:
|
args:
|
||||||
@@ -308,6 +149,15 @@ jobs:
|
|||||||
- --global-dir=./pnpm-global
|
- --global-dir=./pnpm-global
|
||||||
- npm
|
- npm
|
||||||
- yarn
|
- yarn
|
||||||
|
- name: 'array'
|
||||||
|
value: |
|
||||||
|
- {}
|
||||||
|
- recursive: true
|
||||||
|
- args:
|
||||||
|
- --global
|
||||||
|
- --global-dir=./pnpm-global
|
||||||
|
- npm
|
||||||
|
- yarn
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
||||||
@@ -318,72 +168,8 @@ jobs:
|
|||||||
version: 9.15.5
|
version: 9.15.5
|
||||||
run_install: ${{ matrix.run_install.value }}
|
run_install: ${{ matrix.run_install.value }}
|
||||||
|
|
||||||
- name: 'Test: pnpm works'
|
- name: 'Test: which'
|
||||||
run: |
|
run: which pnpm; which pnpx
|
||||||
set -e
|
|
||||||
which pnpm
|
|
||||||
which pnpx
|
|
||||||
actual="$(pnpm --version)"
|
|
||||||
if [ "${actual}" != "9.15.5" ]; then
|
|
||||||
echo "Expected 9.15.5, got ${actual}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
cache_lockfile_verification:
|
- name: 'Test: install'
|
||||||
# The action caches pnpm's lockfile verification log, which lives in
|
run: pnpm install
|
||||||
# `cacheDir` — a directory pnpm resolves per platform and does not print.
|
|
||||||
# Guard the action's copy of that default against pnpm's own.
|
|
||||||
name: 'Lockfile verification cache (${{ matrix.os }}, cache=${{ matrix.cache }})'
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
# The log is cached independently of the store, so the store-less
|
|
||||||
# configuration has to reach it too.
|
|
||||||
- os: ubuntu-latest
|
|
||||||
cache: false
|
|
||||||
- os: ubuntu-latest
|
|
||||||
cache: true
|
|
||||||
- os: macos-latest
|
|
||||||
cache: true
|
|
||||||
- os: windows-latest
|
|
||||||
cache: true
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
||||||
|
|
||||||
- name: Set up a project with a supply-chain policy
|
|
||||||
# A one-minute floor activates the verification without holding back
|
|
||||||
# any version the install resolves.
|
|
||||||
run: |
|
|
||||||
echo '{"dependencies":{"is-odd":"3.0.1"}}' > package.json
|
|
||||||
printf 'packages:\n - .\nminimumReleaseAge: 1\n' > pnpm-workspace.yaml
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- uses: ./
|
|
||||||
with:
|
|
||||||
version: '12.0.0-rc.4'
|
|
||||||
cache: ${{ matrix.cache }}
|
|
||||||
run_install: |
|
|
||||||
- args: [--no-frozen-lockfile]
|
|
||||||
|
|
||||||
- name: 'Test: pnpm wrote the verification log where the action looks for it'
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
case "$RUNNER_OS" in
|
|
||||||
Linux) cacheDir="${XDG_CACHE_HOME:-$HOME/.cache}/pnpm" ;;
|
|
||||||
macOS) cacheDir="$HOME/Library/Caches/pnpm" ;;
|
|
||||||
Windows) cacheDir="$(cygpath -u "$LOCALAPPDATA")/pnpm-cache" ;;
|
|
||||||
*) echo "Unexpected RUNNER_OS: $RUNNER_OS"; exit 1 ;;
|
|
||||||
esac
|
|
||||||
echo "Expecting the verification log in ${cacheDir}"
|
|
||||||
if [ ! -f "${cacheDir}/lockfile-verified.jsonl" ]; then
|
|
||||||
echo "No lockfile-verified.jsonl there; the action would cache nothing"
|
|
||||||
ls -la "${cacheDir}" || true
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
shell: bash
|
|
||||||
|
|||||||
+2
-1
@@ -2,6 +2,8 @@ node_modules
|
|||||||
*.log
|
*.log
|
||||||
/dist/*
|
/dist/*
|
||||||
!/dist/index.js
|
!/dist/index.js
|
||||||
|
!/dist/pnpm.cjs
|
||||||
|
!/dist/worker.js
|
||||||
tmp
|
tmp
|
||||||
temp
|
temp
|
||||||
*.tmp
|
*.tmp
|
||||||
@@ -9,4 +11,3 @@ temp
|
|||||||
tmp.*
|
tmp.*
|
||||||
temp.*
|
temp.*
|
||||||
.pnpm-store
|
.pnpm-store
|
||||||
.claude
|
|
||||||
|
|||||||
@@ -1,60 +1,10 @@
|
|||||||
> [!IMPORTANT]
|
|
||||||
> **This action has a successor: [`pnpm/setup`](https://github.com/pnpm/setup).**
|
|
||||||
>
|
|
||||||
> For pnpm v11 and newer, use [`pnpm/setup`](https://github.com/pnpm/setup) instead. It downloads pnpm's self-contained release binary (no Node.js or npm required) and can install a JavaScript runtime (Node.js, Bun, or Deno) in the same step, replacing `actions/setup-node`.
|
|
||||||
>
|
|
||||||
> `pnpm/action-setup` remains the action to use for installing pnpm v10 and older. See [Migrating to pnpm/setup](#migrating-to-pnpmsetup) below.
|
|
||||||
|
|
||||||
# Setup pnpm
|
|
||||||
|
|
||||||
Install pnpm package manager.
|
|
||||||
|
|
||||||
> ## :warning: Upgrade from v2!
|
> ## :warning: Upgrade from v2!
|
||||||
>
|
>
|
||||||
> The v2 version of this action [has stopped working](https://github.com/pnpm/action-setup/issues/135) with newer Node.js versions. Please, upgrade to the latest version to fix any issues.
|
> The v2 version of this action [has stopped working](https://github.com/pnpm/action-setup/issues/135) with newer Node.js versions. Please, upgrade to the latest version to fix any issues.
|
||||||
|
|
||||||
## Migrating to pnpm/setup
|
# Setup pnpm
|
||||||
|
|
||||||
[`pnpm/setup`](https://github.com/pnpm/setup) installs pnpm v11+ as a native standalone executable and can install Node.js, Bun, or Deno in the same step, so a typical workflow no longer needs `actions/setup-node` or an explicit `pnpm install` step:
|
Install pnpm package manager.
|
||||||
|
|
||||||
```yaml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
|
|
||||||
# Before:
|
|
||||||
# - uses: pnpm/action-setup@v6
|
|
||||||
# with:
|
|
||||||
# version: 10
|
|
||||||
# cache: true
|
|
||||||
# - uses: actions/setup-node@v4
|
|
||||||
# with:
|
|
||||||
# node-version: 22
|
|
||||||
# - run: pnpm install
|
|
||||||
|
|
||||||
# After:
|
|
||||||
- uses: pnpm/setup@v1
|
|
||||||
with:
|
|
||||||
version: 11
|
|
||||||
runtime: node@22
|
|
||||||
cache: true
|
|
||||||
```
|
|
||||||
|
|
||||||
The `version` input can be omitted only when `packageManager` (or `devEngines.packageManager`) in `package.json` declares pnpm v11 or newer; otherwise keep it explicit, since `pnpm/setup` requires pnpm v11+.
|
|
||||||
|
|
||||||
Input and output changes:
|
|
||||||
|
|
||||||
| `pnpm/action-setup` | `pnpm/setup` | Notes |
|
|
||||||
| ------------------- | ------------ | ----- |
|
|
||||||
| `version` | `version` | Must resolve to pnpm v11 or newer. As before, it can be omitted when `packageManager` (or `devEngines.packageManager`) is set in `package.json`. |
|
|
||||||
| `dest` | `dest` | Unchanged. |
|
|
||||||
| `run_install` | `install` | `pnpm/setup` runs `pnpm install` automatically when a `package.json` is present (`install: true` by default); set `install: false` to skip it. The object/array form (`recursive`, `cwd`, `args`) is not supported — run those commands in separate steps. |
|
|
||||||
| `cache` | `cache` | Unchanged. |
|
|
||||||
| `cache_dependency_path` | `cache-dependency-path` | Renamed to kebab-case. |
|
|
||||||
| `package_json_file` | `package-json-file` | Renamed to kebab-case. |
|
|
||||||
| `standalone` | removed | `pnpm/setup` always installs the standalone native executable. |
|
|
||||||
| n/a | `runtime` | New: installs Node.js, Bun, or Deno (e.g. `node@22`, `bun@latest`, `deno@2`), or reads `devEngines.runtime` from `package.json`. |
|
|
||||||
| n/a | `token` | New: GitHub token for release lookup; defaults to `${{ github.token }}` and rarely needs to be set. |
|
|
||||||
| `bin_dest` (output) | `bin-dest` (output) | Renamed to kebab-case. New outputs `runtime-name` and `runtime-version` describe the installed runtime. |
|
|
||||||
|
|
||||||
## Inputs
|
## Inputs
|
||||||
|
|
||||||
@@ -62,9 +12,9 @@ Input and output changes:
|
|||||||
|
|
||||||
Version of pnpm to install.
|
Version of pnpm to install.
|
||||||
|
|
||||||
**Optional** when there is a [`packageManager` or `devEngines.packageManager` field in the `package.json`](https://nodejs.org/api/corepack.html).
|
**Optional** when there is a [`packageManager` field in the `package.json`](https://nodejs.org/api/corepack.html).
|
||||||
|
|
||||||
otherwise, this field is **required** It supports npm versioning scheme, it could be an exact version (such as `10.9.8`), or a version range (such as `10`, `10.x.x`, `10.9.x`, `^10.9.8`, `*`, etc.), or `latest`.
|
otherwise, this field is **required** It supports npm versioning scheme, it could be an exact version (such as `6.24.1`), or a version range (such as `6`, `6.x.x`, `6.24.x`, `^6.24.1`, `*`, etc.), or `latest`.
|
||||||
|
|
||||||
### `dest`
|
### `dest`
|
||||||
|
|
||||||
@@ -94,15 +44,15 @@ If `run_install` is a YAML string representation of either an object or an array
|
|||||||
|
|
||||||
### `cache`
|
### `cache`
|
||||||
|
|
||||||
**Optional** (_type:_ `boolean`, _default:_ `false`) Whether to cache the pnpm store directory, keyed on the lockfile's content hash. On pnpm v11 and newer, the results of pnpm's lockfile verification are cached regardless of this input — see [Lockfile verification cache](#lockfile-verification-cache).
|
**Optional** (_type:_ `boolean`, _default:_ `false`) Whether to cache the pnpm store directory.
|
||||||
|
|
||||||
### `cache_dependency_path`
|
### `cache_dependency_path`
|
||||||
|
|
||||||
**Optional** (_type:_ `string`, _default:_ `pnpm-lock.yaml`) File path to the pnpm lockfile, whose contents hash will be used as a cache key. Accepts multiple paths delimited by newlines.
|
**Optional** (_type:_ `string|string[]`, _default:_ `pnpm-lock.yaml`) File path to the pnpm lockfile, which contents hash will be used as a cache key.
|
||||||
|
|
||||||
### `package_json_file`
|
### `package_json_file`
|
||||||
|
|
||||||
**Optional** (_type:_ `string`, _default:_ `package.json`) File path to the `package.json`/[`package.yaml`](https://github.com/pnpm/pnpm/pull/1799) to read `packageManager` or `devEngines.packageManager` configuration.
|
**Optional** (_type:_ `string`, _default:_ `package.json`) File path to the `package.json`/[`package.yaml`](https://github.com/pnpm/pnpm/pull/1799) to read "packageManager" configuration.
|
||||||
|
|
||||||
### `standalone`
|
### `standalone`
|
||||||
|
|
||||||
@@ -124,7 +74,7 @@ Location of `pnpm` and `pnpx` command.
|
|||||||
|
|
||||||
### Install only pnpm without `packageManager`
|
### Install only pnpm without `packageManager`
|
||||||
|
|
||||||
This works when the repo either doesn't have a `package.json` or has a `package.json` but it doesn't specify `packageManager` or `devEngines.packageManager`.
|
This works when the repo either doesn't have a `package.json` or has a `package.json` but it doesn't specify `packageManager`.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
on:
|
on:
|
||||||
@@ -136,14 +86,14 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: pnpm/action-setup@v6
|
- uses: pnpm/action-setup@v4
|
||||||
with:
|
with:
|
||||||
version: 10
|
version: 10
|
||||||
```
|
```
|
||||||
|
|
||||||
### Install only pnpm with `packageManager`
|
### Install only pnpm with `packageManager`
|
||||||
|
|
||||||
Omit `version` input to use the version in the [`packageManager` or `devEngines.packageManager` field in the `package.json`](https://nodejs.org/api/corepack.html).
|
Omit `version` input to use the version in the [`packageManager` field in the `package.json`](https://nodejs.org/api/corepack.html).
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
on:
|
on:
|
||||||
@@ -155,7 +105,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: pnpm/action-setup@v6
|
- uses: pnpm/action-setup@v4
|
||||||
```
|
```
|
||||||
|
|
||||||
### Install pnpm and a few npm packages
|
### Install pnpm and a few npm packages
|
||||||
@@ -170,9 +120,9 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v6
|
- uses: pnpm/action-setup@v4
|
||||||
with:
|
with:
|
||||||
version: 10
|
version: 10
|
||||||
run_install: |
|
run_install: |
|
||||||
@@ -194,9 +144,9 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v6
|
- uses: pnpm/action-setup@v4
|
||||||
name: Install pnpm
|
name: Install pnpm
|
||||||
with:
|
with:
|
||||||
version: 10
|
version: 10
|
||||||
@@ -208,55 +158,9 @@ jobs:
|
|||||||
|
|
||||||
**Note:** You don't need to run `pnpm store prune` at the end; post-action has already taken care of that.
|
**Note:** You don't need to run `pnpm store prune` at the end; post-action has already taken care of that.
|
||||||
|
|
||||||
### Lockfile verification cache
|
|
||||||
|
|
||||||
pnpm v11 and newer check every lockfile entry before installing it — that each entry pins an integrity hash, that a pinned tarball URL matches the registry's own metadata, and, where configured, your `minimumReleaseAge` and `trustPolicy` policies. The verdict is memoized in a sub-kilobyte file, so an unchanged lockfile is not re-checked against the registry.
|
|
||||||
|
|
||||||
The action restores and saves that file on every run, independently of the `cache` input, because a job that starts without it pays for the check every time. On a repository with ~2000 lockfile entries and a warm store:
|
|
||||||
|
|
||||||
| | without the log | with it |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `minimumReleaseAge` + `trustPolicy` | 13.5s | 1.5s |
|
|
||||||
| no policies configured | 6.7s | 1.6s |
|
|
||||||
|
|
||||||
Reusing a verdict is not a weaker check: pnpm re-verifies whenever the lockfile content changes, and whenever the recorded policy is looser than the one now configured.
|
|
||||||
|
|
||||||
The log is uploaded as soon as the install that produced it finishes, not at the end of the job, so nothing the job runs afterwards — its tests, its build, any later step — can alter what other jobs restore. Dependency lifecycle scripts are the exception, since they run inside the install itself, ahead of the upload: pnpm refuses to run them unless the repository allow-lists the package through `allowBuilds`, and a package on that list can already run code in the job.
|
|
||||||
|
|
||||||
Before uploading, the action checks that the log grew the way an install grows it: every record that predated the install still there, and no more new records than installs it ran. A dependency's script that slips an extra record in is caught by that, and the log is not cached — the next job re-verifies, which costs seconds and nothing else.
|
|
||||||
|
|
||||||
A job that installs in a step of its own rather than through this action is saved at the end of the job instead, since that is the first moment the log is known to be complete. The record count cannot be bounded there, so only the "nothing disappeared" half of the check applies.
|
|
||||||
|
|
||||||
### Cache dependencies from multiple lockfiles
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
on:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
cache-and-install-multiple:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v6
|
|
||||||
with:
|
|
||||||
version: 10
|
|
||||||
cache: true
|
|
||||||
cache_dependency_path: |
|
|
||||||
one/pnpm-lock.yaml
|
|
||||||
two/pnpm-lock.yaml
|
|
||||||
run_install: |
|
|
||||||
- cwd: one
|
|
||||||
- cwd: two
|
|
||||||
```
|
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
This action does not set up Node.js. Use [actions/setup-node](https://github.com/actions/setup-node) yourself. If you are on pnpm v11 or newer, [`pnpm/setup`](https://github.com/pnpm/setup) can install pnpm and Node.js in a single step.
|
This action does not setup Node.js for you, use [actions/setup-node](https://github.com/actions/setup-node) yourself.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
+2
-5
@@ -16,14 +16,11 @@ inputs:
|
|||||||
required: false
|
required: false
|
||||||
default: 'null'
|
default: 'null'
|
||||||
cache:
|
cache:
|
||||||
description: |
|
description: Whether to cache the pnpm store directory
|
||||||
Whether to cache the pnpm store directory, keyed on the lockfile's
|
|
||||||
content hash. On pnpm v11 and newer, the results of pnpm's lockfile
|
|
||||||
verification are cached either way — see the README.
|
|
||||||
required: false
|
required: false
|
||||||
default: 'false'
|
default: 'false'
|
||||||
cache_dependency_path:
|
cache_dependency_path:
|
||||||
description: File path to the pnpm lockfile, whose contents hash will be used as a cache key. Accepts multiple paths delimited by newlines.
|
description: File path to the pnpm lockfile, which contents hash will be used as a cache key
|
||||||
required: false
|
required: false
|
||||||
default: 'pnpm-lock.yaml'
|
default: 'pnpm-lock.yaml'
|
||||||
package_json_file:
|
package_json_file:
|
||||||
|
|||||||
Vendored
+10
-290
File diff suppressed because one or more lines are too long
Vendored
+220780
File diff suppressed because one or more lines are too long
Vendored
+16625
File diff suppressed because it is too large
Load Diff
+5
-4
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:bundle": "esbuild src/index.ts --bundle --platform=node --target=node24 --format=cjs --minify --outfile=dist/index.js --loader:.json=json",
|
"build:ncc": "ncc build --minify --no-source-map-register --no-cache dist/tsc/index.js --out dist/",
|
||||||
"build": "pnpm run build:bundle",
|
"build": "tsc && pnpm run build:ncc",
|
||||||
"start": "pnpm run build && sh ./run.sh",
|
"start": "pnpm run build && sh ./run.sh",
|
||||||
"update-bootstrap": "node scripts/update-bootstrap.mjs"
|
"update-pnpm-dist": "pnpm install && cp ./node_modules/pnpm/dist/pnpm.cjs ./dist/pnpm.cjs && cp ./node_modules/pnpm/dist/worker.js ./dist/worker.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/cache": "^4.1.0",
|
"@actions/cache": "^4.1.0",
|
||||||
@@ -18,7 +18,8 @@
|
|||||||
"zod": "^3.22.4"
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"esbuild": "^0.27.4",
|
"@vercel/ncc": "^0.38.1",
|
||||||
|
"pnpm": "^8.14.3",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+19
-271
@@ -36,9 +36,12 @@ importers:
|
|||||||
specifier: ^3.22.4
|
specifier: ^3.22.4
|
||||||
version: 3.24.1
|
version: 3.24.1
|
||||||
devDependencies:
|
devDependencies:
|
||||||
esbuild:
|
'@vercel/ncc':
|
||||||
specifier: ^0.27.4
|
specifier: ^0.38.1
|
||||||
version: 0.27.4
|
version: 0.38.3
|
||||||
|
pnpm:
|
||||||
|
specifier: ^8.14.3
|
||||||
|
version: 8.15.9
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.3.3
|
specifier: ^5.3.3
|
||||||
version: 5.7.3
|
version: 5.7.3
|
||||||
@@ -121,162 +124,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-IQjj9RIzAKatmNca3D6bT0qJ+Pkox1WZGOg2esJF2YLHb45pQKOwGPIAV+w3rfgkj7zV3RMxpn/c6iftzSOZJQ==}
|
resolution: {integrity: sha512-IQjj9RIzAKatmNca3D6bT0qJ+Pkox1WZGOg2esJF2YLHb45pQKOwGPIAV+w3rfgkj7zV3RMxpn/c6iftzSOZJQ==}
|
||||||
engines: {node: '>=18.0.0'}
|
engines: {node: '>=18.0.0'}
|
||||||
|
|
||||||
'@esbuild/aix-ppc64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [ppc64]
|
|
||||||
os: [aix]
|
|
||||||
|
|
||||||
'@esbuild/android-arm64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [android]
|
|
||||||
|
|
||||||
'@esbuild/android-arm@0.27.4':
|
|
||||||
resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [arm]
|
|
||||||
os: [android]
|
|
||||||
|
|
||||||
'@esbuild/android-x64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [android]
|
|
||||||
|
|
||||||
'@esbuild/darwin-arm64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [darwin]
|
|
||||||
|
|
||||||
'@esbuild/darwin-x64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [darwin]
|
|
||||||
|
|
||||||
'@esbuild/freebsd-arm64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [freebsd]
|
|
||||||
|
|
||||||
'@esbuild/freebsd-x64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [freebsd]
|
|
||||||
|
|
||||||
'@esbuild/linux-arm64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@esbuild/linux-arm@0.27.4':
|
|
||||||
resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [arm]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@esbuild/linux-ia32@0.27.4':
|
|
||||||
resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [ia32]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@esbuild/linux-loong64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [loong64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@esbuild/linux-mips64el@0.27.4':
|
|
||||||
resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [mips64el]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@esbuild/linux-ppc64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [ppc64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@esbuild/linux-riscv64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [riscv64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@esbuild/linux-s390x@0.27.4':
|
|
||||||
resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [s390x]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@esbuild/linux-x64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@esbuild/netbsd-arm64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [netbsd]
|
|
||||||
|
|
||||||
'@esbuild/netbsd-x64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [netbsd]
|
|
||||||
|
|
||||||
'@esbuild/openbsd-arm64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [openbsd]
|
|
||||||
|
|
||||||
'@esbuild/openbsd-x64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [openbsd]
|
|
||||||
|
|
||||||
'@esbuild/openharmony-arm64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [openharmony]
|
|
||||||
|
|
||||||
'@esbuild/sunos-x64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [sunos]
|
|
||||||
|
|
||||||
'@esbuild/win32-arm64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [win32]
|
|
||||||
|
|
||||||
'@esbuild/win32-ia32@0.27.4':
|
|
||||||
resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [ia32]
|
|
||||||
os: [win32]
|
|
||||||
|
|
||||||
'@esbuild/win32-x64@0.27.4':
|
|
||||||
resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [win32]
|
|
||||||
|
|
||||||
'@fastify/busboy@2.1.1':
|
'@fastify/busboy@2.1.1':
|
||||||
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
|
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
@@ -297,6 +144,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-sOx1PKSuFwnIl7z4RN0Ls7N9AQawmR9r66eI5rFCzLDIs8HTIYrIpH9QjYWoX0lkgGrkLxXhi4QnK7MizPRrIg==}
|
resolution: {integrity: sha512-sOx1PKSuFwnIl7z4RN0Ls7N9AQawmR9r66eI5rFCzLDIs8HTIYrIpH9QjYWoX0lkgGrkLxXhi4QnK7MizPRrIg==}
|
||||||
engines: {node: '>=20.0.0'}
|
engines: {node: '>=20.0.0'}
|
||||||
|
|
||||||
|
'@vercel/ncc@0.38.3':
|
||||||
|
resolution: {integrity: sha512-rnK6hJBS6mwc+Bkab+PGPs9OiS0i/3kdTO+CkI8V0/VrW3vmz7O2Pxjw/owOlmo6PKEIxRSeZKv/kuL9itnpYA==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
abort-controller@3.0.0:
|
abort-controller@3.0.0:
|
||||||
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
|
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
|
||||||
engines: {node: '>=6.5'}
|
engines: {node: '>=6.5'}
|
||||||
@@ -358,11 +209,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
|
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
esbuild@0.27.4:
|
|
||||||
resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
event-target-shim@5.0.1:
|
event-target-shim@5.0.1:
|
||||||
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@@ -453,6 +299,11 @@ packages:
|
|||||||
resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==}
|
resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
pnpm@8.15.9:
|
||||||
|
resolution: {integrity: sha512-SZQ0ydj90aJ5Tr9FUrOyXApjOrzuW7Fee13pDzL0e1E6ypjNXP0AHDHw20VLw4BO3M1XhQHkyik6aBYWa72fgQ==}
|
||||||
|
engines: {node: '>=16.14'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
safe-buffer@5.2.1:
|
safe-buffer@5.2.1:
|
||||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||||
|
|
||||||
@@ -678,84 +529,6 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@esbuild/aix-ppc64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/android-arm64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/android-arm@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/android-x64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/darwin-arm64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/darwin-x64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/freebsd-arm64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/freebsd-x64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/linux-arm64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/linux-arm@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/linux-ia32@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/linux-loong64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/linux-mips64el@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/linux-ppc64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/linux-riscv64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/linux-s390x@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/linux-x64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/netbsd-arm64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/netbsd-x64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/openbsd-arm64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/openbsd-x64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/openharmony-arm64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/sunos-x64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/win32-arm64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/win32-ia32@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@esbuild/win32-x64@0.27.4':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@fastify/busboy@2.1.1': {}
|
'@fastify/busboy@2.1.1': {}
|
||||||
|
|
||||||
'@protobuf-ts/runtime-rpc@2.11.1':
|
'@protobuf-ts/runtime-rpc@2.11.1':
|
||||||
@@ -778,6 +551,8 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
'@vercel/ncc@0.38.3': {}
|
||||||
|
|
||||||
abort-controller@3.0.0:
|
abort-controller@3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
event-target-shim: 5.0.1
|
event-target-shim: 5.0.1
|
||||||
@@ -831,35 +606,6 @@ snapshots:
|
|||||||
has-tostringtag: 1.0.2
|
has-tostringtag: 1.0.2
|
||||||
hasown: 2.0.2
|
hasown: 2.0.2
|
||||||
|
|
||||||
esbuild@0.27.4:
|
|
||||||
optionalDependencies:
|
|
||||||
'@esbuild/aix-ppc64': 0.27.4
|
|
||||||
'@esbuild/android-arm': 0.27.4
|
|
||||||
'@esbuild/android-arm64': 0.27.4
|
|
||||||
'@esbuild/android-x64': 0.27.4
|
|
||||||
'@esbuild/darwin-arm64': 0.27.4
|
|
||||||
'@esbuild/darwin-x64': 0.27.4
|
|
||||||
'@esbuild/freebsd-arm64': 0.27.4
|
|
||||||
'@esbuild/freebsd-x64': 0.27.4
|
|
||||||
'@esbuild/linux-arm': 0.27.4
|
|
||||||
'@esbuild/linux-arm64': 0.27.4
|
|
||||||
'@esbuild/linux-ia32': 0.27.4
|
|
||||||
'@esbuild/linux-loong64': 0.27.4
|
|
||||||
'@esbuild/linux-mips64el': 0.27.4
|
|
||||||
'@esbuild/linux-ppc64': 0.27.4
|
|
||||||
'@esbuild/linux-riscv64': 0.27.4
|
|
||||||
'@esbuild/linux-s390x': 0.27.4
|
|
||||||
'@esbuild/linux-x64': 0.27.4
|
|
||||||
'@esbuild/netbsd-arm64': 0.27.4
|
|
||||||
'@esbuild/netbsd-x64': 0.27.4
|
|
||||||
'@esbuild/openbsd-arm64': 0.27.4
|
|
||||||
'@esbuild/openbsd-x64': 0.27.4
|
|
||||||
'@esbuild/openharmony-arm64': 0.27.4
|
|
||||||
'@esbuild/sunos-x64': 0.27.4
|
|
||||||
'@esbuild/win32-arm64': 0.27.4
|
|
||||||
'@esbuild/win32-ia32': 0.27.4
|
|
||||||
'@esbuild/win32-x64': 0.27.4
|
|
||||||
|
|
||||||
event-target-shim@5.0.1: {}
|
event-target-shim@5.0.1: {}
|
||||||
|
|
||||||
events@3.3.0: {}
|
events@3.3.0: {}
|
||||||
@@ -951,6 +697,8 @@ snapshots:
|
|||||||
|
|
||||||
parse-passwd@1.0.0: {}
|
parse-passwd@1.0.0: {}
|
||||||
|
|
||||||
|
pnpm@8.15.9: {}
|
||||||
|
|
||||||
safe-buffer@5.2.1: {}
|
safe-buffer@5.2.1: {}
|
||||||
|
|
||||||
sax@1.4.1: {}
|
sax@1.4.1: {}
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
packages:
|
|
||||||
- '.'
|
|
||||||
allowBuilds:
|
|
||||||
esbuild: true
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
// Usage: node scripts/update-bootstrap.mjs [version]
|
|
||||||
// If version is omitted, fetches the latest next-11 tag from npm.
|
|
||||||
// Regenerates the bootstrap lockfiles used by action-setup to install pnpm via npm.
|
|
||||||
|
|
||||||
import { execSync } from 'child_process'
|
|
||||||
import { mkdtempSync, rmSync, readFileSync, writeFileSync } from 'fs'
|
|
||||||
import { join } from 'path'
|
|
||||||
import { tmpdir } from 'os'
|
|
||||||
|
|
||||||
const BOOTSTRAP_DIR = new URL('../src/install-pnpm/bootstrap/', import.meta.url).pathname
|
|
||||||
|
|
||||||
const version = process.argv[2] || resolveLatestVersion()
|
|
||||||
|
|
||||||
console.log(`Updating bootstrap lockfiles to pnpm@${version} ...`)
|
|
||||||
|
|
||||||
generateLock('pnpm-lock.json', { pnpm: version }, 'bootstrap-pnpm')
|
|
||||||
generateLock('exe-lock.json', { '@pnpm/exe': version }, 'bootstrap-exe')
|
|
||||||
|
|
||||||
console.log('Done!')
|
|
||||||
|
|
||||||
function resolveLatestVersion() {
|
|
||||||
const json = execSync('npm view @pnpm/exe dist-tags --json', { encoding: 'utf8' })
|
|
||||||
const tags = JSON.parse(json)
|
|
||||||
const version = tags['next-11'] || tags['latest']
|
|
||||||
if (!version) {
|
|
||||||
console.error('Could not determine latest pnpm version from npm dist-tags')
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
return version
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateLock(filename, dependencies, name) {
|
|
||||||
const tmp = mkdtempSync(join(tmpdir(), 'pnpm-bootstrap-'))
|
|
||||||
try {
|
|
||||||
writeFileSync(join(tmp, 'package.json'), JSON.stringify({ private: true, dependencies }))
|
|
||||||
execSync('npm install --package-lock-only --ignore-scripts', { cwd: tmp, stdio: 'pipe' })
|
|
||||||
const lock = readFileSync(join(tmp, 'package-lock.json'), 'utf8')
|
|
||||||
const parsed = JSON.parse(lock)
|
|
||||||
parsed.name = name
|
|
||||||
writeFileSync(join(BOOTSTRAP_DIR, filename), JSON.stringify(parsed, null, 2) + '\n')
|
|
||||||
console.log(` ${filename} -> ${Object.values(dependencies)[0]}@${version}`)
|
|
||||||
} finally {
|
|
||||||
rmSync(tmp, { recursive: true, force: true })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,10 +4,10 @@ import { Inputs } from '../inputs'
|
|||||||
import { runRestoreCache } from './run'
|
import { runRestoreCache } from './run'
|
||||||
|
|
||||||
export async function restoreCache(inputs: Inputs) {
|
export async function restoreCache(inputs: Inputs) {
|
||||||
|
if (!inputs.cache) return
|
||||||
|
|
||||||
if (!isFeatureAvailable()) {
|
if (!isFeatureAvailable()) {
|
||||||
if (inputs.cache) {
|
warning('Cache is not available, skipping cache restoration')
|
||||||
warning('Cache is not available, skipping cache restoration')
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,51 +4,23 @@ import { getExecOutput } from '@actions/exec'
|
|||||||
import { hashFiles } from '@actions/glob'
|
import { hashFiles } from '@actions/glob'
|
||||||
import os from 'os'
|
import os from 'os'
|
||||||
import { Inputs } from '../inputs'
|
import { Inputs } from '../inputs'
|
||||||
import { restoreVerificationCache } from '../lockfile-verification-cache'
|
|
||||||
import { removeWindowsExtendedPathPrefix } from '../windows-path'
|
|
||||||
|
|
||||||
export async function runRestoreCache(inputs: Inputs) {
|
export async function runRestoreCache(inputs: Inputs) {
|
||||||
const fileHash = await hashFiles(inputs.cacheDependencyPath)
|
|
||||||
if (!fileHash) {
|
|
||||||
// Both caches are keyed on the lockfile, so neither can be restored
|
|
||||||
// without one. Only the store cache was asked for by name.
|
|
||||||
if (inputs.cache) {
|
|
||||||
throw new Error('Some specified paths were not resolved, unable to cache dependencies.')
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restored whether or not the store is cached: the log is a fraction of a
|
|
||||||
// kilobyte, and without it pnpm re-checks every lockfile entry against the
|
|
||||||
// registry on each run — seconds even on a repository that configures no
|
|
||||||
// supply-chain policies.
|
|
||||||
await restoreVerificationCache(fileHash)
|
|
||||||
|
|
||||||
if (inputs.cache) {
|
|
||||||
await runRestoreStoreCache(fileHash)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function runRestoreStoreCache(fileHash: string) {
|
|
||||||
const cachePath = await getCacheDirectory()
|
const cachePath = await getCacheDirectory()
|
||||||
saveState('cache_path', cachePath)
|
saveState('cache_path', cachePath)
|
||||||
|
|
||||||
|
const fileHash = await hashFiles(inputs.cacheDependencyPath)
|
||||||
|
if (!fileHash) {
|
||||||
|
throw new Error('Some specified paths were not resolved, unable to cache dependencies.')
|
||||||
|
}
|
||||||
|
|
||||||
const primaryKey = `pnpm-cache-${process.env.RUNNER_OS}-${os.arch()}-${fileHash}`
|
const primaryKey = `pnpm-cache-${process.env.RUNNER_OS}-${os.arch()}-${fileHash}`
|
||||||
debug(`Primary key is ${primaryKey}`)
|
debug(`Primary key is ${primaryKey}`)
|
||||||
saveState('cache_primary_key', primaryKey)
|
saveState('cache_primary_key', primaryKey)
|
||||||
|
|
||||||
// We don't need to download everything again if only one dependency changed
|
let cacheKey = await restoreCache([cachePath], primaryKey)
|
||||||
// We can still re-use previous store to cache the rest of the unchanged dependencies
|
|
||||||
const restoreKeys = [
|
|
||||||
`pnpm-cache-${process.env.RUNNER_OS}-${os.arch()}-`
|
|
||||||
];
|
|
||||||
|
|
||||||
let cacheKey = await restoreCache([cachePath], primaryKey, restoreKeys)
|
setOutput('cache-hit', Boolean(cacheKey))
|
||||||
|
|
||||||
// A restore-key (prefix) match still restores an older store, but "cache-hit"
|
|
||||||
// must only report an exact primary-key match, so dependency installation
|
|
||||||
// is not skipped when the lockfile has changed.
|
|
||||||
setOutput('cache-hit', cacheKey === primaryKey)
|
|
||||||
|
|
||||||
if (!cacheKey) {
|
if (!cacheKey) {
|
||||||
info(`Cache is not found`)
|
info(`Cache is not found`)
|
||||||
@@ -61,7 +33,7 @@ async function runRestoreStoreCache(fileHash: string) {
|
|||||||
|
|
||||||
async function getCacheDirectory() {
|
async function getCacheDirectory() {
|
||||||
const { stdout } = await getExecOutput('pnpm store path --silent')
|
const { stdout } = await getExecOutput('pnpm store path --silent')
|
||||||
const cacheFolderPath = removeWindowsExtendedPathPrefix(stdout.trim())
|
const cacheFolderPath = stdout.trim()
|
||||||
debug(`Cache folder is set to "${cacheFolderPath}"`)
|
debug(`Cache folder is set to "${cacheFolderPath}"`)
|
||||||
return cacheFolderPath
|
return cacheFolderPath
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-16
@@ -3,41 +3,33 @@ import restoreCache from './cache-restore'
|
|||||||
import saveCache from './cache-save'
|
import saveCache from './cache-save'
|
||||||
import getInputs, { Inputs } from './inputs'
|
import getInputs, { Inputs } from './inputs'
|
||||||
import installPnpm from './install-pnpm'
|
import installPnpm from './install-pnpm'
|
||||||
import { saveVerificationCache } from './lockfile-verification-cache'
|
|
||||||
import setOutputs from './outputs'
|
import setOutputs from './outputs'
|
||||||
import pnpmInstall from './pnpm-install'
|
import pnpmInstall from './pnpm-install'
|
||||||
import pruneStore from './pnpm-store-prune'
|
import pruneStore from './pnpm-store-prune'
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
const inputs = getInputs()
|
||||||
|
|
||||||
if (getState('is_post') === 'true') {
|
if (getState('is_post') === 'true') {
|
||||||
await runPost()
|
await runPost(inputs)
|
||||||
} else {
|
} else {
|
||||||
await runMain()
|
await runMain(inputs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runMain() {
|
async function runMain(inputs: Inputs) {
|
||||||
const inputs = getInputs()
|
|
||||||
saveState('inputs', inputs)
|
|
||||||
saveState('is_post', 'true')
|
saveState('is_post', 'true')
|
||||||
|
|
||||||
const binDest = await installPnpm(inputs)
|
await installPnpm(inputs)
|
||||||
if (binDest === undefined) return
|
|
||||||
console.log('Installation Completed!')
|
console.log('Installation Completed!')
|
||||||
setOutputs(inputs, binDest)
|
setOutputs(inputs)
|
||||||
|
|
||||||
await restoreCache(inputs)
|
await restoreCache(inputs)
|
||||||
|
|
||||||
pnpmInstall(inputs)
|
pnpmInstall(inputs)
|
||||||
await saveVerificationCache(inputs.runInstall.length)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runPost() {
|
async function runPost(inputs: Inputs) {
|
||||||
const inputs = JSON.parse(getState('inputs')) as Inputs
|
|
||||||
// Covers a job that installs in a later step of its own; when this action
|
|
||||||
// installed, the log was already saved then. Runs before the prune because
|
|
||||||
// pnpm versions before pnpm/pnpm#13893 delete the log during one.
|
|
||||||
await saveVerificationCache()
|
|
||||||
pruneStore(inputs)
|
pruneStore(inputs)
|
||||||
await saveCache(inputs)
|
await saveCache(inputs)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,327 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "bootstrap-exe",
|
|
||||||
"lockfileVersion": 3,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"": {
|
|
||||||
"dependencies": {
|
|
||||||
"@pnpm/exe": "11.19.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@pnpm/exe": {
|
|
||||||
"version": "11.19.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@pnpm/exe/-/exe-11.19.0.tgz",
|
|
||||||
"integrity": "sha512-P1mw8BZaNkEpttlyzKsxTj7PVs94bMB4cQ8pJhgbrCTSBP7xCzKS3VlOwIInS7aS5by6KAbfO5Vs9yK/ekugrg==",
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@reflink/reflink": "0.1.19",
|
|
||||||
"detect-libc": "^2.1.2"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"pn": "pn",
|
|
||||||
"pnpm": "pnpm",
|
|
||||||
"pnpx": "pnpx",
|
|
||||||
"pnx": "pnx"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://opencollective.com/pnpm"
|
|
||||||
},
|
|
||||||
"optionalDependencies": {
|
|
||||||
"@pnpm/linux-arm64": "11.19.0",
|
|
||||||
"@pnpm/linux-x64": "11.19.0",
|
|
||||||
"@pnpm/linuxstatic-arm64": "11.19.0",
|
|
||||||
"@pnpm/linuxstatic-x64": "11.19.0",
|
|
||||||
"@pnpm/macos-arm64": "11.19.0",
|
|
||||||
"@pnpm/win-arm64": "11.19.0",
|
|
||||||
"@pnpm/win-x64": "11.19.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@pnpm/linux-arm64": {
|
|
||||||
"version": "11.19.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@pnpm/linux-arm64/-/linux-arm64-11.19.0.tgz",
|
|
||||||
"integrity": "sha512-c5AJqnsj0BMqMCOtctOzsCqyfY+afFe1kdM9F2FrNhYwtnQRMHoJy+51qfee4yuTPOVRyk3Yh1dwvyAadiznvA==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"funding": {
|
|
||||||
"url": "https://opencollective.com/pnpm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@pnpm/linux-x64": {
|
|
||||||
"version": "11.19.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@pnpm/linux-x64/-/linux-x64-11.19.0.tgz",
|
|
||||||
"integrity": "sha512-KOKpA9o75SvmRQgWO+EqEpQzJg1b9uHk5y61PAx90sSpdYtKDPua2eBXBglzv8YK1xM3DsYXFEf7Scs+3HeDsA==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"funding": {
|
|
||||||
"url": "https://opencollective.com/pnpm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@pnpm/linuxstatic-arm64": {
|
|
||||||
"version": "11.19.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@pnpm/linuxstatic-arm64/-/linuxstatic-arm64-11.19.0.tgz",
|
|
||||||
"integrity": "sha512-Ci9WxgCInZc3F43R6BfaHevi+dYqaI5CLi6421egFsK649eHvYPytvu+zABhTNlYGNJbD8j9w+AUYInz/TPsyQ==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"funding": {
|
|
||||||
"url": "https://opencollective.com/pnpm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@pnpm/linuxstatic-x64": {
|
|
||||||
"version": "11.19.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@pnpm/linuxstatic-x64/-/linuxstatic-x64-11.19.0.tgz",
|
|
||||||
"integrity": "sha512-GNMk96vNJ4uEWigekarjHofXNDFsTYRL0Mw2YlDkv/W+u0cn/UAVPHfd5aAfsf6Arel2ZQfxPUTXlpunFujWnA==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"funding": {
|
|
||||||
"url": "https://opencollective.com/pnpm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@pnpm/macos-arm64": {
|
|
||||||
"version": "11.19.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@pnpm/macos-arm64/-/macos-arm64-11.19.0.tgz",
|
|
||||||
"integrity": "sha512-I3Ee/GQlPxEOeBSzqxBNwcTHxVebjMiN2xLdTBS6OK2TAPzbWMIExjU5brxhr8rAk73p7mbv/a/2tFC/3gl6FA==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"darwin"
|
|
||||||
],
|
|
||||||
"funding": {
|
|
||||||
"url": "https://opencollective.com/pnpm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@pnpm/win-arm64": {
|
|
||||||
"version": "11.19.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@pnpm/win-arm64/-/win-arm64-11.19.0.tgz",
|
|
||||||
"integrity": "sha512-rOiWuJ9wjaFY9ZDVPGVjpvjIQHZNB72rioxvuyzDKJ7dqKQ97VF27a4rmOtjhMB5u83cdDGEJ+OY+H1+TP+frw==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"win32"
|
|
||||||
],
|
|
||||||
"funding": {
|
|
||||||
"url": "https://opencollective.com/pnpm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@pnpm/win-x64": {
|
|
||||||
"version": "11.19.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@pnpm/win-x64/-/win-x64-11.19.0.tgz",
|
|
||||||
"integrity": "sha512-l26XeTxoGxfU+mVcZ5jFdP9hNe5yrOlLPSkAlwwpXPI1iyyU4JUSxm6Jdyxu1UAU1FerD/BvLK2vrlR6d9ogag==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"win32"
|
|
||||||
],
|
|
||||||
"funding": {
|
|
||||||
"url": "https://opencollective.com/pnpm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@reflink/reflink": {
|
|
||||||
"version": "0.1.19",
|
|
||||||
"resolved": "https://registry.npmjs.org/@reflink/reflink/-/reflink-0.1.19.tgz",
|
|
||||||
"integrity": "sha512-DmCG8GzysnCZ15bres3N5AHCmwBwYgp0As6xjhQ47rAUTUXxJiK+lLUxaGsX3hd/30qUpVElh05PbGuxRPgJwA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
},
|
|
||||||
"optionalDependencies": {
|
|
||||||
"@reflink/reflink-darwin-arm64": "0.1.19",
|
|
||||||
"@reflink/reflink-darwin-x64": "0.1.19",
|
|
||||||
"@reflink/reflink-linux-arm64-gnu": "0.1.19",
|
|
||||||
"@reflink/reflink-linux-arm64-musl": "0.1.19",
|
|
||||||
"@reflink/reflink-linux-x64-gnu": "0.1.19",
|
|
||||||
"@reflink/reflink-linux-x64-musl": "0.1.19",
|
|
||||||
"@reflink/reflink-win32-arm64-msvc": "0.1.19",
|
|
||||||
"@reflink/reflink-win32-x64-msvc": "0.1.19"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@reflink/reflink-darwin-arm64": {
|
|
||||||
"version": "0.1.19",
|
|
||||||
"resolved": "https://registry.npmjs.org/@reflink/reflink-darwin-arm64/-/reflink-darwin-arm64-0.1.19.tgz",
|
|
||||||
"integrity": "sha512-ruy44Lpepdk1FqDz38vExBY/PVUsjxZA+chd9wozjUH9JjuDT/HEaQYA6wYN9mf041l0yLVar6BCZuWABJvHSA==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"darwin"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@reflink/reflink-darwin-x64": {
|
|
||||||
"version": "0.1.19",
|
|
||||||
"resolved": "https://registry.npmjs.org/@reflink/reflink-darwin-x64/-/reflink-darwin-x64-0.1.19.tgz",
|
|
||||||
"integrity": "sha512-By85MSWrMZa+c26TcnAy8SDk0sTUkYlNnwknSchkhHpGXOtjNDUOxJE9oByBnGbeuIE1PiQsxDG3Ud+IVV9yuA==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"darwin"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@reflink/reflink-linux-arm64-gnu": {
|
|
||||||
"version": "0.1.19",
|
|
||||||
"resolved": "https://registry.npmjs.org/@reflink/reflink-linux-arm64-gnu/-/reflink-linux-arm64-gnu-0.1.19.tgz",
|
|
||||||
"integrity": "sha512-7P+er8+rP9iNeN+bfmccM4hTAaLP6PQJPKWSA4iSk2bNvo6KU6RyPgYeHxXmzNKzPVRcypZQTpFgstHam6maVg==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@reflink/reflink-linux-arm64-musl": {
|
|
||||||
"version": "0.1.19",
|
|
||||||
"resolved": "https://registry.npmjs.org/@reflink/reflink-linux-arm64-musl/-/reflink-linux-arm64-musl-0.1.19.tgz",
|
|
||||||
"integrity": "sha512-37iO/Dp6m5DDaC2sf3zPtx/hl9FV3Xze4xoYidrxxS9bgP3S8ALroxRK6xBG/1TtfXKTvolvp+IjrUU6ujIGmA==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@reflink/reflink-linux-x64-gnu": {
|
|
||||||
"version": "0.1.19",
|
|
||||||
"resolved": "https://registry.npmjs.org/@reflink/reflink-linux-x64-gnu/-/reflink-linux-x64-gnu-0.1.19.tgz",
|
|
||||||
"integrity": "sha512-jbI8jvuYCaA3MVUdu8vLoLAFqC+iNMpiSuLbxlAgg7x3K5bsS8nOpTRnkLF7vISJ+rVR8W+7ThXlXlUQ93ulkw==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@reflink/reflink-linux-x64-musl": {
|
|
||||||
"version": "0.1.19",
|
|
||||||
"resolved": "https://registry.npmjs.org/@reflink/reflink-linux-x64-musl/-/reflink-linux-x64-musl-0.1.19.tgz",
|
|
||||||
"integrity": "sha512-e9FBWDe+lv7QKAwtKOt6A2W/fyy/aEEfr0g6j/hWzvQcrzHCsz07BNQYlNOjTfeytrtLU7k449H1PI95jA4OjQ==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@reflink/reflink-win32-arm64-msvc": {
|
|
||||||
"version": "0.1.19",
|
|
||||||
"resolved": "https://registry.npmjs.org/@reflink/reflink-win32-arm64-msvc/-/reflink-win32-arm64-msvc-0.1.19.tgz",
|
|
||||||
"integrity": "sha512-09PxnVIQcd+UOn4WAW73WU6PXL7DwGS6wPlkMhMg2zlHHG65F3vHepOw06HFCq+N42qkaNAc8AKIabWvtk6cIQ==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"win32"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@reflink/reflink-win32-x64-msvc": {
|
|
||||||
"version": "0.1.19",
|
|
||||||
"resolved": "https://registry.npmjs.org/@reflink/reflink-win32-x64-msvc/-/reflink-win32-x64-msvc-0.1.19.tgz",
|
|
||||||
"integrity": "sha512-E//yT4ni2SyhwP8JRjVGWr3cbnhWDiPLgnQ66qqaanjjnMiu3O/2tjCPQXlcGc/DEYofpDc9fvhv6tALQsMV9w==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"win32"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/detect-libc": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "bootstrap-pnpm",
|
|
||||||
"lockfileVersion": 3,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"": {
|
|
||||||
"dependencies": {
|
|
||||||
"pnpm": "11.19.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pnpm": {
|
|
||||||
"version": "11.19.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pnpm/-/pnpm-11.19.0.tgz",
|
|
||||||
"integrity": "sha512-eIHz7VkNRyxKlV4riLISF5ERYGbcyIy8o4SeybYPG7qm0syyIfqR2k4cZb7yvL43k2Wup6xTnHv4be3DobItzg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"bin": {
|
|
||||||
"pn": "bin/pnpm.mjs",
|
|
||||||
"pnpm": "bin/pnpm.mjs",
|
|
||||||
"pnpx": "bin/pnpx.mjs",
|
|
||||||
"pnx": "bin/pnpx.mjs"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=22.13"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://opencollective.com/pnpm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,15 +4,13 @@ import runSelfInstaller from './run'
|
|||||||
|
|
||||||
export { runSelfInstaller }
|
export { runSelfInstaller }
|
||||||
|
|
||||||
export async function install(inputs: Inputs): Promise<string | undefined> {
|
export async function install(inputs: Inputs) {
|
||||||
startGroup('Running self-installer...')
|
startGroup('Running self-installer...')
|
||||||
const { exitCode, binDest } = await runSelfInstaller(inputs)
|
const status = await runSelfInstaller(inputs)
|
||||||
endGroup()
|
endGroup()
|
||||||
if (exitCode) {
|
if (status) {
|
||||||
setFailed(`Something went wrong, self-installer exits with code ${exitCode}`)
|
return setFailed(`Something went wrong, self-installer exits with code ${status}`)
|
||||||
return undefined
|
|
||||||
}
|
}
|
||||||
return binDest
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default install
|
export default install
|
||||||
|
|||||||
+59
-151
@@ -1,168 +1,91 @@
|
|||||||
import { addPath, exportVariable } from '@actions/core'
|
import { addPath, exportVariable } from '@actions/core'
|
||||||
import { spawn } from 'child_process'
|
import { spawn } from 'child_process'
|
||||||
import { rm, writeFile, mkdir, symlink } from 'fs/promises'
|
import { rm, writeFile, mkdir, copyFile } from 'fs/promises'
|
||||||
import { readFileSync, existsSync } from 'fs'
|
import { readFileSync } from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
import { execPath } from 'process'
|
||||||
import util from 'util'
|
import util from 'util'
|
||||||
import { Inputs } from '../inputs'
|
import { Inputs } from '../inputs'
|
||||||
import { parse as parseYaml } from 'yaml'
|
import { parse as parseYaml } from 'yaml'
|
||||||
import pnpmLock from './bootstrap/pnpm-lock.json'
|
|
||||||
import exeLock from './bootstrap/exe-lock.json'
|
|
||||||
|
|
||||||
const BOOTSTRAP_PNPM_PACKAGE_JSON = JSON.stringify({ private: true, dependencies: { pnpm: pnpmLock.packages['node_modules/pnpm'].version } })
|
export async function runSelfInstaller(inputs: Inputs): Promise<number> {
|
||||||
const BOOTSTRAP_EXE_PACKAGE_JSON = JSON.stringify({ private: true, dependencies: { '@pnpm/exe': exeLock.packages['node_modules/@pnpm/exe'].version } })
|
const { version, dest, packageJsonFile, standalone } = inputs
|
||||||
|
const { GITHUB_WORKSPACE } = process.env
|
||||||
|
|
||||||
export interface SelfInstallerResult {
|
// prepare self install
|
||||||
exitCode: number
|
|
||||||
binDest: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function runSelfInstaller(inputs: Inputs): Promise<SelfInstallerResult> {
|
|
||||||
const { version, dest, packageJsonFile } = inputs
|
|
||||||
|
|
||||||
// pnpm v11 requires Node >= 22.13; use standalone (exe) bootstrap which
|
|
||||||
// bundles its own Node.js when the system Node is too old
|
|
||||||
const systemNode = await getSystemNodeVersion()
|
|
||||||
const standalone = inputs.standalone || systemNode.major < 22 || (systemNode.major === 22 && systemNode.minor < 13)
|
|
||||||
|
|
||||||
// Install bootstrap pnpm via npm (integrity verified by committed lockfile)
|
|
||||||
await rm(dest, { recursive: true, force: true })
|
await rm(dest, { recursive: true, force: true })
|
||||||
|
// create dest directory after removal
|
||||||
await mkdir(dest, { recursive: true })
|
await mkdir(dest, { recursive: true })
|
||||||
|
const pkgJson = path.join(dest, 'package.json')
|
||||||
|
// we have ensured the dest directory exists, we can write the file directly
|
||||||
|
await writeFile(pkgJson, JSON.stringify({ private: true }))
|
||||||
|
|
||||||
const lockfile = standalone ? exeLock : pnpmLock
|
// copy .npmrc if it exists to install from custom registry
|
||||||
const packageJson = standalone ? BOOTSTRAP_EXE_PACKAGE_JSON : BOOTSTRAP_PNPM_PACKAGE_JSON
|
if (GITHUB_WORKSPACE) {
|
||||||
await writeFile(path.join(dest, 'package.json'), packageJson)
|
try {
|
||||||
await writeFile(path.join(dest, 'package-lock.json'), JSON.stringify(lockfile))
|
await copyFile(path.join(GITHUB_WORKSPACE, '.npmrc'), path.join(dest, '.npmrc'))
|
||||||
|
} catch (error) {
|
||||||
// Append the action's node directory to PATH so npm's
|
// Swallow error if .npmrc doesn't exist
|
||||||
// `#!/usr/bin/env node` shebang resolves on runners (e.g. GHE
|
if (!util.types.isNativeError(error) || !('code' in error) || error.code !== 'ENOENT') throw error
|
||||||
// self-hosted) where node isn't already on PATH. Append (not
|
|
||||||
// prepend) so a user-installed toolchain on PATH — e.g. from a
|
|
||||||
// prior `setup-node` step — keeps precedence; otherwise the
|
|
||||||
// runner-bundled node would shadow it and pair the user's npm
|
|
||||||
// with a mismatched node version. npm itself is resolved via
|
|
||||||
// PATH — on the GitHub Actions runner it is not co-located with
|
|
||||||
// `process.execPath`.
|
|
||||||
const nodeDir = path.dirname(process.execPath)
|
|
||||||
// On Windows, the PATH key casing varies; search case-insensitively.
|
|
||||||
const pathKey = Object.keys(process.env).find(k => k.toUpperCase() === 'PATH') ?? 'PATH'
|
|
||||||
const currentPath = process.env[pathKey]
|
|
||||||
const npmEnv = { ...process.env, [pathKey]: currentPath ? currentPath + path.delimiter + nodeDir : nodeDir }
|
|
||||||
const npmExitCode = await runCommand('npm', ['ci'], { cwd: dest, env: npmEnv })
|
|
||||||
if (npmExitCode !== 0) {
|
|
||||||
return { exitCode: npmExitCode, binDest: path.join(dest, 'node_modules', '.bin') }
|
|
||||||
}
|
|
||||||
|
|
||||||
// On Windows with standalone mode, npm's .bin shims can't properly
|
|
||||||
// execute the extensionless @pnpm/exe native binaries. Add the
|
|
||||||
// @pnpm/exe directory directly to PATH so pnpm.exe is found natively.
|
|
||||||
const pnpmHome = standalone && process.platform === 'win32'
|
|
||||||
? path.join(dest, 'node_modules', '@pnpm', 'exe')
|
|
||||||
: path.join(dest, 'node_modules', '.bin')
|
|
||||||
// PNPM_HOME/bin is where `pnpm self-update` places the target version
|
|
||||||
// binary. It must have higher PATH precedence than pnpmHome (which
|
|
||||||
// contains the bootstrap binary) so the self-updated version is found
|
|
||||||
// first. The bootstrap pnpm is invoked via absolute path, not PATH,
|
|
||||||
// so this ordering does not affect the bootstrap step.
|
|
||||||
addPath(pnpmHome)
|
|
||||||
addPath(path.join(pnpmHome, 'bin'))
|
|
||||||
exportVariable('PNPM_HOME', pnpmHome)
|
|
||||||
|
|
||||||
// Ensure pnpm bin link exists — npm ci sometimes doesn't create it
|
|
||||||
if (process.platform !== 'win32') {
|
|
||||||
const pnpmBinLink = path.join(dest, 'node_modules', '.bin', 'pnpm')
|
|
||||||
if (!existsSync(pnpmBinLink)) {
|
|
||||||
await mkdir(path.join(dest, 'node_modules', '.bin'), { recursive: true })
|
|
||||||
const target = standalone
|
|
||||||
? path.join('..', '@pnpm', 'exe', 'pnpm')
|
|
||||||
: path.join('..', 'pnpm', 'bin', 'pnpm.mjs')
|
|
||||||
await symlink(target, pnpmBinLink)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bootstrapPnpm = standalone
|
// prepare target pnpm
|
||||||
? path.join(dest, 'node_modules', '@pnpm', 'exe', process.platform === 'win32' ? 'pnpm.exe' : 'pnpm')
|
const target = await readTarget({ version, packageJsonFile, standalone })
|
||||||
: path.join(dest, 'node_modules', 'pnpm', 'bin', 'pnpm.mjs')
|
const cp = spawn(execPath, [path.join(__dirname, 'pnpm.cjs'), 'install', target, '--no-lockfile'], {
|
||||||
|
cwd: dest,
|
||||||
|
stdio: ['pipe', 'inherit', 'inherit'],
|
||||||
|
})
|
||||||
|
|
||||||
// Self-update the bootstrap to the requested pnpm version. readTargetVersion
|
const exitCode = await new Promise<number>((resolve, reject) => {
|
||||||
// either returns a value or throws, so this always runs.
|
cp.on('error', reject)
|
||||||
const targetVersion = readTargetVersion({ version, packageJsonFile })
|
cp.on('close', resolve)
|
||||||
const cmd = standalone ? bootstrapPnpm : process.execPath
|
})
|
||||||
const args = standalone ? ['self-update', targetVersion] : [bootstrapPnpm, 'self-update', targetVersion]
|
if (exitCode === 0) {
|
||||||
const exitCode = await runCommand(cmd, args, { cwd: dest })
|
const pnpmHome = path.join(dest, 'node_modules/.bin')
|
||||||
if (exitCode !== 0) {
|
addPath(pnpmHome)
|
||||||
return { exitCode, binDest: pnpmHome }
|
addPath(path.join(pnpmHome, 'bin'))
|
||||||
|
exportVariable('PNPM_HOME', pnpmHome)
|
||||||
}
|
}
|
||||||
// self-update writes the target pnpm/pnpx into PNPM_HOME/bin, leaving
|
return exitCode
|
||||||
// the bootstrap symlinks in pnpmHome pointing at the old version. Use
|
|
||||||
// PNPM_HOME/bin so consumers of the bin_dest output (e.g.
|
|
||||||
// `${steps.pnpm.outputs.bin_dest}/pnpm`) invoke the requested version.
|
|
||||||
//
|
|
||||||
// When the requested version resolves to the bootstrap version, self-update
|
|
||||||
// is a no-op and PNPM_HOME/bin is not created — fall back to pnpmHome,
|
|
||||||
// whose symlinks already point at the right version.
|
|
||||||
const updatedBinDir = path.join(pnpmHome, 'bin')
|
|
||||||
return { exitCode: 0, binDest: existsSync(updatedBinDir) ? updatedBinDir : pnpmHome }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function readTargetVersion(opts: {
|
async function readTarget(opts: {
|
||||||
readonly version?: string | undefined
|
readonly version?: string | undefined
|
||||||
readonly packageJsonFile: string
|
readonly packageJsonFile: string
|
||||||
}): string {
|
readonly standalone: boolean
|
||||||
const { version, packageJsonFile } = opts
|
}) {
|
||||||
|
const { version, packageJsonFile, standalone } = opts
|
||||||
const { GITHUB_WORKSPACE } = process.env
|
const { GITHUB_WORKSPACE } = process.env
|
||||||
|
|
||||||
let packageManager: string | undefined
|
let packageManager
|
||||||
let devEngines: { packageManager?: { name?: string; version?: string } } | undefined
|
|
||||||
|
|
||||||
if (GITHUB_WORKSPACE) {
|
if (GITHUB_WORKSPACE) {
|
||||||
try {
|
try {
|
||||||
const content = readFileSync(path.join(GITHUB_WORKSPACE, packageJsonFile), 'utf8');
|
const content = readFileSync(path.join(GITHUB_WORKSPACE, packageJsonFile), 'utf8');
|
||||||
const manifest = packageJsonFile.endsWith(".yaml")
|
({ packageManager } = packageJsonFile.endsWith(".yaml")
|
||||||
? parseYaml(content, { merge: true })
|
? parseYaml(content, { merge: true })
|
||||||
: JSON.parse(content)
|
: JSON.parse(content)
|
||||||
packageManager = manifest.packageManager
|
)
|
||||||
devEngines = manifest.devEngines
|
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
// Swallow error if package.json doesn't exist in root
|
// Swallow error if package.json doesn't exist in root
|
||||||
if (!util.types.isNativeError(error) || !('code' in error) || error.code !== 'ENOENT') throw error
|
if (!util.types.isNativeError(error) || !('code' in error) || error.code !== 'ENOENT') throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// packageManager is always exact `pnpm@<version>[+<integrity>]` per spec.
|
|
||||||
// Strip the integrity hash for self-update.
|
|
||||||
const packageManagerVersion =
|
|
||||||
typeof packageManager === 'string' && packageManager.startsWith('pnpm@')
|
|
||||||
? packageManager.slice('pnpm@'.length).split('+')[0]
|
|
||||||
: undefined
|
|
||||||
|
|
||||||
if (version) {
|
if (version) {
|
||||||
if (packageManagerVersion && packageManagerVersion !== version) {
|
if (
|
||||||
|
typeof packageManager === 'string' &&
|
||||||
|
packageManager.startsWith('pnpm@') &&
|
||||||
|
packageManager.replace('pnpm@', '') !== version
|
||||||
|
) {
|
||||||
throw new Error(`Multiple versions of pnpm specified:
|
throw new Error(`Multiple versions of pnpm specified:
|
||||||
- version ${version} in the GitHub Action config with the key "version"
|
- version ${version} in the GitHub Action config with the key "version"
|
||||||
- version ${packageManager} in the package.json with the key "packageManager"
|
- version ${packageManager} in the package.json with the key "packageManager"
|
||||||
Remove one of these versions to avoid version mismatch errors like ERR_PNPM_BAD_PM_VERSION`)
|
Remove one of these versions to avoid version mismatch errors like ERR_PNPM_BAD_PM_VERSION`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return version
|
return `${ standalone ? '@pnpm/exe' : 'pnpm' }@${version}`
|
||||||
}
|
|
||||||
|
|
||||||
// Self-update the bootstrap pnpm to the version pinned in package.json so
|
|
||||||
// PATH-resolved `pnpm` (and the bin_dest output) reflect the target
|
|
||||||
// version. Without this, `pnpm store path` runs as the bootstrap and
|
|
||||||
// reports a different STORE_VERSION than the one the user's actual
|
|
||||||
// install writes to — breaking cache: true and actions/setup-node's
|
|
||||||
// `cache: pnpm` on cold caches (issue #233).
|
|
||||||
//
|
|
||||||
// devEngines.packageManager takes priority over packageManager, matching
|
|
||||||
// pnpm's getWantedPackageManager logic. `pnpm self-update` accepts both
|
|
||||||
// exact versions and semver ranges, so we pass either through directly.
|
|
||||||
if (devEngines?.packageManager?.name === 'pnpm' && devEngines.packageManager.version) {
|
|
||||||
return devEngines.packageManager.version
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packageManagerVersion) {
|
|
||||||
return packageManagerVersion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GITHUB_WORKSPACE) {
|
if (!GITHUB_WORKSPACE) {
|
||||||
@@ -172,37 +95,22 @@ please run the actions/checkout before pnpm/action-setup.
|
|||||||
Otherwise, please specify the pnpm version in the action configuration.`)
|
Otherwise, please specify the pnpm version in the action configuration.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(`No pnpm version is specified.
|
if (typeof packageManager !== 'string') {
|
||||||
|
throw new Error(`No pnpm version is specified.
|
||||||
Please specify it by one of the following ways:
|
Please specify it by one of the following ways:
|
||||||
- in the GitHub Action config with the key "version"
|
- in the GitHub Action config with the key "version"
|
||||||
- in the package.json with the key "packageManager"
|
- in the package.json with the key "packageManager"`)
|
||||||
- in the package.json with the key "devEngines.packageManager"`)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function getSystemNodeVersion(): Promise<{ major: number; minor: number }> {
|
if (!packageManager.startsWith('pnpm@')) {
|
||||||
return new Promise((resolve) => {
|
throw new Error('Invalid packageManager field in package.json')
|
||||||
const cp = spawn('node', ['--version'], { stdio: ['pipe', 'pipe', 'pipe'], shell: process.platform === 'win32' })
|
}
|
||||||
let output = ''
|
|
||||||
cp.stdout.on('data', (data: Buffer) => { output += data.toString() })
|
|
||||||
cp.on('close', () => {
|
|
||||||
const match = output.match(/^v(\d+)\.(\d+)/)
|
|
||||||
resolve(match ? { major: parseInt(match[1], 10), minor: parseInt(match[2], 10) } : { major: 0, minor: 0 })
|
|
||||||
})
|
|
||||||
cp.on('error', () => resolve({ major: 0, minor: 0 }))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function runCommand(cmd: string, args: string[], opts: { cwd: string; env?: Record<string, string | undefined> }): Promise<number> {
|
if (standalone) {
|
||||||
return new Promise<number>((resolve, reject) => {
|
return packageManager.replace('pnpm@', '@pnpm/exe@')
|
||||||
const cp = spawn(cmd, args, {
|
}
|
||||||
cwd: opts.cwd,
|
|
||||||
env: opts.env,
|
return packageManager
|
||||||
stdio: ['pipe', 'inherit', 'inherit'],
|
|
||||||
shell: process.platform === 'win32',
|
|
||||||
})
|
|
||||||
cp.on('error', reject)
|
|
||||||
cp.on('close', resolve)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default runSelfInstaller
|
export default runSelfInstaller
|
||||||
|
|||||||
@@ -1,164 +0,0 @@
|
|||||||
import { restoreCache, saveCache } from '@actions/cache'
|
|
||||||
import { debug, getState, info, saveState, warning } from '@actions/core'
|
|
||||||
import { getExecOutput } from '@actions/exec'
|
|
||||||
import { existsSync, readFileSync } from 'fs'
|
|
||||||
import os from 'os'
|
|
||||||
import path from 'path'
|
|
||||||
import { removeWindowsExtendedPathPrefix } from '../windows-path'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Where pnpm v11+ memoizes which lockfile passed which supply-chain policies.
|
|
||||||
* A job without it re-checks every lockfile entry against the registry, which
|
|
||||||
* on a large repository costs more than the install.
|
|
||||||
*/
|
|
||||||
const VERIFICATION_CACHE_FILE = 'lockfile-verified.jsonl'
|
|
||||||
|
|
||||||
const PATH_STATE = 'lockfile_verification_cache_path'
|
|
||||||
const KEY_STATE = 'lockfile_verification_cache_key'
|
|
||||||
const STORED_STATE = 'lockfile_verification_cache_stored'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Where the log lives and under which key it belongs in the cache. Held in
|
|
||||||
* memory as well as in the action's state because the main and post steps run
|
|
||||||
* as separate processes, and state written by one is only readable by the
|
|
||||||
* other.
|
|
||||||
*/
|
|
||||||
let target: { cacheFilePath: string, key: string } | undefined
|
|
||||||
|
|
||||||
/** Whether this process already restored or saved the log. */
|
|
||||||
let stored = false
|
|
||||||
|
|
||||||
/** The log's records as they stood before the install ran. */
|
|
||||||
let recordsBeforeInstall: string[] | undefined
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The verdict is only valid for the exact lockfile content it was recorded
|
|
||||||
* for, so this cache is keyed on the same lockfile hash as the store cache
|
|
||||||
* but restored without prefix fallback: an older entry could never be used.
|
|
||||||
*/
|
|
||||||
export async function restoreVerificationCache(lockfileHash: string): Promise<void> {
|
|
||||||
try {
|
|
||||||
const cacheFilePath = path.join(await getPnpmCacheDirectory(), VERIFICATION_CACHE_FILE)
|
|
||||||
const key = `pnpm-lockfile-verified-${process.env.RUNNER_OS}-${os.arch()}-${lockfileHash}`
|
|
||||||
target = { cacheFilePath, key }
|
|
||||||
saveState(PATH_STATE, cacheFilePath)
|
|
||||||
saveState(KEY_STATE, key)
|
|
||||||
debug(`Lockfile verification cache path is ${cacheFilePath}, key is ${key}`)
|
|
||||||
|
|
||||||
const restoredKey = await restoreCache([cacheFilePath], key)
|
|
||||||
recordsBeforeInstall = readRecords(cacheFilePath)
|
|
||||||
if (!restoredKey) {
|
|
||||||
info('Lockfile verification cache is not found')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
stored = true
|
|
||||||
saveState(STORED_STATE, 'true')
|
|
||||||
info(`Lockfile verification cache restored from key: ${restoredKey}`)
|
|
||||||
} catch (error) {
|
|
||||||
// The gate only costs time, never correctness — a job that cannot reuse
|
|
||||||
// a past verdict re-verifies and moves on.
|
|
||||||
warning(`Failed to restore the lockfile verification cache: ${(error as Error).message}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uploaded as soon as the install that produced the log finishes, rather than
|
|
||||||
* at the end of the job: whatever a job runs after installing can rewrite the
|
|
||||||
* log on disk, and the job's own cache write would then publish that for later
|
|
||||||
* jobs to trust. Lifecycle scripts of the installed packages stay inside the
|
|
||||||
* window — they run during the install — but pnpm only runs those the
|
|
||||||
* repository has allow-listed, and `expectedNewRecords` catches what they
|
|
||||||
* append.
|
|
||||||
*
|
|
||||||
* Safe to call more than once; the second call is a no-op.
|
|
||||||
*/
|
|
||||||
export async function saveVerificationCache(expectedNewRecords = Infinity): Promise<void> {
|
|
||||||
if (stored || getState(STORED_STATE) === 'true') return
|
|
||||||
|
|
||||||
const cacheFilePath = target?.cacheFilePath ?? getState(PATH_STATE)
|
|
||||||
const key = target?.key ?? getState(KEY_STATE)
|
|
||||||
if (!cacheFilePath || !key || !existsSync(cacheFilePath)) return
|
|
||||||
|
|
||||||
if (!onlyGrewAsExpected(cacheFilePath, expectedNewRecords)) return
|
|
||||||
|
|
||||||
try {
|
|
||||||
const cacheId = await saveCache([cacheFilePath], key)
|
|
||||||
if (cacheId === -1) return
|
|
||||||
stored = true
|
|
||||||
saveState(STORED_STATE, 'true')
|
|
||||||
info(`Lockfile verification cache saved with the key: ${key}`)
|
|
||||||
} catch (error) {
|
|
||||||
warning(`Failed to save the lockfile verification cache: ${(error as Error).message}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An install appends its own verdict and leaves every earlier record in place.
|
|
||||||
* Anything else — a record the install did not write, or an earlier one gone —
|
|
||||||
* means something other than pnpm's verification wrote to the log, and
|
|
||||||
* uploading it would hand that to every later job. pnpm compacting the log
|
|
||||||
* (past a thousand records) lands here too, at the cost of one re-verification.
|
|
||||||
*/
|
|
||||||
function onlyGrewAsExpected(cacheFilePath: string, expectedNewRecords: number): boolean {
|
|
||||||
const before = recordsBeforeInstall
|
|
||||||
if (before === undefined) return true
|
|
||||||
|
|
||||||
const after = readRecords(cacheFilePath)
|
|
||||||
if (after === undefined) return false
|
|
||||||
|
|
||||||
if (!before.every((record, index) => after[index] === record)) {
|
|
||||||
warning(
|
|
||||||
'Records that predate the install are missing from the lockfile verification log; not caching it.'
|
|
||||||
)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const added = after.length - before.length
|
|
||||||
if (added > expectedNewRecords) {
|
|
||||||
warning(
|
|
||||||
`The lockfile verification log gained ${added} records during the install, expected at most ${expectedNewRecords}; not caching it.`
|
|
||||||
)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
function readRecords(cacheFilePath: string): string[] | undefined {
|
|
||||||
try {
|
|
||||||
return readFileSync(cacheFilePath, 'utf8').split('\n').filter(Boolean)
|
|
||||||
} catch {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getPnpmCacheDirectory(): Promise<string> {
|
|
||||||
const { stdout } = await getExecOutput('pnpm config get cacheDir', undefined, {
|
|
||||||
silent: true,
|
|
||||||
ignoreReturnCode: true,
|
|
||||||
})
|
|
||||||
const configured = stdout.trim()
|
|
||||||
// `pnpm config get` reports settings, not defaults: an unset `cacheDir`
|
|
||||||
// prints `undefined` and the default has to be derived here.
|
|
||||||
if (configured && configured !== 'undefined') {
|
|
||||||
return removeWindowsExtendedPathPrefix(configured)
|
|
||||||
}
|
|
||||||
return defaultPnpmCacheDirectory()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Mirrors pnpm's own `cacheDir` default. */
|
|
||||||
function defaultPnpmCacheDirectory(): string {
|
|
||||||
const { XDG_CACHE_HOME, LOCALAPPDATA } = process.env
|
|
||||||
if (XDG_CACHE_HOME) return path.join(XDG_CACHE_HOME, 'pnpm')
|
|
||||||
|
|
||||||
const homeDir = os.homedir()
|
|
||||||
switch (process.platform) {
|
|
||||||
case 'darwin':
|
|
||||||
return path.join(homeDir, 'Library', 'Caches', 'pnpm')
|
|
||||||
case 'win32':
|
|
||||||
return LOCALAPPDATA ? path.join(LOCALAPPDATA, 'pnpm-cache') : path.join(homeDir, '.pnpm-cache')
|
|
||||||
default:
|
|
||||||
return path.join(homeDir, '.cache', 'pnpm')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
import { setOutput } from '@actions/core'
|
import { setOutput, addPath } from '@actions/core'
|
||||||
import { Inputs } from '../inputs'
|
import { Inputs } from '../inputs'
|
||||||
|
import { getBinDest } from '../utils'
|
||||||
|
|
||||||
export function setOutputs(inputs: Inputs, binDest: string) {
|
export function setOutputs(inputs: Inputs) {
|
||||||
// NOTE: addPath is already called in installPnpm — do not call it again
|
const binDest = getBinDest(inputs)
|
||||||
// here, as a second addPath would shadow the correct entry on Windows.
|
addPath(binDest)
|
||||||
setOutput('dest', inputs.dest)
|
setOutput('dest', inputs.dest)
|
||||||
setOutput('bin_dest', binDest)
|
setOutput('bin_dest', binDest)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
import { setFailed, startGroup, endGroup } from '@actions/core'
|
import { setFailed, startGroup, endGroup } from '@actions/core'
|
||||||
import { spawnSync } from 'child_process'
|
import { spawnSync } from 'child_process'
|
||||||
import { Inputs } from '../inputs'
|
import { Inputs } from '../inputs'
|
||||||
|
import { patchPnpmEnv } from '../utils'
|
||||||
|
|
||||||
export function runPnpmInstall(inputs: Inputs) {
|
export function runPnpmInstall(inputs: Inputs) {
|
||||||
|
const env = patchPnpmEnv(inputs)
|
||||||
|
|
||||||
for (const options of inputs.runInstall) {
|
for (const options of inputs.runInstall) {
|
||||||
const args = ['install']
|
const args = ['install']
|
||||||
if (options.recursive) args.unshift('recursive')
|
if (options.recursive) args.unshift('recursive')
|
||||||
@@ -11,16 +14,11 @@ export function runPnpmInstall(inputs: Inputs) {
|
|||||||
const cmdStr = ['pnpm', ...args].join(' ')
|
const cmdStr = ['pnpm', ...args].join(' ')
|
||||||
startGroup(`Running ${cmdStr}...`)
|
startGroup(`Running ${cmdStr}...`)
|
||||||
|
|
||||||
// spawnSync inherits process.env, which already has $PNPM_HOME/bin and
|
|
||||||
// $PNPM_HOME prepended via addPath() in install-pnpm. Do NOT pass a
|
|
||||||
// hand-patched env that adds node_modules/.bin to the front — on
|
|
||||||
// Windows standalone, .bin/pnpm.cmd is an npm shim pointing at the
|
|
||||||
// BOOTSTRAP pnpm, which would shadow the self-updated one and break
|
|
||||||
// newer-pnpm-only behavior.
|
|
||||||
const { error, status } = spawnSync('pnpm', args, {
|
const { error, status } = spawnSync('pnpm', args, {
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
cwd: options.cwd,
|
cwd: options.cwd,
|
||||||
shell: true,
|
shell: true,
|
||||||
|
env,
|
||||||
})
|
})
|
||||||
|
|
||||||
endGroup()
|
endGroup()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { warning, startGroup, endGroup } from '@actions/core'
|
import { warning, startGroup, endGroup } from '@actions/core'
|
||||||
import { spawnSync } from 'child_process'
|
import { spawnSync } from 'child_process'
|
||||||
import { Inputs } from '../inputs'
|
import { Inputs } from '../inputs'
|
||||||
|
import { patchPnpmEnv } from '../utils'
|
||||||
|
|
||||||
export function pruneStore(inputs: Inputs) {
|
export function pruneStore(inputs: Inputs) {
|
||||||
if (inputs.runInstall.length === 0) {
|
if (inputs.runInstall.length === 0) {
|
||||||
@@ -9,11 +10,10 @@ export function pruneStore(inputs: Inputs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
startGroup('Running pnpm store prune...')
|
startGroup('Running pnpm store prune...')
|
||||||
// spawnSync inherits process.env (which has the right PATH from addPath
|
|
||||||
// in install-pnpm). See pnpm-install/index.ts for the rationale.
|
|
||||||
const { error, status } = spawnSync('pnpm', ['store', 'prune'], {
|
const { error, status } = spawnSync('pnpm', ['store', 'prune'], {
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
shell: true,
|
shell: true,
|
||||||
|
env: patchPnpmEnv(inputs),
|
||||||
})
|
})
|
||||||
endGroup()
|
endGroup()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import path from 'path'
|
||||||
|
import process from 'process'
|
||||||
|
import { Inputs } from '../inputs'
|
||||||
|
|
||||||
|
export const getBinDest = (inputs: Inputs): string => path.join(inputs.dest, 'node_modules', '.bin')
|
||||||
|
|
||||||
|
export const patchPnpmEnv = (inputs: Inputs): NodeJS.ProcessEnv => ({
|
||||||
|
...process.env,
|
||||||
|
PATH: path.join(getBinDest(inputs), 'bin') + path.delimiter + getBinDest(inputs) + path.delimiter + process.env.PATH,
|
||||||
|
})
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/**
|
|
||||||
* pnpm may report an extended-length path on Windows. The `?` in that prefix
|
|
||||||
* is interpreted as a wildcard by `@actions/cache`, which rejects it as a glob
|
|
||||||
* in the root segment. Cache APIs do not need the extended-length form, so
|
|
||||||
* convert it back to a regular drive or UNC path.
|
|
||||||
*/
|
|
||||||
export function removeWindowsExtendedPathPrefix(cachePath: string): string {
|
|
||||||
const extendedPathPrefix = '\\\\?\\'
|
|
||||||
if (!cachePath.startsWith(extendedPathPrefix)) return cachePath
|
|
||||||
|
|
||||||
const pathWithoutPrefix = cachePath.slice(extendedPathPrefix.length)
|
|
||||||
const uncPrefix = 'UNC\\'
|
|
||||||
if (pathWithoutPrefix.toUpperCase().startsWith(uncPrefix)) {
|
|
||||||
return `\\\\${pathWithoutPrefix.slice(uncPrefix.length)}`
|
|
||||||
}
|
|
||||||
return pathWithoutPrefix
|
|
||||||
}
|
|
||||||
|
|
||||||
export default removeWindowsExtendedPathPrefix
|
|
||||||
+11
-4
@@ -1,19 +1,26 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2022",
|
"target": "ES2022",
|
||||||
"module": "ESNext",
|
"module": "Node16",
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"lib": [
|
"lib": [
|
||||||
"ES2023"
|
"ES2023"
|
||||||
],
|
],
|
||||||
"noEmit": true,
|
"outDir": "./dist/tsc",
|
||||||
|
"preserveConstEnums": true,
|
||||||
|
"incremental": false,
|
||||||
|
"declaration": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"importHelpers": false,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"pretty": true,
|
"pretty": true,
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"esModuleInterop": true
|
"esModuleInterop": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"emitDecoratorMetadata": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user