Files
pnpm/.github/workflows/ecosystem-e2e.yml
T
Zoltan Kochan 28bb2a339b ci: reference same-repository actions and workflows with the self-repository syntax (#14452)
zizmor's self-repository audit flags every `uses: ./.github/...` reference
now that GitHub has a dedicated `$/` form. The `$/` form resolves against the
workflow's own commit rather than the runtime checkout, so it cannot load an
action cloned into the workspace at runtime, and GitHub treats it as pinned.

Rewrites all 22 references (18 local actions, 4 reusable workflow calls).

With the `$/` form the runner downloads the whole repository as an action
archive at job setup, and that download fails on any broken symlink in the
tree. The four broken symlinks were all test fixtures: the directory-fetcher
and cafs tests now copy their fixture into a temp dir and create the broken
symlink there, and the has-not-outdated-deps fixture drops two dangling
node_modules links that `pnpm outdated` never followed.

pnpm's GitHub Actions dependency discovery only followed `./` references
into local actions and reusable workflows; both stacks now follow `$/` too.
2026-09-02 13:58:57 +02:00

129 lines
4.7 KiB
YAML

name: Ecosystem E2E
# Installs real-world JS stacks (Next.js, Vite, …) with both the pnpm CLI
# and pacquet, under both the default isolated layout and the global virtual
# store, then builds and serves each app. The binary axis catches pnpm↔pacquet
# parity gaps; the layout axis catches breakage introduced by the global
# virtual store. Runs on a daily cron rather than per-PR — the installs are
# slow and track upstream framework releases, so a red cell is investigated,
# not treated as a merge blocker.
permissions:
contents: read
on:
workflow_dispatch:
schedule:
- cron: '0 6 * * *'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# Compile pacquet, the harness, and the pnpm bundle once, then share them
# with every stack job — building them per stack would repeat the same
# multi-minute Rust and bundle builds across the whole matrix.
build:
if: github.repository == 'pnpm/pnpm' # Only run on the main repository, not forks
name: Ecosystem E2E / Build
runs-on: blacksmith-8vcpu-ubuntu-2404
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install pnpm
uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0
- name: Setup Rust toolchain
uses: $/.github/actions/rustup
- name: Build pnpm and the harness
run: cargo build --release --bin pnpm --bin ecosystem-e2e
- name: Build the pnpm CLI bundle
run: |
pnpm install --frozen-lockfile
pnpm --filter 'pnpm' run compile
- name: Upload build outputs
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ecosystem-e2e-build
path: |
target/release/pnpm
target/release/ecosystem-e2e
pnpm11/pnpm/dist
retention-days: 1
if-no-files-found: error
ecosystem-e2e:
if: github.repository == 'pnpm/pnpm' # Only run on the main repository, not forks
name: Ecosystem E2E / ${{ matrix.stack }}
needs: build
runs-on: blacksmith-8vcpu-ubuntu-2404
# Bound the blast radius: a hung build or serve subprocess can't pin a
# runner indefinitely.
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
# One stack per job so a slow or flaky stack can't mask the others
# and each gets its own log artifact.
stack: [next, vite-react, angular, astro, sveltekit, nuxt, react-router]
steps:
# The pnpm shim launches the repo's committed `pnpm11/pnpm/bin/pnpm.cjs`, so the
# checkout is still needed alongside the downloaded `pnpm11/pnpm/dist` bundle.
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install Node
# The runner image's system Node is older than the bundle's floor
# (`node:sqlite` needs >= 22.13). Installs the `devEngines.runtime`
# pin, which the harness passes to every subprocess through PATH.
uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0
with:
install: false
- name: Download build outputs
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: ecosystem-e2e-build
path: .
- name: Restore executable bits
# Artifacts don't preserve the executable bit.
run: chmod +x target/release/pnpm target/release/ecosystem-e2e
- name: Wrap the built pnpm bundle as an executable
# The harness takes a single executable for --pnpm; the launcher is a
# .cjs that needs `node`. Wrap the repo's bin entry (which loads
# dist/pnpm.mjs) so the run tests this repo's pnpm, not a system one.
run: |
printf '#!/usr/bin/env bash\nexec node "%s/pnpm11/pnpm/bin/pnpm.cjs" "$@"\n' "$PWD" > pnpm-built
chmod +x pnpm-built
- name: Run ecosystem E2E
run: |
./target/release/ecosystem-e2e \
--pnpm "$PWD/pnpm-built" \
--pacquet "$PWD/target/release/pnpm" \
--binary both \
--layout both \
--stack ${{ matrix.stack }} \
--work-dir "$RUNNER_TEMP/ecosystem-e2e-work"
- name: Upload cell logs
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ecosystem-e2e-logs-${{ matrix.stack }}
path: ${{ runner.temp }}/ecosystem-e2e-work/**/*.log
retention-days: 7
if-no-files-found: ignore