From f270f3e51f966d39be5bf2f6008683a3ef06c10f Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Tue, 20 Oct 2026 18:32:15 +0200 Subject: [PATCH 1/2] ci: Keep Namespace cache volumes complete and cache the pnpm binary Namespace keeps the cache volume of every job that exits cleanly, and the last write wins. E2E jobs and jobs without cache use had the same tag as the dependency volume, so they often committed an empty or E2E-only volume, and the next Build installed all dependencies again. E2E jobs now use their own tag, and jobs without cache use have no tag. `pnpm/action-setup` downloads pnpm with `pnpm self-update` in every job. The new `mount-pnpm-store` action mounts the pnpm store and the npm cache before `install-pnpm`, so both downloads come from the cache volume. The `pnpm` mode of nscloud-cache-action runs pnpm, so the action sets `PNPM_CONFIG_STORE_DIR` itself until the mode works without pnpm. Co-Authored-By: Claude Opus 5.5 --- .../actions/install-dependencies/action.yml | 9 ++-- .github/actions/mount-pnpm-store/action.yml | 28 +++++++++++++ .github/workflows/build.yml | 41 ++++++++----------- 3 files changed, 48 insertions(+), 30 deletions(-) create mode 100644 .github/actions/mount-pnpm-store/action.yml diff --git a/.github/actions/install-dependencies/action.yml b/.github/actions/install-dependencies/action.yml index 76ca231532f9..420b26b59d49 100644 --- a/.github/actions/install-dependencies/action.yml +++ b/.github/actions/install-dependencies/action.yml @@ -4,9 +4,6 @@ description: 'Installs pnpm dependencies into node_modules folders on the Namesp runs: using: 'composite' steps: - - name: Install pnpm - uses: ./.github/actions/install-pnpm - - name: List dependency paths id: paths run: | @@ -19,11 +16,13 @@ runs: shell: bash - name: Mount dependency cache - uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0 + uses: ./.github/actions/mount-pnpm-store with: - cache: pnpm path: ${{ steps.paths.outputs.paths }} + - name: Install pnpm + uses: ./.github/actions/install-pnpm + # The cache volume can hold node_modules of another commit or branch. This is a no-op when they match # pnpm-lock.yaml. - name: Install dependencies diff --git a/.github/actions/mount-pnpm-store/action.yml b/.github/actions/mount-pnpm-store/action.yml new file mode 100644 index 000000000000..567518bbfe75 --- /dev/null +++ b/.github/actions/mount-pnpm-store/action.yml @@ -0,0 +1,28 @@ +name: 'Mount pnpm store' +description: + 'Mounts the pnpm store, the npm cache and the given paths from the Namespace cache volume. Use it before + `install-pnpm`, so `install-pnpm` takes pnpm from the cache volume.' + +inputs: + path: + description: 'Paths to mount from the cache volume in addition to the pnpm store, one per line.' + required: false + default: '' + +runs: + using: 'composite' + steps: + # Replaces the `pnpm` mode of nscloud-cache-action until it works without pnpm on PATH. The mode runs `pnpm store + # path`, so it only works after `install-pnpm`, when `pnpm self-update` has already downloaded pnpm. + - name: Set pnpm store directory + run: echo "PNPM_CONFIG_STORE_DIR=$HOME/.cache/pnpm-store" >> "$GITHUB_ENV" + shell: bash + + # The `npm` mode keeps the npm cache of the `npm ci` in `pnpm/action-setup`, which installs the bootstrap pnpm + - name: Mount cache paths + uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0 + with: + cache: npm + path: | + ~/.cache/pnpm-store + ${{ inputs.path }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 59962d0d401f..e6ea871caf7d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -52,8 +52,9 @@ env: # This option both controls the `v8-compile-cache-lib` and `v8-compile-cache` packages. DISABLE_V8_COMPILE_CACHE: '1' -# All jobs share one Namespace cache volume through `overrides.cache-tag`. Pull request jobs get their own volume -# (`-pr`), so they cannot change the node_modules that develop and release builds install from. +# Jobs that install the monorepo dependencies share one Namespace cache volume through `overrides.cache-tag`, E2E jobs +# share another one (`-e2e`). Jobs that do not use a cache volume have no cache tag. Pull request jobs get their own +# volumes (`-pr`), so they cannot change the node_modules that develop and release builds install from. jobs: job_get_metadata: uses: ./.github/workflows/ci-metadata.yml @@ -268,9 +269,7 @@ jobs: job_check_branches: name: Check PR branches needs: job_get_metadata - runs-on: - namespace-profile-sentry-javascript-small;overrides.cache-tag=sentry-javascript${{ github.event_name == - 'pull_request' && '-pr' || '' }} + runs-on: namespace-profile-sentry-javascript-small if: github.event_name == 'pull_request' permissions: pull-requests: write @@ -354,9 +353,7 @@ jobs: name: Check lockfile needs: [job_get_metadata] timeout-minutes: 10 - runs-on: - namespace-profile-sentry-javascript;overrides.cache-tag=sentry-javascript${{ github.event_name == 'pull_request' - && '-pr' || '' }} + runs-on: namespace-profile-sentry-javascript if: | needs.job_get_metadata.outputs.changed_deps == 'true' || needs.job_get_metadata.outputs.is_base_branch == 'true' || @@ -1054,8 +1051,8 @@ jobs: always() && needs.job_build_tarballs.result == 'success' && needs.job_build.outputs.e2e-matrix !='{"include":[]}' needs: [job_get_metadata, job_build, job_build_layer, job_build_tarballs] runs-on: - namespace-profile-sentry-javascript;overrides.cache-tag=sentry-javascript${{ github.event_name == 'pull_request' - && '-pr' || '' }} + namespace-profile-sentry-javascript;overrides.cache-tag=sentry-javascript-e2e${{ github.event_name == + 'pull_request' && '-pr' || '' }} timeout-minutes: 15 env: # We just use a dummy DSN here, only send to the tunnel anyhow @@ -1100,13 +1097,11 @@ jobs: uses: denoland/setup-deno@v2.0.5 with: deno-version: ${{ matrix.deno-version || 'v2.8.3' }} - - name: Install pnpm - uses: ./.github/actions/install-pnpm # Keeps the pnpm store on the cache volume for the `pnpm install` of the test application - name: Mount pnpm store - uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0 - with: - cache: pnpm + uses: ./.github/actions/mount-pnpm-store + - name: Install pnpm + uses: ./.github/actions/install-pnpm - name: Restore tarball artifacts uses: actions/download-artifact@v8 @@ -1202,8 +1197,8 @@ jobs: github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]' needs: [job_get_metadata, job_build, job_build_tarballs] runs-on: - namespace-profile-sentry-javascript;overrides.cache-tag=sentry-javascript${{ github.event_name == 'pull_request' - && '-pr' || '' }} + namespace-profile-sentry-javascript;overrides.cache-tag=sentry-javascript-e2e${{ github.event_name == + 'pull_request' && '-pr' || '' }} timeout-minutes: 15 env: E2E_TEST_AUTH_TOKEN: ${{ secrets.E2E_TEST_AUTH_TOKEN }} @@ -1251,13 +1246,11 @@ jobs: uses: denoland/setup-deno@v2.0.5 with: deno-version: ${{ matrix.deno-version || 'v2.8.3' }} - - name: Install pnpm - uses: ./.github/actions/install-pnpm # Keeps the pnpm store on the cache volume for the `pnpm install` of the test application - name: Mount pnpm store - uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0 - with: - cache: pnpm + uses: ./.github/actions/mount-pnpm-store + - name: Install pnpm + uses: ./.github/actions/install-pnpm - name: Restore tarball artifacts uses: actions/download-artifact@v8 @@ -1343,9 +1336,7 @@ jobs: ] # Always run this, even if a dependent job failed if: always() - runs-on: - namespace-profile-sentry-javascript-small;overrides.cache-tag=sentry-javascript${{ github.event_name == - 'pull_request' && '-pr' || '' }} + runs-on: namespace-profile-sentry-javascript-small permissions: {} steps: - name: Check for failures From b18c6c11643989b373ded08d166cf05acd416d76 Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Tue, 20 Oct 2026 20:59:03 +0200 Subject: [PATCH 2/2] fixup! ci: Keep Namespace cache volumes complete and cache the pnpm binary --- .github/actions/mount-pnpm-store/action.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/actions/mount-pnpm-store/action.yml b/.github/actions/mount-pnpm-store/action.yml index 567518bbfe75..fed4e40c1b73 100644 --- a/.github/actions/mount-pnpm-store/action.yml +++ b/.github/actions/mount-pnpm-store/action.yml @@ -1,11 +1,11 @@ name: 'Mount pnpm store' description: - 'Mounts the pnpm store, the npm cache and the given paths from the Namespace cache volume. Use it before + 'Mounts the pnpm store, the pnpm and npm caches and the given paths from the Namespace cache volume. Use it before `install-pnpm`, so `install-pnpm` takes pnpm from the cache volume.' inputs: path: - description: 'Paths to mount from the cache volume in addition to the pnpm store, one per line.' + description: 'Paths to mount from the cache volume in addition to the pnpm store and caches, one per line.' required: false default: '' @@ -14,8 +14,12 @@ runs: steps: # Replaces the `pnpm` mode of nscloud-cache-action until it works without pnpm on PATH. The mode runs `pnpm store # path`, so it only works after `install-pnpm`, when `pnpm self-update` has already downloaded pnpm. - - name: Set pnpm store directory - run: echo "PNPM_CONFIG_STORE_DIR=$HOME/.cache/pnpm-store" >> "$GITHUB_ENV" + # The cache directory holds `lockfile-verified.jsonl`. With it, `pnpm install` skips the supply-chain check of a + # lockfile that was already verified, which otherwise fetches the metadata of every package from the registry. + - name: Set pnpm store and cache directories + run: | + echo "PNPM_CONFIG_STORE_DIR=$HOME/.cache/pnpm-store" >> "$GITHUB_ENV" + echo "PNPM_CONFIG_CACHE_DIR=$HOME/.cache/pnpm" >> "$GITHUB_ENV" shell: bash # The `npm` mode keeps the npm cache of the `npm ci` in `pnpm/action-setup`, which installs the bootstrap pnpm @@ -25,4 +29,5 @@ runs: cache: npm path: | ~/.cache/pnpm-store + ~/.cache/pnpm ${{ inputs.path }}