mirror of
https://github.com/mattermost/mattermost.git
synced 2026-08-27 05:37:15 -05:00
refactor: speed up E2E test workflows and eliminate npm cache-restore failures (#36599)
Workers no longer run `npm ci` — `node_modules` and framework binaries are restored from actions/cache populated once by a new `prep-deps` job. This closes the intermittent EEXIST/ENOENT failure inside npm's own cacache writer that occasionally fails `npm ci` on a runner. Removing `npm ci` from workers also cuts ~5 min of duplicated install work per worker. dispatch-begin now runs as its own job after prep-deps so it fires once the per-worker test-server setup is the only remaining work before dispatch-run.
This commit is contained in:
@@ -16,25 +16,119 @@ All pipelines follow the **smoke-then-full** pattern: smoke tests run first, ful
|
||||
|
||||
```
|
||||
.github/workflows/
|
||||
├── e2e-tests-ci.yml # PR orchestrator
|
||||
├── e2e-tests-on-merge.yml # Merge orchestrator (master/release branches)
|
||||
├── e2e-tests-on-release.yml # Release cut orchestrator
|
||||
├── e2e-tests-cypress.yml # Shared wrapper: cypress smoke -> full
|
||||
├── e2e-tests-playwright.yml # Shared wrapper: playwright smoke -> full
|
||||
├── e2e-tests-cypress-template.yml # Template: actual cypress test execution
|
||||
└── e2e-tests-playwright-template.yml # Template: actual playwright test execution
|
||||
├── e2e-tests-ci.yml # PR orchestrator
|
||||
├── e2e-tests-on-merge.yml # Merge orchestrator (master/release branches)
|
||||
├── e2e-tests-on-release.yml # Release cut orchestrator
|
||||
├── e2e-tests-cypress.yml # Shared wrapper: routes to v1 or v2 template
|
||||
├── e2e-tests-playwright.yml # Shared wrapper: routes to v1 or v2 template
|
||||
├── e2e-tests-cypress-template-v2.yml # Active: cypress + test-system-io dispatch
|
||||
├── e2e-tests-playwright-template-v2.yml # Active: playwright + test-system-io dispatch
|
||||
├── e2e-tests-cypress-template.yml # Deprecated v1 (legacy in-job execution)
|
||||
└── e2e-tests-playwright-template.yml # Deprecated v1 (legacy in-job execution)
|
||||
```
|
||||
|
||||
> **v1 templates are deprecated.** They remain available behind a feature flag during cutover but receive no further changes. New work targets the v2 templates exclusively. The wrappers route by `vars.E2E_USE_TEST_IO_DISPATCH` — `'true'` selects v2, anything else falls back to v1.
|
||||
|
||||
### Call hierarchy
|
||||
|
||||
```
|
||||
e2e-tests-ci.yml ─────────────────┐
|
||||
e2e-tests-on-merge.yml ───────────┤──► e2e-tests-cypress.yml ──► e2e-tests-cypress-template.yml
|
||||
e2e-tests-on-release.yml ─────────┘ e2e-tests-playwright.yml ──► e2e-tests-playwright-template.yml
|
||||
e2e-tests-on-merge.yml ───────────┤──► e2e-tests-cypress.yml ─────┐
|
||||
e2e-tests-on-release.yml ─────────┘ e2e-tests-playwright.yml ──┤
|
||||
│
|
||||
┌──────────────────────────┘
|
||||
│ routes on E2E_USE_TEST_IO_DISPATCH
|
||||
▼
|
||||
v2 (active) ──► e2e-tests-{cypress,playwright}-template-v2.yml
|
||||
v1 (legacy) ──► e2e-tests-{cypress,playwright}-template.yml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow Architecture (v2)
|
||||
|
||||
v2 splits the template into five jobs — `prepare-run`, `prep-deps`, `dispatch-begin`, `workers` (matrix), and `report` — and pushes spec-level execution to [Test System IO](https://github.com/mattermost/mattermost-test-system-io) so workers stay thin and identical.
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────────────┐
|
||||
│ Template v2: e2e-tests-{cypress,playwright}-template-v2.yml │
|
||||
│ │
|
||||
│ ┌───────────────────┐ ┌──────────────────────────────┐ │
|
||||
│ │ prepare-run │ │ prep-deps │ │
|
||||
│ │ (1 runner) │ parallel │ (1 runner) │ │
|
||||
│ │ │ ◄────────────► │ │ │
|
||||
│ │ • build workers │ │ Cypress: │ │
|
||||
│ │ matrix [1..N] │ │ • cypress/node_modules │ │
|
||||
│ │ • compute commit │ │ • ~/.cache/Cypress (binary)│ │
|
||||
│ │ status context │ │ │ │
|
||||
│ │ • emit composite │ │ Playwright: │ │
|
||||
│ │ identity │ │ • webapp/platform/{client, │ │
|
||||
│ │ │ │ types}/{lib,node_mod} │ │
|
||||
│ │ │ │ • playwright/node_modules │ │
|
||||
│ │ │ │ • playwright/lib/dist │ │
|
||||
│ │ │ │ • ~/.cache/ms-playwright │ │
|
||||
│ │ │ │ (chromium only) │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ │ → saved to actions/cache │ │
|
||||
│ └─────────┬─────────┘ └───────────────┬──────────────┘ │
|
||||
│ │ │ │
|
||||
│ │ ▼ │
|
||||
│ │ ┌──────────────────────────────┐ │
|
||||
│ │ │ dispatch-begin │ │
|
||||
│ │ │ • register run with │ │
|
||||
│ │ │ Test System IO │ │
|
||||
│ │ │ • runs immediately before │ │
|
||||
│ │ │ workers to minimise the │ │
|
||||
│ │ │ inactivity-timeout window │ │
|
||||
│ │ └───────────────┬──────────────┘ │
|
||||
│ │ │ │
|
||||
│ └────────────────────┬─────────────────────┘ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ workers (matrix, fail-fast: false) │ │
|
||||
│ │ Cypress full: N=40 | Playwright full: N=10 │ │
|
||||
│ │ │ │
|
||||
│ │ each worker, in parallel: │ │
|
||||
│ │ 1. sparse-checkout actions + full checkout-repo │ │
|
||||
│ │ 2. setup-node │ │
|
||||
│ │ 3. restore caches ◄─── actions/cache (from prep-deps) │ │
|
||||
│ │ (fail-on-cache-miss: true) │ │
|
||||
│ │ 4. cloud-init + start-server (docker compose stack) │ │
|
||||
│ │ 5. prepare-cypress | prepare-playwright (run setup project) │ │
|
||||
│ │ 6. dispatch-run ──────────────────────────────────┐ │ │
|
||||
│ │ (pulls specs from Test System IO, runs locally, │ │ │
|
||||
│ │ posts result, loops until queue is empty) │ │ │
|
||||
│ │ 7. cloud-teardown │ │ │
|
||||
│ └────────────────────┬────────────────────────────────────┼───────┘ │
|
||||
│ │ │ │
|
||||
│ ▼ │ │
|
||||
│ ┌─────────────────────────────────────────────────┐ │ │
|
||||
│ │ report │ │ │
|
||||
│ │ • pull aggregated results from Test System IO │ ◄────┘ │
|
||||
│ │ • post commit status │ │
|
||||
│ │ • send webhook notification │ │
|
||||
│ └─────────────────────────────────────────────────┘ │
|
||||
└────────────────────────────────────────────────────────────────────────┬─┘
|
||||
│
|
||||
┌───────────────────────────▼───┐
|
||||
│ Test System IO (external) │
|
||||
│ • spec-level dispatch │
|
||||
│ • result aggregation │
|
||||
│ • retry orchestration │
|
||||
└───────────────────────────────┘
|
||||
```
|
||||
|
||||
### Key properties
|
||||
|
||||
- **Spec-level vs. job-level parallelism.** The matrix sizes the runner pool; Test System IO does the spec assignment. Slow specs don't block a worker — fast workers keep pulling the next spec from the queue.
|
||||
- **Cache-only workers.** `prep-deps` installs once per workflow run and saves to `actions/cache`. Every worker restores with `fail-on-cache-miss: true` and runs zero `npm ci`. Eliminates the 40-way `EEXIST/ENOENT` race in npm's shared cacache writer.
|
||||
- **dispatch-begin runs late.** It depends on `prep-deps` so the gap between Test System IO run registration and the first worker calling `dispatch-run` is just per-worker setup (~3–5 min). Registering earlier risks the run timing out before any worker checks in, bulk-failing every spec.
|
||||
- **Playwright slim slice.** Playwright only consumes `@mattermost/client` and `@mattermost/types` from webapp, so prep-deps caches just those two packages' built `lib/` and `node_modules` (~10–30 MB) instead of the full `webapp/node_modules` tree (~1–2 GB).
|
||||
- **Browser/binary caches.** Cypress caches `~/.cache/Cypress` (cypress binary lives outside node_modules); playwright caches `~/.cache/ms-playwright` (chromium only). Both keyed on the framework's lockfile so they invalidate on version bumps.
|
||||
- **No retry plumbing in the template.** Test System IO handles per-spec retries; the workflow only sees aggregated results.
|
||||
|
||||
---
|
||||
|
||||
## Pipeline 1: PR (`e2e-tests-ci.yml`)
|
||||
|
||||
Runs E2E tests for every PR commit after the enterprise docker image is built. Fails if the commit is not associated with an open PR.
|
||||
|
||||
@@ -25,6 +25,12 @@ jobs:
|
||||
cache-dependency-path: |
|
||||
e2e-tests/cypress/package-lock.json
|
||||
e2e-tests/playwright/package-lock.json
|
||||
webapp/package-lock.json
|
||||
- name: ci/npm-cache-verify
|
||||
# Heal any partial/dangling entries left in the restored ~/.npm cache
|
||||
# before running `npm ci`. Avoids the intermittent EEXIST/ENOENT
|
||||
# failures in npm's cacache writer.
|
||||
run: npm cache verify
|
||||
|
||||
# Cypress check
|
||||
- name: ci/cypress/npm-install
|
||||
|
||||
@@ -135,7 +135,7 @@ env:
|
||||
SERVER_IMAGE: "${{ inputs.server_image_repo }}/${{ inputs.server_edition == 'fips' && 'mattermost-enterprise-fips-edition' || inputs.server_edition == 'team' && 'mattermost-team-edition' || 'mattermost-enterprise-edition' }}:${{ inputs.server_image_tag }}"
|
||||
|
||||
jobs:
|
||||
dispatch-begin:
|
||||
prepare-run:
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -193,13 +193,62 @@ jobs:
|
||||
run: |
|
||||
echo "workers=$(jq -nc --argjson n ${{ inputs.workers }} '[range(1; $n+1)]')" >> $GITHUB_OUTPUT
|
||||
echo "start_time=$(date +%s)" >> $GITHUB_OUTPUT
|
||||
|
||||
# Install cypress node_modules once, then workers restore from cache.
|
||||
prep-deps:
|
||||
name: prep-deps
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: ci/checkout-repo
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
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-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') }}
|
||||
- name: ci/install-cypress-deps
|
||||
if: steps.cache-cypress.outputs.cache-hit != 'true'
|
||||
working-directory: e2e-tests/cypress
|
||||
run: npm ci
|
||||
|
||||
# Register the Test System IO run AFTER prep-deps so workers reach
|
||||
# dispatch-run within Test System IO's inactivity window.
|
||||
dispatch-begin:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [prepare-run, prep-deps]
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
statuses: write
|
||||
steps:
|
||||
- name: ci/checkout-repo
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
ref: ${{ inputs.commit_sha }}
|
||||
fetch-depth: 1
|
||||
- name: ci/dispatch-begin
|
||||
uses: mattermost/mattermost-test-system-io/.github/actions/test-system-io-dispatch-begin@a2ea7f005484c28fedf51e16645f6d3bd683fd63 # 2026-05-16
|
||||
with:
|
||||
use-staging: ${{ vars.E2E_USE_STAGING_TEST_IO_URL != 'false' }}
|
||||
framework: cypress
|
||||
repo-dir: ${{ github.workspace }}
|
||||
composite-identity: ${{ steps.composite-identity.outputs.composite-identity-json }}
|
||||
composite-identity: ${{ needs.prepare-run.outputs.composite-identity-json }}
|
||||
total-reports-expected: ${{ inputs.workers }}
|
||||
retest-on-fail: ${{ inputs.retest_on_fail }}
|
||||
cypress-stage: ${{ inputs.cypress_stage }}
|
||||
@@ -217,16 +266,16 @@ jobs:
|
||||
name: dispatch-run-${{ matrix.worker_index }}
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 30
|
||||
needs: dispatch-begin
|
||||
needs: [prepare-run, dispatch-begin]
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
worker_index: ${{ fromJSON(needs.dispatch-begin.outputs.workers-matrix) }}
|
||||
worker_index: ${{ fromJSON(needs.prepare-run.outputs.workers-matrix) }}
|
||||
env:
|
||||
COMPOSITE_IDENTITY: ${{ needs.dispatch-begin.outputs.composite-identity-json }}
|
||||
COMPOSITE_IDENTITY: ${{ needs.prepare-run.outputs.composite-identity-json }}
|
||||
SERVER: "${{ inputs.server }}"
|
||||
MM_LICENSE: "${{ secrets.MM_LICENSE }}"
|
||||
ENABLED_DOCKER_SERVICES: "${{ inputs.enabled_docker_services }}"
|
||||
@@ -260,29 +309,26 @@ jobs:
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: npm
|
||||
cache-dependency-path: "e2e-tests/cypress/package-lock.json"
|
||||
- name: ci/get-webapp-node-modules
|
||||
working-directory: webapp
|
||||
run: make node_modules
|
||||
- name: ci/restore-cypress-deps
|
||||
uses: actions/cache/restore@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') }}
|
||||
fail-on-cache-miss: true
|
||||
- name: ci/cloud-init
|
||||
working-directory: e2e-tests
|
||||
run: make cloud-init
|
||||
- name: ci/start-server
|
||||
working-directory: e2e-tests
|
||||
run: make start-server
|
||||
# `npm ci` in the host context replaces the container-built native
|
||||
# binaries with host-built ones, since the dispatch adapter spawns
|
||||
# `npx cypress run` on the host.
|
||||
- name: ci/prepare-cypress
|
||||
working-directory: e2e-tests/cypress
|
||||
run: npm ci
|
||||
- name: ci/dispatch-run
|
||||
uses: mattermost/mattermost-test-system-io/.github/actions/test-system-io-dispatch-run@a2ea7f005484c28fedf51e16645f6d3bd683fd63 # 2026-05-16
|
||||
with:
|
||||
use-staging: ${{ vars.E2E_USE_STAGING_TEST_IO_URL != 'false' }}
|
||||
framework: cypress
|
||||
composite-identity: ${{ needs.dispatch-begin.outputs.composite-identity-json }}
|
||||
composite-identity: ${{ needs.prepare-run.outputs.composite-identity-json }}
|
||||
repo-dir: ${{ github.workspace }}
|
||||
artifacts-root: ${{ github.workspace }}/worker-artifacts
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -306,7 +352,7 @@ jobs:
|
||||
|
||||
report:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [dispatch-begin, workers]
|
||||
needs: [prepare-run, dispatch-begin, workers]
|
||||
if: always()
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -324,7 +370,7 @@ jobs:
|
||||
uses: mattermost/mattermost-test-system-io/.github/actions/test-system-io-summary@a2ea7f005484c28fedf51e16645f6d3bd683fd63 # 2026-05-16
|
||||
with:
|
||||
use-staging: ${{ vars.E2E_USE_STAGING_TEST_IO_URL != 'false' }}
|
||||
composite-identity: ${{ needs.dispatch-begin.outputs.composite-identity-json }}
|
||||
composite-identity: ${{ needs.prepare-run.outputs.composite-identity-json }}
|
||||
framework: cypress
|
||||
report-type: ${{ inputs.report_type }}
|
||||
image-tag: ${{ inputs.server_image_tag }}
|
||||
|
||||
@@ -101,7 +101,7 @@ env:
|
||||
SERVER_IMAGE: "${{ inputs.server_image_repo }}/${{ inputs.server_edition == 'fips' && 'mattermost-enterprise-fips-edition' || inputs.server_edition == 'team' && 'mattermost-team-edition' || 'mattermost-enterprise-edition' }}:${{ inputs.server_image_tag }}"
|
||||
|
||||
jobs:
|
||||
dispatch-begin:
|
||||
prepare-run:
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -158,13 +158,104 @@ jobs:
|
||||
run: |
|
||||
echo "workers=$(jq -nc --argjson n ${{ inputs.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.
|
||||
prep-deps:
|
||||
name: prep-deps
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: ci/checkout-repo
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
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/@mattermost/client
|
||||
webapp/node_modules/@mattermost/types
|
||||
webapp/platform/client/lib
|
||||
webapp/platform/client/node_modules
|
||||
webapp/platform/types/lib
|
||||
webapp/platform/types/node_modules
|
||||
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/cache-playwright-deps
|
||||
# Caches node_modules + the rolled-up @mattermost/playwright-lib dist
|
||||
# so workers don't re-run rollup on every job.
|
||||
id: cache-playwright
|
||||
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
|
||||
with:
|
||||
path: |
|
||||
e2e-tests/playwright/node_modules
|
||||
e2e-tests/playwright/lib/dist
|
||||
e2e-tests/playwright/lib/node_modules
|
||||
key: e2e-playwright-deps-${{ runner.os }}-${{ hashFiles('e2e-tests/playwright/package-lock.json', 'e2e-tests/playwright/lib/src/**', 'e2e-tests/playwright/lib/package.json', 'e2e-tests/playwright/lib/rollup.config.js', 'e2e-tests/playwright/lib/tsconfig.json') }}
|
||||
- name: ci/install-playwright-deps
|
||||
# `npm ci` creates symlinks at node_modules/@mattermost/{client,types}
|
||||
# → webapp/platform/{client,types}; targets must already be built.
|
||||
# The postinstall then builds lib/dist via rollup. Skip browser
|
||||
# download here — chromium is cached separately below.
|
||||
if: steps.cache-playwright.outputs.cache-hit != 'true'
|
||||
working-directory: e2e-tests/playwright
|
||||
env:
|
||||
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1"
|
||||
run: npm ci
|
||||
- name: ci/cache-playwright-browsers
|
||||
# Cache chromium binary (~150MB) keyed on the playwright lockfile so a
|
||||
# version bump invalidates. Restored by workers; no docker image needed.
|
||||
id: cache-pw-browsers
|
||||
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: playwright-browsers-${{ runner.os }}-${{ hashFiles('e2e-tests/playwright/package-lock.json') }}
|
||||
- name: ci/install-playwright-chromium
|
||||
if: steps.cache-pw-browsers.outputs.cache-hit != 'true'
|
||||
working-directory: e2e-tests/playwright
|
||||
run: npx playwright install chromium
|
||||
|
||||
# Register the Test System IO run AFTER prep-deps so workers reach
|
||||
# dispatch-run within Test System IO's inactivity window.
|
||||
dispatch-begin:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [prepare-run, prep-deps]
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
statuses: write
|
||||
steps:
|
||||
- name: ci/checkout-repo
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
ref: ${{ inputs.commit_sha }}
|
||||
fetch-depth: 1
|
||||
- name: ci/dispatch-begin
|
||||
uses: mattermost/mattermost-test-system-io/.github/actions/test-system-io-dispatch-begin@a2ea7f005484c28fedf51e16645f6d3bd683fd63 # 2026-05-16
|
||||
with:
|
||||
use-staging: ${{ vars.E2E_USE_STAGING_TEST_IO_URL != 'false' }}
|
||||
framework: playwright
|
||||
repo-dir: ${{ github.workspace }}
|
||||
composite-identity: ${{ steps.composite-identity.outputs.composite-identity-json }}
|
||||
composite-identity: ${{ needs.prepare-run.outputs.composite-identity-json }}
|
||||
total-reports-expected: ${{ inputs.workers }}
|
||||
retest-on-fail: ${{ inputs.retest_on_fail }}
|
||||
playwright-project: ${{ inputs.playwright_project }}
|
||||
@@ -177,16 +268,16 @@ jobs:
|
||||
name: dispatch-run-${{ matrix.worker_index }}
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 30
|
||||
needs: dispatch-begin
|
||||
needs: [prepare-run, dispatch-begin]
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
worker_index: ${{ fromJSON(needs.dispatch-begin.outputs.workers-matrix) }}
|
||||
worker_index: ${{ fromJSON(needs.prepare-run.outputs.workers-matrix) }}
|
||||
env:
|
||||
COMPOSITE_IDENTITY: ${{ needs.dispatch-begin.outputs.composite-identity-json }}
|
||||
COMPOSITE_IDENTITY: ${{ needs.prepare-run.outputs.composite-identity-json }}
|
||||
SERVER: "${{ inputs.server }}"
|
||||
MM_LICENSE: "${{ secrets.MM_LICENSE }}"
|
||||
ENABLED_DOCKER_SERVICES: "${{ inputs.enabled_docker_services }}"
|
||||
@@ -214,31 +305,53 @@ jobs:
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: npm
|
||||
cache-dependency-path: "e2e-tests/playwright/package-lock.json"
|
||||
- name: ci/get-webapp-node-modules
|
||||
working-directory: webapp
|
||||
run: make node_modules
|
||||
- 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/@mattermost/client
|
||||
webapp/node_modules/@mattermost/types
|
||||
webapp/platform/client/lib
|
||||
webapp/platform/client/node_modules
|
||||
webapp/platform/types/lib
|
||||
webapp/platform/types/node_modules
|
||||
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
|
||||
- name: ci/restore-playwright-deps
|
||||
uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
|
||||
with:
|
||||
path: |
|
||||
e2e-tests/playwright/node_modules
|
||||
e2e-tests/playwright/lib/dist
|
||||
e2e-tests/playwright/lib/node_modules
|
||||
key: e2e-playwright-deps-${{ runner.os }}-${{ hashFiles('e2e-tests/playwright/package-lock.json', 'e2e-tests/playwright/lib/src/**', 'e2e-tests/playwright/lib/package.json', 'e2e-tests/playwright/lib/rollup.config.js', 'e2e-tests/playwright/lib/tsconfig.json') }}
|
||||
fail-on-cache-miss: true
|
||||
- name: ci/restore-playwright-browsers
|
||||
uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: playwright-browsers-${{ runner.os }}-${{ hashFiles('e2e-tests/playwright/package-lock.json') }}
|
||||
fail-on-cache-miss: true
|
||||
- name: ci/cloud-init
|
||||
working-directory: e2e-tests
|
||||
run: make cloud-init
|
||||
- name: ci/start-server
|
||||
working-directory: e2e-tests
|
||||
run: make start-server
|
||||
# Build once + run the `setup` project so per-spec dispatches can
|
||||
# pass --no-deps and skip plugin-load + server-deployment checks.
|
||||
# Run the `setup` project so per-spec dispatches can pass --no-deps
|
||||
# and skip plugin-load + server-deployment checks. node_modules,
|
||||
# lib/dist, and chromium are all restored from cache.
|
||||
- name: ci/prepare-playwright
|
||||
working-directory: e2e-tests/playwright
|
||||
run: |
|
||||
npm ci
|
||||
npm run build
|
||||
npx playwright test --project=setup
|
||||
run: npx playwright test --project=setup
|
||||
- name: ci/dispatch-run
|
||||
uses: mattermost/mattermost-test-system-io/.github/actions/test-system-io-dispatch-run@a2ea7f005484c28fedf51e16645f6d3bd683fd63 # 2026-05-16
|
||||
with:
|
||||
use-staging: ${{ vars.E2E_USE_STAGING_TEST_IO_URL != 'false' }}
|
||||
framework: playwright
|
||||
composite-identity: ${{ needs.dispatch-begin.outputs.composite-identity-json }}
|
||||
composite-identity: ${{ needs.prepare-run.outputs.composite-identity-json }}
|
||||
repo-dir: ${{ github.workspace }}
|
||||
artifacts-root: ${{ github.workspace }}/worker-artifacts
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -263,7 +376,7 @@ jobs:
|
||||
|
||||
report:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [dispatch-begin, workers]
|
||||
needs: [prepare-run, dispatch-begin, workers]
|
||||
if: always()
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -281,7 +394,7 @@ jobs:
|
||||
uses: mattermost/mattermost-test-system-io/.github/actions/test-system-io-summary@a2ea7f005484c28fedf51e16645f6d3bd683fd63 # 2026-05-16
|
||||
with:
|
||||
use-staging: ${{ vars.E2E_USE_STAGING_TEST_IO_URL != 'false' }}
|
||||
composite-identity: ${{ needs.dispatch-begin.outputs.composite-identity-json }}
|
||||
composite-identity: ${{ needs.prepare-run.outputs.composite-identity-json }}
|
||||
framework: playwright
|
||||
report-type: ${{ inputs.report_type }}
|
||||
image-tag: ${{ inputs.server_image_tag }}
|
||||
|
||||
@@ -179,7 +179,14 @@ jobs:
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: npm
|
||||
cache-dependency-path: "e2e-tests/playwright/package-lock.json"
|
||||
cache-dependency-path: |
|
||||
e2e-tests/playwright/package-lock.json
|
||||
webapp/package-lock.json
|
||||
- name: ci/npm-cache-verify
|
||||
# Heal any partial/dangling entries left in the restored ~/.npm cache
|
||||
# before running `npm ci`. Avoids the intermittent EEXIST/ENOENT
|
||||
# failures in npm's cacache writer.
|
||||
run: npm cache verify
|
||||
- name: ci/get-webapp-node-modules
|
||||
working-directory: webapp
|
||||
run: make node_modules
|
||||
|
||||
Reference in New Issue
Block a user