* chore: update dependencies, Node.js, pnpm, and GitHub Actions
* chore: update pnpm/setup to v3.1.2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: update pnpm/setup examples to v3.1.2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Adds `<version>-alpine`, `<major>-alpine`, and `alpine` tags built from
docker/Dockerfile.alpine with the musl release tarball. Alpine users can
use the image as a base or copy /opt/pnpm into `node:*-alpine` without
fetching the installer from get.pnpm.io, which was returning 403 to
bursts of concurrent CI jobs.
The download, checksum, and version check move into
docker/install-pnpm.sh, shared by both Dockerfiles. The Alpine image
also installs libstdc++ and libgcc, which the musl Node.js builds
installed by `pnpm runtime` need. The Alpine build runs only for
releases that ship musl tarballs for both x64 and arm64, so v11 and
v10 releases skip it.
Every release used to publish the `latest` and `<major>` tags, so a v11
maintenance release moved `latest` back to v11. The builds now push only
the exact version tags. A final step lists the stable releases and, with
`docker buildx imagetools create`, points `<major>` at the highest
version in that major and `latest` at the highest version overall. The
Alpine tags follow the same rule. Deciding after the builds sees every
release of a burst, since lines are published seconds apart. A
concurrency group was rejected because GitHub cancels a pending run when
a third one queues. The selection lives in
.github/scripts/docker-image-tags.sh with a test run by CI, and fails on
an empty release list.
The v12 CI docs now run the Bitbucket Pipelines and GitLab CI examples
in `ghcr.io/pnpm/pnpm:12` instead of downloading the installer, and
recommend the image for CI that runs jobs in containers. CircleCI keeps
the installer because its checkout step needs git and ssh.
The CI examples that still use the standalone script fall back to the
latest pnpm/get.pnpm.io installer release when get.pnpm.io fails. They
run the script only after a download succeeds.
Related to pnpm/pnpm#16973.
* chore: update dependencies, Node.js, pnpm, and GitHub Actions
* chore: hold typescript on 6.x for typescript-eslint compatibility
The update-lockfile job bumped the `typescript` catalog entry to 7.0.2,
which typescript-eslint refuses to load against — it hard-errors at load
with "typescript-eslint does not support TS 7.0" — failing the
Compile & Lint job.
The 7.x compiler is already used for the build via
`@typescript/native-preview` (tsgo); the `typescript` npm package only
serves the JS-API tooling (eslint, jest), which needs 6.x until
typescript-eslint adds TS >=7.1 support
(https://github.com/typescript-eslint/typescript-eslint/issues/10940).
Revert the catalog entry to 6.0.3 and add `typescript` to
`update.ignoreDeps` so the update-lockfile workflow stops re-bumping it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* chore: drop the stray typescript@7.0.2 from the lockfile
openpgp declares an optional `typescript` peer (>=4.7). After the catalog
was reverted to 6.0.3, pnpm's incremental resolution kept openpgp latched
onto the leftover typescript@7.0.2 node, leaving it (and its native
platform packages) in the lockfile and tripping peer-mismatch review bots.
Re-point openpgp's optional peer to 6.0.3 so typescript@7.0.2 is gone
entirely; the openpgp subtree is now identical to the base branch.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Move non-npm-trusted-publishing GitHub Actions jobs to Blacksmith runner labels.
Use larger Blacksmith runners for heavier build, Docker, benchmark, Windows, and macOS jobs, while leaving the npm OIDC trusted-publishing publish jobs on GitHub-hosted runners. npm trusted publishing currently does not support self-hosted runner providers, so the TypeScript pnpm publish job, Rust pnpm publish job, and pnpr publish job keep their GitHub-hosted labels.
Keep benchmark artifact names stable so follow-up workflow_run jobs on the default branch keep matching the producing benchmark jobs.
The Docker workflow can be triggered via workflow_dispatch, and its build job pushes mutable
tags (:latest and :<major>) to ghcr.io/pnpm/pnpm. Unlike release.yml and update-latest.yml,
the build job had no environment gate, so any collaborator with write access could publish an
image to the public mutable tags without reviewer approval.
Add an environment: release gate to the build job so workflow_dispatch runs require approval
from the release environment reviewers, matching the protection already used by the other
publishing workflows. The release (published) event path is unaffected.
Co-authored-by: Claude <noreply@anthropic.com>
Resolves all 30 zizmor alerts reported on main after #11607:
- template-injection (19): move `${{ ... }}` interpolations in `run:` blocks
to `env:` so untrusted-ish values (workflow_dispatch inputs, github.ref_name,
github.actor) can't break out of shell quoting.
- artipacked (8): add `persist-credentials: false` to `actions/checkout` in
audit, benchmark, ci, codeql-analysis, docker, release, test workflows.
`update-lockfile.yml` keeps the persisted token (later step pushes to a
branch) with a `zizmor: ignore[artipacked]` comment and justification.
- dependabot-cooldown (1): add a 7-day cooldown so brand-new (potentially
malicious) Actions releases don't get auto-PR'd day-of-release.
- ref-version-mismatch (1): `bluwy/release-for-reddit-action` SHA pointed at
the `v2` tag, not a non-existent `v2.0.0`. Fix the comment.
- superfluous-actions (1): mark `softprops/action-gh-release` with a
`zizmor: ignore` and justification — the release pipeline is sensitive and
the action is battle-tested; we're not swapping it for `gh release` here.
Verified locally with `zizmor --persona regular .github` (online audits on):
No findings to report. Good job! (2 ignored, 32 suppressed)
---
Written by an agent (Claude Code, claude-opus-4-7).
* feat: publish base docker image to GHCR
Adds a Dockerfile (debian:stable-slim + pnpm standalone binary) and a
release-triggered workflow that builds multi-arch images and pushes to
ghcr.io/pnpm/pnpm. Users who need Node.js can install it inside the
container via `pnpm runtime set node <version>`.
Refs #11300
* docs: add docker/README.md
* chore(cspell): add buildx to dictionary
* docs: mention devEngines.runtime as alternative to pnpm runtime set
* fix(docker): pin base image, verify tarball sha256, harden download
- Pin `debian:stable-slim` to a digest for reproducibility.
- Compute pnpm tarball SHA256 in the workflow and verify it inside the
build, detecting tampered artifacts regardless of what `pnpm --version`
reports.
- Download the tarball to disk with `--retry` instead of `curl | tar`
for resilience under multi-arch QEMU builds.
- README: use `--load` so the local test image is available to `docker run`.
* chore(cspell): sort dictionary additions
* fix(docker): address Copilot review feedback
- Include $PNPM_HOME/bin on PATH so pnpm-installed globals (node, etc.)
are discoverable, and make $PNPM_HOME writable for non-root users.
- Document that `pnpm runtime set node` needs `-g` to install globally.
- Pass workflow inputs via env: instead of inlining GitHub expressions
into shell, and validate the version string before use.
* fix(docker): install libatomic1 for pnpm standalone binary
The pnpm linux standalone binary dynamically links against
libatomic.so.1, which is not present in debian:stable-slim by
default. Without it, `pnpm --version` fails during the build with:
pnpm: error while loading shared libraries: libatomic.so.1:
cannot open shared object file: No such file or directory
Caught by local build testing.