feat: add pnpm-install as a shared composite action
Lifts ptpa_pl's local .gitea/actions/pnpm-install into this repo, parametrised enough for repositories we have not met yet: working-directory, install args, pnpm version and an opt-in store cache. Cache is off by default. ADR-0014 pins actions/cache to major 3 and no workflow on this instance has exercised the cache server yet - a shared action that a dozen jobs hang off is the wrong place to premiere that dependency. Two traps found while testing against ptpa_pl's lockfile in node:24-bookworm-slim, both avoided by pinning the store instead of reading `pnpm store path`: that command defaults to <workspace>/.pnpm-store, inside the working tree where a committing job could sweep it up, and it exits 0 while printing its error to stdout, which would have fed actions/cache a garbage path silently. The version input also carries COREPACK_ENABLE_PROJECT_SPEC=0, without which a packageManager field outranks `corepack prepare --activate` and the input would do nothing at all - no effect, no error.
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
name: Install pnpm dependencies
|
||||
description: >-
|
||||
Activates pnpm through corepack and installs dependencies from the lockfile. The version comes
|
||||
from the packageManager field unless overridden; the store cache is opt-in.
|
||||
|
||||
inputs:
|
||||
working-directory:
|
||||
description: Directory holding package.json and pnpm-lock.yaml.
|
||||
required: false
|
||||
default: '.'
|
||||
version:
|
||||
description: >-
|
||||
pnpm version. Empty takes it from the packageManager field; a value overrides that field
|
||||
and stops it from being enforced.
|
||||
required: false
|
||||
default: ''
|
||||
args:
|
||||
description: Full argument list for `pnpm install`; setting it drops the default --frozen-lockfile.
|
||||
required: false
|
||||
default: --frozen-lockfile
|
||||
cache:
|
||||
description: Set to "true" to cache the pnpm store between jobs.
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Activate pnpm
|
||||
shell: bash
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
env:
|
||||
COREPACK_ENABLE_DOWNLOAD_PROMPT: '0'
|
||||
VERSION: ${{ inputs.version }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
corepack enable
|
||||
if [ -n "${VERSION}" ]; then
|
||||
corepack prepare "pnpm@${VERSION}" --activate
|
||||
# `prepare --activate` only sets the default corepack falls back to; a packageManager
|
||||
# field outranks it, so without this the input would silently do nothing on every repo
|
||||
# that has one. Written to GITHUB_ENV so the install step sees it too.
|
||||
echo "COREPACK_ENABLE_PROJECT_SPEC=0" >> "$GITHUB_ENV"
|
||||
fi
|
||||
|
||||
# The store is pinned instead of read back from `pnpm store path`, because that command
|
||||
# defaults to <workspace>/.pnpm-store - inside the working tree, where a job that commits
|
||||
# could sweep it up - and because it exits 0 while printing its error to stdout, which would
|
||||
# silently feed garbage to actions/cache. Only npm_config_store_dir moves it; PNPM_STORE_DIR
|
||||
# is not a pnpm setting. Set here rather than as a step env so it also reaches the install
|
||||
# step, and only when caching is on, so the default path keeps pnpm's own store placement.
|
||||
- name: Pin store and compute cache key
|
||||
id: store
|
||||
if: inputs.cache == 'true'
|
||||
shell: bash
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
echo "npm_config_store_dir=${HOME}/.pnpm-store" >> "$GITHUB_ENV"
|
||||
echo "key=$(sha256sum pnpm-lock.yaml | cut -d ' ' -f 1)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# actions/cache stays on major 3: from v4.2 it speaks a cache service protocol Gitea does
|
||||
# not implement. Read ADR-0014 in gitea-runner/images before letting Renovate bump this.
|
||||
- name: Cache pnpm store
|
||||
if: inputs.cache == 'true'
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-store-${{ runner.os }}-${{ steps.store.outputs.key }}
|
||||
restore-keys: pnpm-store-${{ runner.os }}-
|
||||
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
env:
|
||||
ARGS: ${{ inputs.args }}
|
||||
# ARGS stays unquoted on purpose - it carries a list of flags, not a single argument.
|
||||
run: pnpm install ${ARGS}
|
||||
Reference in New Issue
Block a user