Files
actions/pnpm-install/action.yaml
T
cierzniak e8cc842238 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.
2026-08-10 23:32:51 +02:00

79 lines
3.2 KiB
YAML

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}