mirror of
https://github.com/mattermost/mattermost.git
synced 2026-09-03 20:53:20 -05:00
Hand Cypress E2E deps to workers as a run-scoped artifact (#38253)
prep-deps wrote node_modules + the Cypress binary to a shared Actions cache keyed on the cypress lockfile, and the 40 workers read it back within the same run. The repo is pinned at the 10 GB Actions cache ceiling (100 entries, 9.99 GB), so LRU eviction runs continuously. Every distinct cypress lockfile a run happens to build costs a ~275 MB entry in that budget — four are live today, 1.10 GB total — and they evict entries other jobs depend on: the webapp node_modules cache (3.7 GB), the Playwright deps cache, and the E2E npm registry cache. Build the deps once in prep-deps and upload them as a run-scoped artifact instead. The handoff is unchanged in shape — one producer, N consumers, within a run — but it costs the shared cache nothing, and it drops the fail-on-cache-miss cliff the workers previously depended on. The artifact name is scoped by edition: e2e-tests-ci.yml invokes this template twice per workflow run (default and fips) and artifact names are run-scoped, so the two invocations would otherwise collide. prep-deps loses its cache-hit shortcut and now always installs, so it restores the master-warmed ~/.npm registry cache read-only to keep that install short, and its timeout goes 10 -> 15 minutes. Playwright still uses the cache handoff; it is a larger payload with a churnier key and follows separately.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
name: "Pack Cypress deps artifact"
|
||||
description: >
|
||||
Tar the Cypress node_modules and binary into a run-scoped artifact for the
|
||||
workers in e2e-tests-cypress-template.yml. The payload must stay in sync with
|
||||
unpack-cypress-deps.
|
||||
|
||||
inputs:
|
||||
fips:
|
||||
description: >
|
||||
Whether this is a FIPS-edition run. e2e-tests-ci.yml invokes the cypress
|
||||
template twice per workflow run — once per edition — and artifact names are
|
||||
run-scoped, so the two invocations would otherwise collide. Must match the
|
||||
unpack step.
|
||||
required: false
|
||||
default: "false"
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
# -C so the archives hold paths relative to their extraction root, letting
|
||||
# unpack extract straight into the workspace and HOME.
|
||||
- name: ci/pack-cypress-deps
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
tar -czf "${RUNNER_TEMP}/cypress-node-modules.tgz" -C "${GITHUB_WORKSPACE}" e2e-tests/cypress/node_modules
|
||||
tar -czf "${RUNNER_TEMP}/cypress-binary.tgz" -C "${HOME}" .cache/Cypress
|
||||
- name: ci/upload-cypress-deps
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: e2e-cypress-deps${{ inputs.fips == 'true' && '-fips' || '' }}
|
||||
path: |
|
||||
${{ runner.temp }}/cypress-node-modules.tgz
|
||||
${{ runner.temp }}/cypress-binary.tgz
|
||||
# Only ever consumed by workers in the same run.
|
||||
retention-days: 1
|
||||
if-no-files-found: error
|
||||
# The tarballs are already gzipped; re-compressing them in the zip
|
||||
# wrapper costs CPU for no gain.
|
||||
compression-level: 0
|
||||
@@ -0,0 +1,27 @@
|
||||
name: "Unpack Cypress deps artifact"
|
||||
description: >
|
||||
Download and extract the run-scoped artifact built by pack-cypress-deps,
|
||||
restoring the Cypress node_modules and binary into place.
|
||||
|
||||
inputs:
|
||||
fips:
|
||||
description: >
|
||||
Whether this is a FIPS-edition run. Must match the pack step so the correct
|
||||
artifact is downloaded.
|
||||
required: false
|
||||
default: "false"
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: ci/download-cypress-deps
|
||||
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
|
||||
with:
|
||||
name: e2e-cypress-deps${{ inputs.fips == 'true' && '-fips' || '' }}
|
||||
path: ${{ runner.temp }}
|
||||
- name: ci/unpack-cypress-deps
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
tar -xzf "${RUNNER_TEMP}/cypress-node-modules.tgz" -C "${GITHUB_WORKSPACE}"
|
||||
tar -xzf "${RUNNER_TEMP}/cypress-binary.tgz" -C "${HOME}"
|
||||
@@ -198,13 +198,12 @@ jobs:
|
||||
echo "workers=$(jq -nc --argjson n "${INPUT_WORKERS}" '[range(1; $n+1)]')" >> $GITHUB_OUTPUT
|
||||
echo "start_time=$(date +%s)" >> $GITHUB_OUTPUT
|
||||
|
||||
# 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.
|
||||
# Build the Cypress deps once and hand them to the workers as a run-scoped
|
||||
# artifact.
|
||||
prep-deps:
|
||||
name: prep-deps
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
@@ -214,23 +213,23 @@ jobs:
|
||||
persist-credentials: false
|
||||
ref: ${{ inputs.commit_sha }}
|
||||
fetch-depth: 1
|
||||
# Provides the @mattermost/eslint-plugin target the cypress install
|
||||
# symlinks to.
|
||||
- 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;
|
||||
# otherwise workers see "cypress npm package installed but binary missing".
|
||||
id: cache-cypress
|
||||
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
|
||||
with:
|
||||
path: |
|
||||
e2e-tests/cypress/node_modules
|
||||
~/.cache/Cypress
|
||||
key: e2e-cypress-deps-${{ runner.os }}-${{ hashFiles('e2e-tests/cypress/package-lock.json') }}
|
||||
# Read-only restore of the registry cache warmed daily from master, so the
|
||||
# install below refetches as little as possible.
|
||||
- name: ci/restore-npm-cache
|
||||
uses: ./.github/actions/restore-e2e-npm-cache
|
||||
# The postinstall downloads the Cypress binary to ~/.cache/Cypress rather
|
||||
# than into node_modules, which is why the artifact carries both.
|
||||
- name: ci/install-cypress-deps
|
||||
if: steps.cache-cypress.outputs.cache-hit != 'true'
|
||||
working-directory: e2e-tests/cypress
|
||||
run: npm ci
|
||||
- name: ci/pack-cypress-deps
|
||||
uses: ./.github/actions/pack-cypress-deps
|
||||
with:
|
||||
fips: ${{ inputs.server_edition == 'fips' }}
|
||||
|
||||
# Register the Test System IO run AFTER prep-deps so workers reach
|
||||
# dispatch-run within Test System IO's inactivity window.
|
||||
@@ -317,14 +316,12 @@ jobs:
|
||||
uses: ./.github/actions/webapp-setup
|
||||
with:
|
||||
read-only: "true"
|
||||
- name: ci/restore-cypress-deps
|
||||
uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
|
||||
# prep-deps built these; it is an ancestor of this job via dispatch-begin,
|
||||
# so the artifact is always present by now.
|
||||
- name: ci/reuse-cypress-deps
|
||||
uses: ./.github/actions/unpack-cypress-deps
|
||||
with:
|
||||
path: |
|
||||
e2e-tests/cypress/node_modules
|
||||
~/.cache/Cypress
|
||||
key: e2e-cypress-deps-${{ runner.os }}-${{ hashFiles('e2e-tests/cypress/package-lock.json') }}
|
||||
fail-on-cache-miss: true
|
||||
fips: ${{ inputs.server_edition == 'fips' }}
|
||||
- name: ci/cloud-init
|
||||
working-directory: e2e-tests
|
||||
run: make cloud-init
|
||||
|
||||
Reference in New Issue
Block a user