From 162270ff442a85ff93bc9d0a3ac8e9e6efbbccfb Mon Sep 17 00:00:00 2001 From: Mattermost Build Date: Thu, 25 Jun 2026 20:31:33 +0200 Subject: [PATCH] ci: replace volatile e2e-platform-pkgs cache with shared webapp-setup (#37182) (#37238) * ci: replace volatile e2e-platform-pkgs cache with shared webapp-setup * ci: replace volatile e2e-platform-pkgs cache in cypress template v2 * ci: tighten prep-deps comments * fix: typo in webapp-setup comment (cherry picked from commit 2d05d063711fdb25f022c961660a031e2f4ae65c) Co-authored-by: Jesse Hallam --- .github/actions/webapp-setup/action.yml | 33 +++++++++++-- .../e2e-tests-cypress-template-v2.yml | 46 ++++-------------- .../e2e-tests-playwright-template-v2.yml | 48 ++++--------------- 3 files changed, 45 insertions(+), 82 deletions(-) diff --git a/.github/actions/webapp-setup/action.yml b/.github/actions/webapp-setup/action.yml index ef09ac4b7a5..3d32e3172af 100644 --- a/.github/actions/webapp-setup/action.yml +++ b/.github/actions/webapp-setup/action.yml @@ -1,6 +1,12 @@ name: "Web app setup" description: "Set up NPM and dependencies" +inputs: + read-only: + description: "Restore from cache without saving" + required: false + default: "false" + runs: using: "composite" steps: @@ -9,8 +15,9 @@ runs: with: node-version-file: ".nvmrc" - name: ci/cache-node-modules + if: inputs.read-only != 'true' uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 - id: cache-node-modules + id: cache-node-modules-rw with: path: | webapp/node_modules @@ -20,16 +27,34 @@ runs: webapp/platform/shared/node_modules webapp/platform/types/node_modules key: node-modules-${{ runner.os }}-${{ hashFiles('webapp/package-lock.json') }} + - name: ci/restore-node-modules + if: inputs.read-only == 'true' + uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + id: cache-node-modules-ro + with: + path: | + webapp/node_modules + webapp/channels/node_modules + webapp/platform/client/node_modules + webapp/platform/components/node_modules + webapp/platform/shared/node_modules + webapp/platform/types/node_modules + key: node-modules-${{ runner.os }}-${{ hashFiles('webapp/package-lock.json') }} + - name: ci/resolve-cache-hit + id: cache-hit + shell: bash + run: | + echo "cache-hit=${{ steps.cache-node-modules-rw.outputs.cache-hit || steps.cache-node-modules-ro.outputs.cache-hit }}" >> $GITHUB_OUTPUT - name: ci/get-node-modules - if: steps.cache-node-modules.outputs.cache-hit != 'true' + if: steps.cache-hit.outputs.cache-hit != 'true' shell: bash working-directory: webapp run: | make node_modules - name: ci/build-platform-packages - # These are built automatically when depenedencies are installed, but they aren't cached properly, so we need to + # These are built automatically when dependencies are installed, but they aren't cached properly, so we need to # manually build them when the cache is hit. They aren't worth caching because they have too many dependencies. - if: steps.cache-node-modules.outputs.cache-hit == 'true' + if: steps.cache-hit.outputs.cache-hit == 'true' shell: bash working-directory: webapp run: | diff --git a/.github/workflows/e2e-tests-cypress-template-v2.yml b/.github/workflows/e2e-tests-cypress-template-v2.yml index a131a56c09e..48c58d9b8a5 100644 --- a/.github/workflows/e2e-tests-cypress-template-v2.yml +++ b/.github/workflows/e2e-tests-cypress-template-v2.yml @@ -198,7 +198,9 @@ jobs: echo "workers=$(jq -nc --argjson n "${INPUT_WORKERS}" '[range(1; $n+1)]')" >> $GITHUB_OUTPUT echo "start_time=$(date +%s)" >> $GITHUB_OUTPUT - # Install cypress node_modules once, then workers restore from cache. + # Install webapp node_modules once via the shared webapp-setup action, then + # workers restore the same stable cache. The node_modules cache is keyed only + # on webapp/package-lock.json and is shared with webapp-ci.yml jobs. prep-deps: name: prep-deps runs-on: ubuntu-24.04 @@ -212,29 +214,8 @@ jobs: persist-credentials: false ref: ${{ inputs.commit_sha }} fetch-depth: 1 - - name: ci/setup-node - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 - with: - node-version-file: ".nvmrc" - - name: ci/cache-platform-pkgs - # `webapp/node_modules/@mattermost/{client,types}` are the workspace - # symlinks Node walks up to find when platform/client requires - # @mattermost/types. Without them, module resolution fails inside - # the slim slice. - id: cache-platform-pkgs - uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 - with: - path: | - webapp/**/node_modules - webapp/platform/client/lib - webapp/platform/types/lib - key: e2e-platform-pkgs-${{ runner.os }}-${{ hashFiles('webapp/package-lock.json', 'webapp/platform/client/src/**', 'webapp/platform/client/tsconfig*.json', 'webapp/platform/types/src/**', 'webapp/platform/types/tsconfig*.json') }} - - name: ci/build-platform-pkgs - # Full webapp install is needed for tsc + workspace linking; the - # postinstall builds platform/{client,types}/lib. We only cache those. - if: steps.cache-platform-pkgs.outputs.cache-hit != 'true' - working-directory: webapp - run: make node_modules + - name: ci/setup-webapp-node-modules + uses: ./.github/actions/webapp-setup - name: ci/cache-cypress-deps # node_modules + the cypress binary (downloaded to ~/.cache/Cypress by # cypress's postinstall, not into node_modules). Both must be cached; @@ -332,21 +313,10 @@ jobs: persist-credentials: false ref: ${{ inputs.commit_sha }} fetch-depth: 0 - - name: ci/setup-node - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - name: ci/setup-webapp-node-modules + uses: ./.github/actions/webapp-setup with: - node-version-file: ".nvmrc" - - name: ci/restore-platform-pkgs - # Built lib/ for @mattermost/client and @mattermost/types, plus the - # webapp workspace symlinks under webapp/node_modules/@mattermost/. - uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 - with: - path: | - webapp/**/node_modules - webapp/platform/client/lib - webapp/platform/types/lib - key: e2e-platform-pkgs-${{ runner.os }}-${{ hashFiles('webapp/package-lock.json', 'webapp/platform/client/src/**', 'webapp/platform/client/tsconfig*.json', 'webapp/platform/types/src/**', 'webapp/platform/types/tsconfig*.json') }} - fail-on-cache-miss: true + read-only: "true" - name: ci/restore-cypress-deps uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: diff --git a/.github/workflows/e2e-tests-playwright-template-v2.yml b/.github/workflows/e2e-tests-playwright-template-v2.yml index 43a22f0e619..6caaeb7988f 100644 --- a/.github/workflows/e2e-tests-playwright-template-v2.yml +++ b/.github/workflows/e2e-tests-playwright-template-v2.yml @@ -163,9 +163,9 @@ jobs: echo "workers=$(jq -nc --argjson n "${INPUT_WORKERS}" '[range(1; $n+1)]')" >> $GITHUB_OUTPUT echo "start_time=$(date +%s)" >> $GITHUB_OUTPUT - # Build @mattermost/client + @mattermost/types and install playwright deps once, - # then workers restore from cache. Playwright only consumes those two packages - # from webapp, so we cache just their built lib/ instead of all of webapp/node_modules. + # Install webapp node_modules once via the shared webapp-setup action, then + # workers restore the same stable cache. The node_modules cache is keyed only + # on webapp/package-lock.json and is shared with webapp-ci.yml jobs. prep-deps: name: prep-deps runs-on: ubuntu-24.04 @@ -179,29 +179,8 @@ jobs: persist-credentials: false ref: ${{ inputs.commit_sha }} fetch-depth: 1 - - name: ci/setup-node - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 - with: - node-version-file: ".nvmrc" - - name: ci/cache-platform-pkgs - # `webapp/node_modules/@mattermost/{client,types}` are the workspace - # symlinks Node walks up to find when platform/client requires - # @mattermost/types. Without them, module resolution fails inside - # the slim slice. - id: cache-platform-pkgs - uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 - with: - path: | - webapp/**/node_modules - webapp/platform/client/lib - webapp/platform/types/lib - key: e2e-platform-pkgs-${{ runner.os }}-${{ hashFiles('webapp/package-lock.json', 'webapp/platform/client/src/**', 'webapp/platform/client/tsconfig*.json', 'webapp/platform/types/src/**', 'webapp/platform/types/tsconfig*.json') }} - - name: ci/build-platform-pkgs - # Full webapp install is needed for tsc + workspace linking; the - # postinstall builds platform/{client,types}/lib. We only cache those. - if: steps.cache-platform-pkgs.outputs.cache-hit != 'true' - working-directory: webapp - run: make node_modules + - name: ci/setup-webapp-node-modules + uses: ./.github/actions/webapp-setup - name: ci/cache-playwright-deps # Caches node_modules + the rolled-up @mattermost/playwright-lib dist # so workers don't re-run rollup on every job. @@ -306,21 +285,10 @@ jobs: persist-credentials: false ref: ${{ inputs.commit_sha }} fetch-depth: 0 - - name: ci/setup-node - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - name: ci/setup-webapp-node-modules + uses: ./.github/actions/webapp-setup with: - node-version-file: ".nvmrc" - - name: ci/restore-platform-pkgs - # Built lib/ for @mattermost/client and @mattermost/types, plus the - # webapp workspace symlinks under webapp/node_modules/@mattermost/. - uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 - with: - path: | - webapp/**/node_modules - webapp/platform/client/lib - webapp/platform/types/lib - key: e2e-platform-pkgs-${{ runner.os }}-${{ hashFiles('webapp/package-lock.json', 'webapp/platform/client/src/**', 'webapp/platform/client/tsconfig*.json', 'webapp/platform/types/src/**', 'webapp/platform/types/tsconfig*.json') }} - fail-on-cache-miss: true + read-only: "true" - name: ci/restore-playwright-deps uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: