Files
upstream-mattermost/.github/workflows/e2e-tests-playwright-rolling-upgrades-template.yml
upstream-mirror 240db4e2a7
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Nightly Race / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
snapshot of https://github.com/mattermost/mattermost.git (master, 2026-09-16; blobs > 131072B omitted)
2026-09-16 00:29:55 +05:00

405 lines
18 KiB
YAML

---
name: E2E Tests - Playwright Rolling Upgrades Template
# Tests ONE from-version, given the from-image (upgrade_from_server_image) and the to-image
# (SERVER_IMAGE, built from server_image_* inputs). The caller resolves the from-version matrix
# and invokes this workflow once per entry, so everything here — the test system io run, the
# commit status, the workers — belongs to a single from-version.
#
# Shape mirrors e2e-tests-playwright-template.yml, with the upgrade harness prepended to each
# worker: upgrade-from → upgrade-to leaves that worker's server on the to-image, and dispatch-run
# then draws normal specs against it. The harness itself never goes through test system io —
# upgrade-specs/ lives outside the Playwright testDir, so dispatch-begin cannot enqueue it.
on:
workflow_call:
inputs:
upgrade_from_server_image:
description: "Full from-image reference to upgrade FROM (e.g. mattermostdevelopment/mattermost-enterprise-edition:release-11.9)"
type: string
required: true
upgrade_from_context_label:
description: "From-version label for job/artifact names (e.g. release-11.9, release-11.7-esr)"
type: string
required: true
context_name:
description: "GitHub commit status context name for this from-version"
type: string
required: true
workers:
description: "Number of parallel test system io dispatch workers"
type: number
required: false
default: 20
commit_sha:
type: string
required: true
branch:
type: string
required: true
build_id:
type: string
required: true
server_image_tag:
description: "Server image tag to upgrade TO (e.g., master or short SHA)"
type: string
required: true
server_edition:
description: "Server edition: enterprise (default), fips, or team"
type: string
required: false
default: enterprise
server_image_repo:
description: "Docker registry: mattermostdevelopment (default) or mattermost"
type: string
required: false
default: mattermostdevelopment
server_image_aliases:
description: "Comma-separated alias tags for description"
type: string
required: false
enable_reporting:
type: boolean
required: false
default: false
report_type:
type: string
required: false
ref_branch:
type: string
required: false
pr_number:
type: string
required: false
playwright_project:
description: "Playwright project name (passed to dispatch-begin metadata and dispatch-run --project=)."
type: string
required: false
default: chrome
playwright_retries:
description: "Playwright --retries=N (per-spec, in-process retry of flaky tests)"
type: number
required: false
default: 1
retest_on_fail:
description: "Re-dispatch failed dispatch units once (whole-spec retry, on top of Playwright --retries)"
type: boolean
required: false
default: true
secrets:
MM_LICENSE:
required: false
REPORT_WEBHOOK_URL:
required: false
# Callers must grant: contents: read, statuses: write, id-token: write
permissions:
contents: read
statuses: write
id-token: write
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 }}"
# Job/workflow-level so ci/publish-webhook's `if` can see it (step env is applied after `if`).
REPORT_WEBHOOK_URL: ${{ secrets.REPORT_WEBHOOK_URL }}
jobs:
prepare-run:
runs-on: ubuntu-24.04
permissions:
contents: read
id-token: write
statuses: write
outputs:
composite-identity-json: ${{ steps.composite-identity.outputs.composite-identity-json }}
workers-matrix: ${{ steps.matrix.outputs.workers }}
start_time: ${{ steps.matrix.outputs.start_time }}
steps:
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
ref: ${{ inputs.commit_sha }}
fetch-depth: 1
- name: ci/composite-identity
id: composite-identity
env:
CONTEXT_NAME: ${{ inputs.context_name }}
GITHUB_REPOSITORY: ${{ github.repository }}
MM_BRANCH: ${{ inputs.branch }}
MM_SHA: ${{ inputs.commit_sha }}
PR_NUMBER: ${{ inputs.pr_number }}
run: |
# Same derivation as e2e-tests-playwright-template.yml: drop the `e2e-test/` prefix (the
# framework name already implies E2E in the dashboard) and swap remaining `/` for `-` so
# the dashboard URL is path-safe. The from-version is already part of the context, so it
# carries into the run name for free. The commit-status context itself stays unchanged —
# branch protection and the override workflows depend on it.
NAME="${CONTEXT_NAME#e2e-test/}"
NAME="${NAME//\//-}"
if [ -n "$PR_NUMBER" ]; then
COMPOSITE_IDENTITY=$(jq -nc \
--arg repo "${GITHUB_REPOSITORY}" \
--arg sha "${MM_SHA}" \
--arg run_id "${GITHUB_RUN_ID}" \
--arg name "${NAME}" \
--arg attempt "${GITHUB_RUN_ATTEMPT}" \
--arg branch "${MM_BRANCH}" \
--arg pr "${PR_NUMBER}" \
'{repository:$repo, commit_sha:$sha, gh_run_id:$run_id, name:$name, gh_run_attempt:$attempt, branch:$branch, gh_pr_number:$pr}')
else
COMPOSITE_IDENTITY=$(jq -nc \
--arg repo "${GITHUB_REPOSITORY}" \
--arg sha "${MM_SHA}" \
--arg run_id "${GITHUB_RUN_ID}" \
--arg name "${NAME}" \
--arg attempt "${GITHUB_RUN_ATTEMPT}" \
--arg branch "${MM_BRANCH}" \
'{repository:$repo, commit_sha:$sha, gh_run_id:$run_id, name:$name, gh_run_attempt:$attempt, branch:$branch}')
fi
echo "composite-identity-json=${COMPOSITE_IDENTITY}" >> "$GITHUB_OUTPUT"
- name: ci/matrix
id: matrix
env:
INPUT_WORKERS: ${{ inputs.workers }}
run: |
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.
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:
persist-credentials: false
ref: ${{ inputs.commit_sha }}
fetch-depth: 1
- name: ci/setup-webapp-node-modules
uses: ./.github/actions/webapp-setup
- name: ci/cache-playwright-deps
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
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
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 this from-version's run AFTER prep-deps so workers reach dispatch-run within test
# system io's inactivity window. Workers here have the upgrade harness to get through first, so
# the gap is wider than the full suite's — see the harness note on the workers job.
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:
persist-credentials: false
ref: ${{ inputs.commit_sha }}
fetch-depth: 1
- name: ci/dispatch-begin
uses: mattermost/mattermost-test-system-io/.github/actions/test-system-io-dispatch-begin@1631d8fcea24f4545a0b3b7f77e41c2fe0be4418 # 2026-07-28
with:
use-staging: ${{ vars.E2E_USE_STAGING_TEST_IO_URL != 'false' }}
framework: playwright
repo-dir: ${{ github.workspace }}
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 }}
github-token: ${{ secrets.GITHUB_TOKEN }}
commit-status-context: ${{ inputs.context_name }}
image-tag: ${{ inputs.server_image_tag }}
image-aliases: ${{ inputs.server_image_aliases }}
workers:
name: rolling-upgrade-${{ inputs.upgrade_from_context_label }}-${{ matrix.worker_index }}
runs-on: ubuntu-24.04
# Longer than the full suite's 30m workers: each one upgrades a server before it draws its
# first spec, which costs two image pulls plus the swap.
timeout-minutes: 60
needs: [prepare-run, dispatch-begin]
permissions:
contents: read
id-token: write
strategy:
fail-fast: false
matrix:
worker_index: ${{ fromJSON(needs.prepare-run.outputs.workers-matrix) }}
env:
COMPOSITE_IDENTITY: ${{ needs.prepare-run.outputs.composite-identity-json }}
MM_LICENSE: "${{ secrets.MM_LICENSE }}"
TEST: playwright
BRANCH: "${{ inputs.branch }}"
BUILD_ID: "${{ inputs.build_id }}"
CI_BASE_URL: "rolling-upgrade-${{ inputs.upgrade_from_context_label }}-${{ matrix.worker_index }}"
# The from-image this worker boots on. The to-image it ends up on is SERVER_IMAGE, which
# testConfig picks up for the swap.
PW_UPGRADE_FROM_SERVER_IMAGE: "${{ inputs.upgrade_from_server_image }}"
PW_USE_TESTCONTAINERS: "true"
# Same fixed set as the full suite's workers: dispatch pulls specs from a shared queue, so no
# worker knows in advance which service-tagged spec (e.g. @ldap, @saml) it will draw.
PW_TESTCONTAINERS_SERVICES: "openldap,keycloak,elasticsearch,opensearch,minio,azurite"
# Load-bearing three times over here: upgrade-to has to adopt the stack upgrade-from left
# running, the swap has to keep Postgres and file storage while only the server is replaced,
# and dispatch-run's per-spec invocations all have to land on that same upgraded server.
PW_TESTCONTAINERS_REUSE: "true"
steps:
- name: ci/checkout-actions
# Sparse-checkout just .github/actions from the triggering ref (master)
# so the composite action below is available before the full checkout
# overwrites the workspace with inputs.commit_sha.
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
sparse-checkout: .github/actions
sparse-checkout-cone-mode: true
- name: ci/runner-prep-for-openldap
uses: ./.github/actions/runner-prep-openldap
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: ci/setup-webapp-node-modules
uses: ./.github/actions/webapp-setup
with:
read-only: "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
# Boots the stack on the from-image (global setup) and seeds the baseline. Runs the `setup`
# project as a project dependency. No testcontainers:down first — the runner is fresh, so
# upgrade-from's clean-slate guard has nothing to trip over.
- name: ci/upgrade-from
working-directory: e2e-tests/playwright
run: npx playwright test --project=upgrade-from
# Swaps this worker's server to SERVER_IMAGE in place and re-verifies the baseline.
- name: ci/upgrade-to
working-directory: e2e-tests/playwright
run: npx playwright test --project=upgrade-to
# From here the server is the to-image, upgraded in place, and the rest of the job is the
# normal full suite against it. Nothing is re-prepared in between: an upgrade that needed the
# suite's setup re-run to be usable would not be a passing upgrade. The stack is already up
# and seeded from upgrade-from (whose own `setup` dependency ran there), and each dispatched
# spec brings its own config through pw.initSetup().
#
# Skipped automatically when the harness above failed, since a server that did not survive
# its own upgrade has nothing useful to say about the suite.
- name: ci/dispatch-run
uses: mattermost/mattermost-test-system-io/.github/actions/test-system-io-dispatch-run@1631d8fcea24f4545a0b3b7f77e41c2fe0be4418 # 2026-07-28
with:
use-staging: ${{ vars.E2E_USE_STAGING_TEST_IO_URL != 'false' }}
framework: playwright
composite-identity: ${{ needs.prepare-run.outputs.composite-identity-json }}
repo-dir: ${{ github.workspace }}
artifacts-root: ${{ github.workspace }}/worker-artifacts
github-token: ${{ secrets.GITHUB_TOKEN }}
gh-job-name: rolling-upgrade-${{ inputs.upgrade_from_context_label }}-${{ matrix.worker_index }}
playwright-retries: ${{ inputs.playwright_retries }}
playwright-project: ${{ inputs.playwright_project }}
- name: ci/upload-debug-artifacts
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
# Includes logs/upgrade/{from,to}-mattermost.log (+ highlights, postgres, from-baseline.json)
# captured by saveUpgradePhaseLogs during upgrade-from / upgrade-swap-to / upgrade-to.
name: playwright-rolling-upgrades-${{ inputs.server_edition }}-from-${{ inputs.upgrade_from_context_label }}-debug-${{ matrix.worker_index }}
path: |
e2e-tests/playwright/logs/
e2e-tests/playwright/results/
worker-artifacts/
retention-days: 5
if-no-files-found: ignore
report:
runs-on: ubuntu-24.04
needs: [prepare-run, dispatch-begin, workers]
if: always()
permissions:
contents: read
id-token: write
statuses: write
outputs:
commit_status_description: ${{ steps.summary.outputs.commit_status_description }}
webhook_payload: ${{ steps.summary.outputs.webhook_payload }}
steps:
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: ci/run-summary
id: summary
continue-on-error: true
uses: mattermost/mattermost-test-system-io/.github/actions/test-system-io-summary@e2d5032cfa71a3ad11b0975b135cd221564f2787 # 2026-08-06
with:
use-staging: ${{ vars.E2E_USE_STAGING_TEST_IO_URL != 'false' }}
composite-identity: ${{ needs.prepare-run.outputs.composite-identity-json }}
framework: playwright
report-type: ${{ inputs.report_type }}
image-tag: ${{ inputs.server_image_tag }}
image-aliases: ${{ inputs.server_image_aliases }}
server-image: ${{ env.SERVER_IMAGE }}
pr-number: ${{ inputs.pr_number }}
ref-branch: ${{ inputs.ref_branch }}
commit-status-context: ${{ inputs.context_name }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: ci/publish-webhook
if: inputs.enable_reporting && env.REPORT_WEBHOOK_URL != ''
env:
PAYLOAD: ${{ steps.summary.outputs.webhook_payload }}
run: |
curl -X POST -H "Content-Type: application/json" -d "$PAYLOAD" "$REPORT_WEBHOOK_URL"
- name: ci/assert-results
env:
SUMMARY_OUTCOME: ${{ steps.summary.outcome }}
run: |
[ "$SUMMARY_OUTCOME" = "success" ]