From 892fcc0f6c417411d0b52f2804506f07d4b9aa48 Mon Sep 17 00:00:00 2001 From: Ehab Younes Date: Mon, 21 Sep 2026 12:53:31 +0000 Subject: [PATCH] ci: migrate setup to pnpm/setup Replace pnpm/action-setup + actions/setup-node + manual install step with pnpm/setup v3.0.0 (SHA-pinned), which installs pnpm, provisions Node 22 via pnpm runtime set, and runs pnpm install --frozen-lockfile (require-lockfile: true). Also migrates publish-extension.yaml's standalone setup-node usages. The store cache is a restore/save split around actions/cache, the same policy as the Chromium cache: every branch restores (lockfile-hash key, platform prefix fallback so a dependency bump reuses the rest of the store), only the default branch and releases save. pnpm/setup's own cache: true saves per job per run (pnpm/setup#55, pnpm/setup#56), and v2.1.0's runtime-hashed primary key is never matched by its runtime-less restore probe, so every job saved on every run. Measured on this PR's CI with pnpm/setup caching (setup step, warm): Windows 32-37s vs 56-85s baseline, Linux 8-13s. The split keeps those restore times and drops PR post steps to ~1s. Closes #1119 --- .github/actions/setup/action.yml | 48 +++++++++++++++++++----- .github/workflows/ci.yaml | 11 ++++++ .github/workflows/pre-release.yaml | 2 + .github/workflows/publish-extension.yaml | 14 ++++--- .github/workflows/release.yaml | 3 ++ CONTRIBUTING.md | 1 + 6 files changed, 64 insertions(+), 15 deletions(-) diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index f980648f76..858f2819e5 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -1,6 +1,15 @@ name: Setup + description: Install pnpm, Node.js, and project dependencies. +inputs: + cache-save: + description: >- + Save the pnpm store cache after the job. Restores always run; only the + default branch saves, so PR runs cannot race one shared key or evict + each other's stores from the cache quota. + default: "false" + runs: using: composite steps: @@ -9,17 +18,38 @@ runs: # Needed for git-based deps (e.g. github:coder/coder) so pnpm can clone without SSH. run: git config --global url."https://github.com/".insteadOf "git@github.com:" - - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 + - uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0 with: - # Caches the pnpm store, keyed by lockfile hash with a prefix fallback, - # so a dependency bump reuses the rest of the store. setup-node's own - # pnpm cache restores on an exact hash only. - cache: true + runtime: node@22 + # The store cache is handled by the actions/cache steps below, which + # unlike this action's `cache: true` can save only on the default + # branch (pnpm/setup#56 tracks a restore-only mode). + cache: false + require-lockfile: true + + - name: Get pnpm store path + id: pnpm-store + shell: bash + run: echo "path=$(pnpm store path)" >> "$GITHUB_OUTPUT" - - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + # Restores on every branch; saves only where cache-save is set (the + # default branch). Same policy as the Chromium cache in ci.yaml. + - name: Restore pnpm store cache + id: store-cache + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: - node-version: "22" + path: ${{ steps.pnpm-store.outputs.path }} + key: pnpm-store-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pnpm-lock.yaml') }} + restore-keys: pnpm-store-${{ runner.os }}-${{ runner.arch }}- - - name: Install dependencies + - name: Prune unreferenced store packages + if: inputs.cache-save == 'true' shell: bash - run: pnpm install --frozen-lockfile + run: pnpm store prune + + - name: Save pnpm store cache + if: inputs.cache-save == 'true' && steps.store-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ${{ steps.pnpm-store.outputs.path }} + key: ${{ steps.store-cache.outputs.cache-primary-key }} diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6301c1bb6f..0a3283ecd1 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -23,6 +23,9 @@ jobs: persist-credentials: false - name: Setup pnpm, Node.js, and dependencies uses: ./.github/actions/setup + with: + # Only the default branch saves the store cache. + cache-save: ${{ github.ref == 'refs/heads/main' }} - run: pnpm typecheck @@ -61,6 +64,8 @@ jobs: persist-credentials: false - name: Setup pnpm, Node.js, and dependencies uses: ./.github/actions/setup + with: + cache-save: ${{ github.ref == 'refs/heads/main' }} - name: Run tests with Electron ${{ matrix.electron-version }} run: ./scripts/test-electron.sh ${{ matrix.electron-version }} @@ -87,6 +92,8 @@ jobs: persist-credentials: false - name: Setup pnpm, Node.js, and dependencies uses: ./.github/actions/setup + with: + cache-save: ${{ github.ref == 'refs/heads/main' }} - run: pnpm build @@ -106,6 +113,8 @@ jobs: persist-credentials: false - name: Setup pnpm, Node.js, and dependencies uses: ./.github/actions/setup + with: + cache-save: ${{ github.ref == 'refs/heads/main' }} - name: Get Playwright version id: playwright-version @@ -151,6 +160,8 @@ jobs: persist-credentials: false - name: Setup pnpm, Node.js, and dependencies uses: ./.github/actions/setup + with: + cache-save: ${{ github.ref == 'refs/heads/main' }} - name: Get version from package.json id: version diff --git a/.github/workflows/pre-release.yaml b/.github/workflows/pre-release.yaml index dcf2fe403d..00b4b13181 100644 --- a/.github/workflows/pre-release.yaml +++ b/.github/workflows/pre-release.yaml @@ -20,6 +20,8 @@ jobs: - name: Setup pnpm, Node.js, and dependencies uses: ./.github/actions/setup + with: + cache-save: true - name: Extract version from tag id: version diff --git a/.github/workflows/publish-extension.yaml b/.github/workflows/publish-extension.yaml index 43c1310ccb..99c299bbec 100644 --- a/.github/workflows/publish-extension.yaml +++ b/.github/workflows/publish-extension.yaml @@ -34,9 +34,9 @@ jobs: with: persist-credentials: false - - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + - uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0 with: - node-version: "22" + runtime: node@22 - name: Construct package name id: package @@ -77,9 +77,10 @@ jobs: contents: read if: ${{ needs.setup.outputs.hasVscePat == 'true' }} steps: - - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + - uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0 with: - node-version: "22" + runtime: node@22 + install: false - name: Install vsce env: @@ -110,9 +111,10 @@ jobs: contents: read if: ${{ needs.setup.outputs.hasOvsxPat == 'true' }} steps: - - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + - uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0 with: - node-version: "22" + runtime: node@22 + install: false - name: Install ovsx run: npm install -g ovsx@1.2.0 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 44f48751be..c84aa07b61 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -29,6 +29,9 @@ jobs: - name: Setup pnpm, Node.js, and dependencies uses: ./.github/actions/setup + with: + # Release runs refresh the store cache. + cache-save: true - name: Extract version from tag id: version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 18bf8c53fa..9737792952 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -319,6 +319,7 @@ When updating the minimum Node.js version, update these files: - **tsconfig.json**: `extends` (the `@tsconfig/nodeXX` package), `lib` (match base ESNext version) - **esbuild.mjs**: `target` - **.github/workflows/ci.yaml**: `electron-version` and `vscode-version` matrices +- **.github/workflows/publish-extension.yaml**, **.github/actions/setup/action.yml**: `runtime: node@XX` ## Dependencies