mirror of
https://github.com/pnpm/pnpm.git
synced 2026-05-13 02:55:56 -04:00
## Summary Migrates CI workflows from `pnpm/action-setup` + manual `pn runtime set node …` + `pn install` to the new combined `pnpm/setup` action (see https://github.com/pnpm/setup/pull/1). `pnpm/setup` installs pnpm and the JS runtime in one step. It also runs `pnpm install` automatically when a `package.json` is present, so per-workflow install steps are dropped. When the `runtime` input is set, the action passes `--no-runtime` to `pnpm install` so the matrix-selected Node version isn't shadowed by a different `devEngines.runtime` pin. ## What changed | Workflow | Migration | |---|---| | `test.yml` | `pnpm/setup` with `runtime: node@${{ inputs.node }}`. Verify-Node step asserts the matrix version stayed active. Verify-npm step retained as canary (npm comes from the runner image, not the pnpm-installed runtime). | | `ci.yml` | `pnpm/setup` (no `runtime` input — `devEngines.runtime` in package.json handles the Node pin). | | `release.yml` | `pnpm/setup` with `runtime: node@26.0.0`. | | `benchmark.yml` | `pnpm/setup` with `runtime: node@26.0.0`. | | `audit.yml` | `pnpm/setup` with `install: false` — audit only needs pnpm itself, not `node_modules`. | | `update-lockfile.yml` | `pnpm/setup` with `install: false` — the job deletes `pnpm-lock.yaml` and regenerates it via `--lockfile-only`, so the action's auto-install would be wasted. | | `update-latest.yml` | Untouched — it only uses npm, no pnpm setup needed. | ## Caveats / things to watch - **npm availability.** `pnpm runtime set node` does not extract npm. The runner image's pre-installed Node toolchain provides `npm` on PATH; if a future runner image change removes that, dlx-style git-hosted dependency tests in `test.yml` will fail. The `Verify npm` step in `test.yml` is the canary. ## Related upstream change - [pnpm/setup#3](https://github.com/pnpm/setup/pull/3) — added the `install` input so callers like `audit.yml` and `update-lockfile.yml` can opt out of the action's auto-install.
122 lines
3.8 KiB
YAML
122 lines
3.8 KiB
YAML
name: Benchmarks
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
pr_number:
|
|
description: 'PR number to benchmark (works with fork PRs too)'
|
|
required: false
|
|
default: ''
|
|
type: string
|
|
runs:
|
|
description: 'Number of benchmark runs per scenario'
|
|
required: false
|
|
default: '10'
|
|
type: string
|
|
warmup:
|
|
description: 'Number of warmup runs before timing'
|
|
required: false
|
|
default: '1'
|
|
type: string
|
|
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
|
|
jobs:
|
|
benchmark:
|
|
name: Run Benchmarks
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 180
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Checkout PR head
|
|
if: inputs.pr_number != ''
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
PR_NUMBER="${{ inputs.pr_number }}"
|
|
echo "Fetching PR #$PR_NUMBER head..."
|
|
git fetch origin "refs/pull/${PR_NUMBER}/head:refs/remotes/origin/pr-${PR_NUMBER}"
|
|
git checkout "origin/pr-${PR_NUMBER}"
|
|
echo "Checked out PR #$PR_NUMBER at $(git rev-parse --short HEAD)"
|
|
|
|
- name: Install pnpm and Node
|
|
uses: pnpm/setup@b1cac37306e39c21283b9dd6cb0ac288fb35ba6b
|
|
with:
|
|
runtime: node@26.0.0
|
|
|
|
- name: Install hyperfine
|
|
run: |
|
|
wget -q https://github.com/sharkdp/hyperfine/releases/download/v1.18.0/hyperfine_1.18.0_amd64.deb
|
|
sudo dpkg -i hyperfine_1.18.0_amd64.deb
|
|
|
|
- name: Compile
|
|
run: pnpm run compile
|
|
|
|
- name: Run benchmarks
|
|
id: bench
|
|
continue-on-error: true
|
|
run: |
|
|
set -o pipefail
|
|
./benchmarks/bench.sh 2>&1 | tee bench-output.txt
|
|
BENCH_DIR=$(grep "Temp directory kept at:" bench-output.txt | sed 's/Temp directory kept at: //')
|
|
echo "bench_dir=$BENCH_DIR" >> "$GITHUB_OUTPUT"
|
|
env:
|
|
RUNS: ${{ inputs.runs }}
|
|
WARMUP: ${{ inputs.warmup }}
|
|
|
|
- name: Comment on PR
|
|
if: steps.bench.outputs.bench_dir != ''
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
BENCH_DIR="${{ steps.bench.outputs.bench_dir }}"
|
|
RESULTS_FILE="$BENCH_DIR/results.md"
|
|
|
|
if [ ! -f "$RESULTS_FILE" ]; then
|
|
echo "::warning::Results file not found at $RESULTS_FILE"
|
|
exit 0
|
|
fi
|
|
|
|
echo "--- Benchmark Results ---"
|
|
cat "$RESULTS_FILE"
|
|
echo "-------------------------"
|
|
|
|
if [ -n "${{ inputs.pr_number }}" ]; then
|
|
PR_NUMBER="${{ inputs.pr_number }}"
|
|
else
|
|
PR_NUMBER=$(gh pr list --head "${{ github.ref_name }}" --json number --jq '.[0].number' 2>/dev/null || echo "")
|
|
fi
|
|
|
|
if [ -z "$PR_NUMBER" ]; then
|
|
echo "::notice::No open PR found for branch ${{ github.ref_name }}. Results printed above."
|
|
exit 0
|
|
fi
|
|
|
|
MARKER="<!-- pnpm-benchmark-results -->"
|
|
{
|
|
echo "$MARKER"
|
|
cat "$RESULTS_FILE"
|
|
echo ""
|
|
echo "_Run [${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) · ${{ inputs.runs }} runs per scenario · triggered by @${{ github.actor }}_"
|
|
} > /tmp/comment-body.md
|
|
|
|
COMMENT_ID=$(gh api "repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \
|
|
--jq "[.[] | select(.body | startswith(\"$MARKER\"))] | .[0].id // empty" 2>/dev/null || echo "")
|
|
|
|
if [ -n "$COMMENT_ID" ]; then
|
|
echo "Updating existing benchmark comment $COMMENT_ID on PR #$PR_NUMBER"
|
|
gh api "repos/${{ github.repository }}/issues/comments/${COMMENT_ID}" \
|
|
-X PATCH \
|
|
-F "body=@/tmp/comment-body.md"
|
|
else
|
|
echo "Creating new benchmark comment on PR #$PR_NUMBER"
|
|
gh pr comment "$PR_NUMBER" --body-file /tmp/comment-body.md
|
|
fi
|