Skip to content

ci: update dependencies with pnpm/update instead of Dependabot #92

ci: update dependencies with pnpm/update instead of Dependabot

ci: update dependencies with pnpm/update instead of Dependabot #92

Workflow file for this run

name: Test Action
on:
pull_request:
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
jobs:
smoke:
# Direct binary download + pnpm on PATH across OSes and architectures.
name: 'Smoke (${{ matrix.os }} / pnpm ${{ matrix.version }})'
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: '12.0.0'
- os: ubuntu-24.04-arm
version: '12.0.0'
- os: macos-latest
version: '12.0.0'
- os: windows-latest
version: '12.0.0'
steps:
- uses: actions/checkout@v7
- id: pnpm
uses: ./
with:
version: ${{ matrix.version }}
- name: 'Test: pnpm version on PATH matches request'
env:
BIN_DEST: ${{ steps.pnpm.outputs.bin-dest }}
REQUIRED: ${{ matrix.version }}
run: |
set -e
which pnpm
actual="$(pnpm --version)"
echo "pnpm --version: ${actual}"
if [ "${actual}" != "${REQUIRED}" ]; then
echo "Expected pnpm ${REQUIRED}, got ${actual}"
exit 1
fi
bin_dest_version="$("$BIN_DEST/pnpm" --version)"
if [ "${bin_dest_version}" != "${REQUIRED}" ]; then
echo "Expected ${REQUIRED} via bin_dest, got ${bin_dest_version}"
exit 1
fi
shell: bash
smoke-v11:
# v11's release archive bundles a Node-SEA launcher plus a sibling `dist/`,
# unlike v12's single self-contained binary. Verify the action downloads and
# lays it out correctly and puts pnpm on PATH across OSes/arches. (macos-latest
# is arm64; pnpm v11 ships no Intel-macOS binary, so no macos-13 entry here.)
name: 'Smoke pnpm 11 (${{ matrix.os }})'
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v7
- id: pnpm
uses: ./
with:
version: '11.17.0'
install: false
- name: 'Test: pnpm 11 on PATH matches request'
env:
BIN_DEST: ${{ steps.pnpm.outputs.bin-dest }}
run: |
set -e
which pnpm
actual="$(pnpm --version)"
echo "pnpm --version: ${actual}"
if [ "${actual}" != "11.17.0" ]; then
echo "Expected pnpm 11.17.0, got ${actual}"
exit 1
fi
bin_dest_version="$("$BIN_DEST/pnpm" --version)"
if [ "${bin_dest_version}" != "11.17.0" ]; then
echo "Expected 11.17.0 via bin_dest, got ${bin_dest_version}"
exit 1
fi
shell: bash
cache-windows:
# pnpm can report a Windows store path with the extended-length `\\?\`
# prefix. Cache paths must use the regular drive-path form because the
# cache toolkit otherwise interprets `?` as a glob in the root segment.
#
# The pnpm version below is load-bearing, not stale: 12.0.0 reports a
# plain `D:\.pnpm-store\v11` for this store-dir, so only an older
# release still reproduces the prefix this job exists to cover. Do not
# bump it without checking that `pnpm store path` still starts `\\?\`.
name: 'Cache Windows extended-length store path'
runs-on: windows-latest
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- name: Configure store at the drive root
run: Set-Content -Path .npmrc -Value 'store-dir=/.pnpm-store'
- uses: ./
with:
version: '12.0.0-rc.0'
runtime: node@22
cache: true
- name: 'Test: pnpm reports an extended-length store path'
run: |
$storePath = pnpm store path
Write-Host "pnpm store path: $storePath"
if (-not $storePath.StartsWith('\\?\')) {
throw "Expected an extended-length store path, got: $storePath"
}
runtime-cache-prime:
name: 'Prime runtime cache'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: ./
with:
version: '11.22.0'
runtime: node@24.19.0
cache: true
- name: 'Test: moving selector cache keys'
run: pnpm test
runtime-cache-hit:
name: 'Restore runtime cache'
needs: runtime-cache-prime
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
# `pnpm runtime set` always fetches SHASUMS256.txt(.sig) and index.json
# from nodejs.org to verify the runtime, warm store or not, so the job
# cannot prove the restore happened by cutting the network. What it can
# prove is the key scheme: a second run of the same selector must land
# an exact hit on the key the first run saved under the resolved
# version, which only holds if the restore precedes the install.
- id: pnpm
uses: ./
with:
version: '11.22.0'
runtime: node@24.19.0
cache: true
install: false
- name: 'Test: runtime cache was restored'
env:
CACHE_HIT: ${{ steps.pnpm.outputs.cache-hit }}
run: |
set -e
if [ "${CACHE_HIT}" != "true" ]; then
echo "Expected a runtime cache hit, got: ${CACHE_HIT}"
exit 1
fi
actual="$(node --version)"
if [ "${actual}" != "v24.19.0" ]; then
echo "Expected node v24.19.0, got: ${actual}"
exit 1
fi
shell: bash
runtime-node-pnpm11:
# The whole premise of supporting v11 is that `pnpm runtime` works there.
# Install pnpm v11, install a runtime through it, and run `pnpm install`.
name: 'Runtime node + install on pnpm 11'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Set up a synthetic package.json
# Use a fresh manifest (and drop the repo lockfile) so `pnpm install`
# under v11 resolves cleanly rather than against a v12-authored lockfile.
run: |
rm -f pnpm-lock.yaml
cat > package.json <<'EOF'
{
"dependencies": {
"is-odd": "3.0.1"
}
}
EOF
shell: bash
- id: pnpm
uses: ./
with:
version: '11.17.0'
runtime: node@22
- name: 'Test: pnpm 11, node 22, and install all worked'
env:
OUT_NAME: ${{ steps.pnpm.outputs.runtime-name }}
OUT_VERSION: ${{ steps.pnpm.outputs.runtime-version }}
run: |
set -e
pnpm_version="$(pnpm --version)"
echo "pnpm --version: ${pnpm_version}"
case "${pnpm_version}" in
11.*) ;;
*) echo "Expected pnpm 11.x, got ${pnpm_version}"; exit 1 ;;
esac
which node
node_version="$(node --version)"
echo "node --version: ${node_version}"
case "${node_version}" in
v22.*) ;;
*) echo "Expected node v22.x, got ${node_version}"; exit 1 ;;
esac
if [ "${OUT_NAME}" != "node" ]; then
echo "Expected outputs.runtime-name=node, got ${OUT_NAME}"; exit 1
fi
case "${OUT_VERSION}" in
22.*) ;;
*) echo "Expected outputs.runtime-version=22.x, got ${OUT_VERSION}"; exit 1 ;;
esac
if [ ! -d node_modules/is-odd ]; then
echo "Expected pnpm install to populate node_modules/is-odd"; exit 1
fi
shell: bash
version-from-dist-tag:
# `version` may be an npm dist-tag; it is resolved against the main
# `pnpm` package's dist-tags.
name: 'Version from dist-tag (next-12)'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: ./
with:
version: next-12
install: false
- name: 'Test: dist-tag resolves to a 12.x version'
run: |
set -e
which pnpm
actual="$(pnpm --version)"
echo "pnpm --version: ${actual}"
case "${actual}" in
12.*) echo "ok" ;;
*) echo "Expected pnpm 12.x, got ${actual}"; exit 1 ;;
esac
shell: bash
version-range:
# `version` may be a semver range. While v12 only has prereleases the
# range resolution falls back to prerelease versions.
name: 'Version from semver range (^12.0.0-0)'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: ./
with:
version: '^12.0.0-0'
install: false
- name: 'Test: range resolves to a 12.x version'
run: |
set -e
actual="$(pnpm --version)"
echo "pnpm --version: ${actual}"
case "${actual}" in
12.*) echo "ok" ;;
*) echo "Expected pnpm 12.x, got ${actual}"; exit 1 ;;
esac
shell: bash
runtime-node:
# Explicit runtime input across OSes. Asserts node binary is on PATH and
# the action's outputs reflect what was installed.
name: 'Runtime node@${{ matrix.major }} (${{ matrix.os }})'
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
major: '22'
- os: macos-latest
major: '22'
- os: windows-latest
major: '22'
steps:
- uses: actions/checkout@v7
- id: pnpm
uses: ./
with:
version: '12.0.0'
runtime: node@${{ matrix.major }}
- name: 'Test: node binary on PATH'
env:
MAJOR: ${{ matrix.major }}
run: |
set -e
which node
actual="$(node --version)"
echo "node --version: ${actual}"
case "${actual}" in
v${MAJOR}.*) echo "ok" ;;
*) echo "Expected node v${MAJOR}.x, got ${actual}"; exit 1 ;;
esac
shell: bash
- name: 'Test: outputs.runtime-name and outputs.runtime-version'
env:
OUT_NAME: ${{ steps.pnpm.outputs.runtime-name }}
OUT_VERSION: ${{ steps.pnpm.outputs.runtime-version }}
EXPECTED_VERSION: ${{ matrix.major }}
run: |
set -e
if [ "${OUT_NAME}" != "node" ]; then
echo "Expected outputs.runtime-name=node, got ${OUT_NAME}"
exit 1
fi
case "${OUT_VERSION}" in
"${EXPECTED_VERSION}".*) ;;
*) echo "Expected outputs.runtime-version=${EXPECTED_VERSION}.x, got ${OUT_VERSION}"; exit 1 ;;
esac
shell: bash
runtime-bun:
name: Runtime bun
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: ./
with:
version: '12.0.0'
runtime: bun@latest
- name: 'Test: bun on PATH'
run: |
set -e
which bun
bun --version
shell: bash
runtime-deno:
name: Runtime deno
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: ./
with:
version: '12.0.0'
runtime: deno@2
- name: 'Test: deno on PATH'
run: |
set -e
which deno
deno --version
shell: bash
runtime-from-devengines:
# No `runtime` input — the action should pick up devEngines.runtime from
# package.json and install every entry. Also asserts that `pnpm install` runs by
# default when a manifest is present.
name: 'Runtime from devEngines.runtime'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Set up package.json with devEngines.runtime
# Remove the action's own pnpm-lock.yaml so `pnpm install` doesn't
# hit a frozen-lockfile mismatch against the synthetic manifest.
run: |
rm -f pnpm-lock.yaml
cat > package.json <<'EOF'
{
"packageManager": "pnpm@12.0.0",
"devEngines": {
"runtime": [
{ "name": "bun", "version": "1.3.12", "onFail": "warn" },
{ "name": "node", "version": "24", "onFail": "warn" },
{ "name": "bun", "version": "1.3.13", "onFail": "warn" }
]
},
"dependencies": {
"is-odd": "3.0.1"
}
}
EOF
shell: bash
- id: pnpm
uses: ./
- name: 'Test: Bun and Node are installed and dependencies are resolved'
env:
OUT_NAME: ${{ steps.pnpm.outputs.runtime-name }}
OUT_VERSION: ${{ steps.pnpm.outputs.runtime-version }}
OUT_RUNTIMES: ${{ steps.pnpm.outputs.runtimes }}
run: |
set -e
which bun
bun_actual="$(bun --version)"
echo "bun --version: ${bun_actual}"
if [ "${bun_actual}" != "1.3.13" ]; then
echo "Expected bun 1.3.13, got ${bun_actual}"
exit 1
fi
which node
actual="$(node --version)"
echo "node --version: ${actual}"
case "${actual}" in
v24.*) ;;
*) echo "Expected node v24.x, got ${actual}"; exit 1 ;;
esac
if [ "${OUT_NAME}" != "bun" ]; then
echo "Expected outputs.runtime-name=bun, got ${OUT_NAME}"
exit 1
fi
if [ "${OUT_VERSION}" != "1.3.13" ]; then
echo "Expected outputs.runtime-version=1.3.13, got ${OUT_VERSION}"
exit 1
fi
# Declaration order is part of the contract, and each version must be
# the one that landed rather than the selector that was asked for.
first="$(printf '%s' "${OUT_RUNTIMES}" | jq -r '.[0].name + "@" + .[0].version')"
second="$(printf '%s' "${OUT_RUNTIMES}" | jq -r '.[1].name + "@" + .[1].version')"
count="$(printf '%s' "${OUT_RUNTIMES}" | jq -r 'length')"
if [ "${count}" != "2" ]; then
echo "Expected 2 entries in outputs.runtimes, got ${count}: ${OUT_RUNTIMES}"
exit 1
fi
if [ "${first}" != "bun@1.3.13" ]; then
echo "Expected outputs.runtimes[0]=bun@1.3.13, got ${first}"
exit 1
fi
case "${second}" in
node@24.*) ;;
*) echo "Expected outputs.runtimes[1]=node@24.x, got ${second}"; exit 1 ;;
esac
# `pnpm install` should have run automatically — node_modules must exist.
if [ ! -d node_modules/is-odd ]; then
echo "Expected pnpm install to have populated node_modules/is-odd"
exit 1
fi
shell: bash
runtime-overrides-devengines:
# Explicit `runtime` input conflicts with `devEngines.runtime` in
# package.json. The action should install the explicit version AND pass
# `--no-runtime` to pnpm install so the devEngines runtime doesn't shadow
# the matrix one.
name: 'Explicit runtime overrides devEngines.runtime'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Set up package.json with conflicting devEngines.runtime
run: |
rm -f pnpm-lock.yaml
cat > package.json <<'EOF'
{
"packageManager": "pnpm@12.0.0",
"devEngines": {
"runtime": { "name": "node", "version": "^20.0.0", "onFail": "download" }
},
"dependencies": {
"is-odd": "3.0.1"
}
}
EOF
shell: bash
- id: pnpm
uses: ./
with:
runtime: node@22
- name: 'Test: node 22 stays active after pnpm install'
run: |
set -e
actual="$(node --version)"
echo "node --version: ${actual}"
case "${actual}" in
v22.*) ;;
*) echo "Expected node v22.x after install (--no-runtime should have suppressed the devEngines runtime fetch), got ${actual}"; exit 1 ;;
esac
# pnpm install should still have run.
if [ ! -d node_modules/is-odd ]; then
echo "Expected pnpm install to have populated node_modules/is-odd"
exit 1
fi
shell: bash
runtime-survives-context-shims:
# pnpm 12 links the global `node` bin as a context-aware shim that would
# switch to the version the project pins in devEngines.runtime. The
# exported PNPM_CONFIG_GLOBAL_SHIMS must keep the installed runtime
# authoritative for every later step.
name: 'Installed runtime beats context-aware shims'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Set up package.json with conflicting devEngines.runtime
run: |
rm -f pnpm-lock.yaml
cat > package.json <<'EOF'
{
"packageManager": "pnpm@12.0.0",
"devEngines": {
"runtime": { "name": "node", "version": "20.19.0", "onFail": "download" }
}
}
EOF
shell: bash
- uses: ./
with:
runtime: node@22
- name: 'Test: node 22 runs inside the project'
run: |
set -e
actual="$(node --version)"
echo "node --version: ${actual}"
case "${actual}" in
v22.*) ;;
*) echo "Expected node v22.x, got ${actual} — the context-aware shim switched to the project's pin"; exit 1 ;;
esac
echo "PNPM_CONFIG_GLOBAL_SHIMS: ${PNPM_CONFIG_GLOBAL_SHIMS}"
if [ "${PNPM_CONFIG_GLOBAL_SHIMS}" != '{"node":false}' ]; then
echo 'Expected PNPM_CONFIG_GLOBAL_SHIMS={"node":false}'
exit 1
fi
shell: bash
context-shims-opt-out:
# The counterpart to the job above, and its canary: a workflow that sets
# the setting itself keeps pnpm's switching behaviour, so the project's
# pin wins. If this job stops switching, the job above is no longer
# proving anything. Both spellings pnpm accepts are covered, since
# honouring only one of them would silently override the other.
name: 'Workflow-set ${{ matrix.env_name }} is not overwritten'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
env_name: [PNPM_CONFIG_GLOBAL_SHIMS, pnpm_config_global_shims]
steps:
- uses: actions/checkout@v7
- name: Set up package.json with conflicting devEngines.runtime
run: |
rm -f pnpm-lock.yaml
cat > package.json <<'EOF'
{
"packageManager": "pnpm@12.0.0",
"devEngines": {
"runtime": { "name": "node", "version": "20.19.0", "onFail": "download" }
}
}
EOF
shell: bash
- name: Opt back into context-aware shims
env:
ENV_NAME: ${{ matrix.env_name }}
run: printf '%s={"node":"auto"}\n' "$ENV_NAME" >> "$GITHUB_ENV"
shell: bash
- uses: ./
with:
runtime: node@22
- name: "Test: the project's pin still wins"
run: |
set -e
echo "PNPM_CONFIG_GLOBAL_SHIMS: ${PNPM_CONFIG_GLOBAL_SHIMS}"
if [ "${PNPM_CONFIG_GLOBAL_SHIMS}" = '{"node":false}' ]; then
echo "The action overwrote the setting the workflow provided"
exit 1
fi
actual="$(node --version)"
echo "node --version: ${actual}"
case "${actual}" in
v20.19.0) ;;
*) echo "Expected node v20.19.0 from the context-aware shim, got ${actual}"; exit 1 ;;
esac
shell: bash
runtime-version-fallback:
# `runtime: node` without an `@<version>` suffix should fall back to the
# version declared in devEngines.runtime.
name: 'runtime version falls back to devEngines'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Set up package.json with devEngines.runtime version
run: |
rm -f pnpm-lock.yaml
cat > package.json <<'EOF'
{
"packageManager": "pnpm@12.0.0",
"devEngines": {
"runtime": { "name": "node", "version": "^20.0.0", "onFail": "download" }
}
}
EOF
shell: bash
- id: pnpm
uses: ./
with:
runtime: node
- name: 'Test: node 20 via fallback'
run: |
set -e
actual="$(node --version)"
echo "node --version: ${actual}"
case "${actual}" in
v20.*) ;;
*) echo "Expected node v20.x, got ${actual}"; exit 1 ;;
esac
shell: bash
install-false:
# `install: false` skips the auto-install step even though a manifest is
# present.
name: 'install: false skips pnpm install'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Set up package.json with a dependency
run: |
rm -f pnpm-lock.yaml
cat > package.json <<'EOF'
{
"packageManager": "pnpm@12.0.0",
"dependencies": {
"is-odd": "3.0.1"
}
}
EOF
shell: bash
- uses: ./
with:
version: '12.0.0'
install: false
- name: 'Test: node_modules was not populated'
run: |
set -e
if [ -d node_modules/is-odd ]; then
echo "Expected install: false to skip pnpm install, but node_modules/is-odd exists"
exit 1
fi
# pnpm itself should still be on PATH.
which pnpm
pnpm --version
shell: bash
no-runtime:
# No runtime input, no devEngines.runtime. Action installs pnpm only and
# leaves the runtime outputs empty. With no package.json, `pnpm install`
# is also skipped.
name: 'No runtime, no manifest'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- id: pnpm
uses: ./
with:
version: '12.0.0'
- name: 'Test: pnpm works, runtime outputs are empty'
env:
OUT_NAME: ${{ steps.pnpm.outputs.runtime-name }}
OUT_VERSION: ${{ steps.pnpm.outputs.runtime-version }}
OUT_RUNTIMES: ${{ steps.pnpm.outputs.runtimes }}
run: |
set -e
which pnpm
pnpm --version
if [ -n "${OUT_NAME}" ]; then
echo "Expected outputs.runtime-name to be empty, got '${OUT_NAME}'"
exit 1
fi
if [ -n "${OUT_VERSION}" ]; then
echo "Expected outputs.runtime-version to be empty, got '${OUT_VERSION}'"
exit 1
fi
if [ "${OUT_RUNTIMES}" != "[]" ]; then
echo "Expected outputs.runtimes=[], got '${OUT_RUNTIMES}'"
exit 1
fi
shell: bash
cache-lockfile-verification:
# The action caches pnpm's lockfile verification log, which lives in
# `cacheDir`. Newer pnpm reports that via `pnpm cache path`; older
# releases have no such subcommand and the action derives pnpm's
# per-platform default instead. Guard that derivation 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@v7
- name: Configure a supply-chain policy so the verification runs
# A one-minute floor activates the check without holding back any
# version this repo already locks.
run: |
printf '\nminimumReleaseAge: 1\n' >> pnpm-workspace.yaml
shell: bash
- uses: ./
with:
version: '12.0.0'
runtime: node@22
cache: ${{ matrix.cache }}
- 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
working-directory:
# A project whose root is not the repository root. Running the install at
# the repository root would exit 0 having installed nothing, so assert the
# dependency actually landed. `cache: true` is part of the test: without
# `cache-dependency-path` rebasing onto the working directory it matches no
# lockfile and the restore throws outright.
name: 'Project in a subdirectory'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Move this project into docs/
run: |
set -e
mkdir -p docs
mv package.json pnpm-lock.yaml pnpm-workspace.yaml docs/
node -e "
const fs = require('fs')
const manifest = JSON.parse(fs.readFileSync('docs/package.json', 'utf8'))
manifest.packageManager = 'pnpm@12.0.0'
fs.writeFileSync('docs/package.json', JSON.stringify(manifest, null, 2))
"
shell: bash
- id: pnpm
uses: ./
with:
working-directory: docs
runtime: node@22
cache: true
- name: 'Test: the subdirectory project was installed'
run: |
set -e
if [ ! -d docs/node_modules/@actions/cache ]; then
echo "Expected pnpm install to populate docs/node_modules"
ls -la docs || true
exit 1
fi
if [ -d node_modules ]; then
echo "Did not expect node_modules at the repository root"
exit 1
fi
# `packageManager` was read from docs/package.json, not the root.
pnpm_version="$(pnpm --version)"
if [ "${pnpm_version}" != "12.0.0" ]; then
echo "Expected pnpm 12.0.0 from docs/package.json, got ${pnpm_version}"
exit 1
fi
shell: bash
working-directory-deprecated-input:
# `package-json-file` is deprecated but must keep working exactly as it
# did: the directory holding the file becomes the working directory, and
# an explicit `cache-dependency-path` stays relative to the repository
# root. Rebasing it onto the working directory would look for
# `web/web/pnpm-lock.yaml` and fail the restore.
name: 'Deprecated package-json-file still works'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Move this project into web/
run: |
set -e
mkdir -p web
mv package.json pnpm-lock.yaml pnpm-workspace.yaml web/
node -e "
const fs = require('fs')
const manifest = JSON.parse(fs.readFileSync('web/package.json', 'utf8'))
manifest.packageManager = 'pnpm@12.0.0'
fs.writeFileSync('web/package.json', JSON.stringify(manifest, null, 2))
"
shell: bash
- uses: ./
with:
package-json-file: web/package.json
cache: true
cache-dependency-path: web/pnpm-lock.yaml
- name: 'Test: the install ran in web/'
run: |
set -e
if [ ! -d web/node_modules/@actions/cache ]; then
echo "Expected pnpm install to populate web/node_modules"
ls -la web || true
exit 1
fi
pnpm_version="$(pnpm --version)"
if [ "${pnpm_version}" != "12.0.0" ]; then
echo "Expected pnpm 12.0.0 from web/package.json, got ${pnpm_version}"
exit 1
fi
shell: bash
require-lockfile:
# `require-lockfile` installs against an existing lockfile and fails when
# there is none — the case pnpm's CI default leaves open, since a plain
# install resolves from the registry and exits 0 instead.
name: 'require-lockfile'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Set up a manifest with a matching lockfile
run: |
set -e
rm -f pnpm-lock.yaml
cat > package.json <<'EOF'
{
"packageManager": "pnpm@12.0.0",
"dependencies": {
"is-odd": "3.0.1"
}
}
EOF
shell: bash
- name: Put pnpm on PATH without installing
uses: ./
with:
version: '12.0.0'
install: false
- name: Write the lockfile and record its checksum
run: |
set -e
pnpm install --lockfile-only
sha256sum pnpm-lock.yaml > lockfile.sha256
shell: bash
- uses: ./
with:
version: '12.0.0'
require-lockfile: true
- name: 'Test: installed from the lockfile, which is untouched'
run: |
set -e
if [ ! -d node_modules/is-odd ]; then
echo "Expected require-lockfile to populate node_modules/is-odd"; exit 1
fi
if ! sha256sum --check --status lockfile.sha256; then
echo "Expected a successful require-lockfile install to leave the lockfile alone"; exit 1
fi
shell: bash
- name: Remove the lockfile entirely
run: rm -f pnpm-lock.yaml
shell: bash
- id: missing
continue-on-error: true
uses: ./
with:
version: '12.0.0'
require-lockfile: true
- name: 'Test: a missing lockfile failed the step before pnpm ran'
env:
OUTCOME: ${{ steps.missing.outcome }}
run: |
set -e
echo "outcome: ${OUTCOME}"
if [ "${OUTCOME}" != "failure" ]; then
echo "Expected require-lockfile to fail when no lockfile exists"; exit 1
fi
shell: bash
- name: 'Test: without require-lockfile the same state installs and writes one'
# The contrast the input exists for: pnpm's CI default does not require
# a lockfile, so this succeeds where the step above failed.
run: |
set -e
rm -f pnpm-lock.yaml
shell: bash
- uses: ./
with:
version: '12.0.0'
- name: 'Test: a plain install wrote the lockfile and succeeded'
run: |
set -e
if [ ! -f pnpm-lock.yaml ]; then
echo "Expected a plain install to write a lockfile"; exit 1
fi
shell: bash