Skip to content

ci(e2e-v2): New test servers (e2e-test-stack) for mobile CI - #10054

Draft
saturninoabril wants to merge 23 commits into
full-ios-in-prfrom
cursor/e2e-test-automation-v2-02f5
Draft

ci(e2e-v2): New test servers (e2e-test-stack) for mobile CI#10054
saturninoabril wants to merge 23 commits into
full-ios-in-prfrom
cursor/e2e-test-automation-v2-02f5

Conversation

@saturninoabril

@saturninoabril saturninoabril commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds an independent E2E v2 pipeline that does not modify the existing Matterwick workflows (e2e-detox-pr.yml, e2e-maestro-pr.yml, and friends).

v2 leases its own test servers through e2e-test-stack-actions. Each platform has its own create/destroy lifetime (separate batch, hostname prefix, and commit statuses). Stacks are leased only after the matching app artifact succeeds. A failed iOS simulator build skips iOS / iPad / Maestro iOS create+tests; Android still runs if its build passed.

Phase 0 scope: PR only. Templates take run_type / context_suffix / per-platform parallelism so main, release, and CMT can reuse them later.

Detox gates:

  • e2e-test/detox-ios: full phone suite (empty include tags, exclude @ipad_only), 30 workers, stack 30+2
  • e2e-test/detox-android: exclude @ipad_only,@ios_only, 20 workers, stack 20+2
  • e2e-test/detox-ipad: include @ipad_only, 1 worker, stack 1 (SITE_1 only)

Maestro gates:

  • e2e-test/maestro-ios: 1 worker, stack 1 (SITE_1 only), reuses the iOS simulator artifact
  • e2e-test/maestro-android: 1 worker, stack 1 (SITE_1 only), uses the Maestro Android APK (android-maestro-build-files-*)

workflow_dispatch parallelism overrides iOS and Android Detox only; iPad and Maestro stay at 1.

flowchart TD
  PR[pull_request TEMPORARY] --> Wait[wait-for-ci]
  UI[workflow_dispatch Actions UI] --> Wait
  Wait --> DetoxCheck["e2e-test/detox-check"]
  Wait --> MaestroCheck["e2e-test/maestro-check"]
  Wait --> BuildIOS["e2e-test/ios-build or ios-build-cache"]
  Wait --> BuildAndroid["e2e-test/android-build or android-build-cache"]
  Wait --> BuildMaestroAndroid["e2e-test/android-maestro-build or android-maestro-build-cache"]
  BuildIOS --> CreateIOS["create ios stack"]
  BuildIOS --> CreateIpad["create ipad stack"]
  BuildIOS --> CreateMaestroIOS["create maestro-ios stack"]
  BuildAndroid --> CreateAndroid["create android stack"]
  BuildMaestroAndroid --> CreateMaestroAndroid["create maestro-android stack"]
  DetoxCheck --> DetoxIOS[detox-ios]
  DetoxCheck --> DetoxAndroid[detox-android]
  DetoxCheck --> DetoxIpad[detox-ipad]
  MaestroCheck --> MaestroIOS[maestro-ios]
  MaestroCheck --> MaestroAndroid[maestro-android]
  CreateIOS --> DetoxIOS
  CreateAndroid --> DetoxAndroid
  CreateIpad --> DetoxIpad
  CreateMaestroIOS --> MaestroIOS
  CreateMaestroAndroid --> MaestroAndroid
  DetoxIOS --> DestroyIOS["destroy ios stack"]
  DetoxAndroid --> DestroyAndroid["destroy android stack"]
  DetoxIpad --> DestroyIpad["destroy ipad stack"]
  MaestroIOS --> DestroyMaestroIOS["destroy maestro-ios stack"]
  MaestroAndroid --> DestroyMaestroAndroid["destroy maestro-android stack"]
Loading

Ticket Link

E2E test automation v2 (no Matterwick).

Checklist

  • Added or updated unit tests (required for all new features)
  • Has UI changes
  • Includes text changes and localization file updates
  • Have tested against the 5 core themes to ensure consistency between them.
  • Have run E2E tests by adding label E2E/Run (or E2E/Run-iOS / E2E/Run-Android for platform-specific runs).

Device Information

This PR was tested on: GitHub Actions workflows (YAML + Jest). Live Detox / Maestro runs on the E2E v2 workflow after CI is green.

Screenshots

N/A — CI workflow only.

Release Note

NONE

Follow-up on CI

Root Jest picks up .github/actions/**/*.test.js. The v2 helper tests are now Jest suites (same pattern as compute-e2e-build-fingerprint/paths.test.js) so ci / test stays green.

Follow-up on detox-ios subset (run 31996338717, 110 passed / 4 failed)

account.e2e.ts MM-T5114_3 failed because email notifications were disabled, so the option was missing: Email notifications disabled by System Administrator.

  • Fix: set MM_EMAILSETTINGS_SENDEMAILNOTIFICATIONS=true on the v2 stack and patch the same flag during provision.

global_threads.e2e.ts MM-T4805_4 expected hardcoded admin, but the test-stack starter is sysadmin: Global threads starter display name is sysadmin.

  • Fix: assert adminUsername from test config (workers already set ADMIN_USERNAME from stack credentials). MM-T4805_5 was a cascade from that failure.

Phase 6

The @ios_pr / 8-worker subset is green, so PR defaults moved to the full phone suite. Worker counts are now iOS 30 / Android 20 / iPad 1. workflow_dispatch can still override iOS and Android Detox parallelism (iPad and Maestro stay at 1).

Instances from create artifact

Create no longer passes the instances JSON through reusable-workflow outputs. Masked admin passwords caused GitHub to redact that output, so workers saw INSTANCES as empty. Workers now download e2e-create-<batch_id> and bind instances[shard-1] as SITE_1. Phone stacks also bind the last two entries as SITE_2 / SITE_3. iPad and Maestro bind SITE_1 only.

instance_key

Per-platform hostname prefixes (toolkit limit 24 characters): mobile-pr-<n>-ios, mobile-pr-<n>-and, mobile-pr-<n>-ipad, mobile-pr-<n>-mios, mobile-pr-<n>-mand (android is and so mobile-release-cut-and fits). Same pattern for main / release / release-cut.

Follow-up: create workflow parse error

GitHub rejected e2e-stack-create-v2.yml at parse time (Unexpected symbol: '+') because expressions cannot add fromJSON(...) values. Instance count is now $((WORKERS + EXTRAS)) in bash.

Follow-up: temporary pull_request trigger

workflow_run on ci never started E2E on this PR because that trigger always uses the default-branch workflow file, and e2e-pr-v2.yml is not on main. TEMPORARY: listen on pull_request so remaining phases can run (Actions job rows will appear). workflow_dispatch stays so the GitHub Actions UI can run a chosen ref. Before review: switch back to workflow_run on ci completed and keep workflow_dispatch.

Follow-up: Node 24 action pins

ci.yml, prepare-node-deps, and test-coverage now pin checkout / setup-node / cache / artifacts to current Node 24 SHAs. Coverage PR comments use actions/github-script instead of thollander/actions-comment-pull-request (still Node 20).

Follow-up: S3 build cache on ubuntu-24.04

Fingerprint + S3 restore for iOS/Android artifacts runs on ubuntu-24.04. macos-26 / ubuntu-latest-8-cores start only on a cache miss.

Follow-up: lease stacks after builds

Create jobs now needs the matching build. iOS simulator success gates Detox iOS, Detox iPad, and Maestro iOS. Android Detox APK gates Detox Android. Maestro Android APK gates Maestro Android.

Follow-up: Maestro first run (run 32140040219)

Android: 5/15 passed (account + clock_display green). iOS: 0 passed; worker cancelled at 60m with 1 spec missed.

Cause: exclude_tags.json no longer excluded @android_only, @ios_only, or @multi_device, so Test System IO leased Calls on iOS and six two-device flows on one worker. iOS login also tapped the LDAP placeholder (Email, Username or AD/LDAP Username); the v2 stack does not enable LDAP, so the field is Email or Username. Android uses the username testID, which is why those account flows passed.

file_type_preview (MM-T3244) ran without seed_file_preview.ts and looked for id: undefined-file-container. Android call_ui_permission hit the 9m Maestro timeout (emulator WebRTC); the next Calls/bookmark flows failed in 0s, then Maestro recovered.

Fix: restore platform + @multi_device + MM-T3244 excludes, and match iOS login with Email.*Username.*.

Existing v1 Matterwick E2E is unchanged.

Open in Web Open in Cursor 

cursoragent and others added 5 commits August 17, 2026 04:47
Add reusable pieces the v2 pipeline needs without changing existing
workflows: wait for the mobile ci workflow, Matterwick-equivalent MM_*
server_env, and a tested splitter that gives each worker its own SITE_1
plus two shared extras.

Co-authored-by: saturnino <saturnino@mattermost.com>
Separate build workflow from test orchestration. Posts e2e-test/ios-build
or e2e-test/ios-build-cache (and the Android equivalents) so a cache hit
is visible as its own commit status. Reuses the existing S3 fingerprint
cache without modifying v1 workflows.

Co-authored-by: saturnino <saturnino@mattermost.com>
Create worker_count dedicated SITE_1 servers plus two shared extras
(SITE_2, SITE_3) using the toolkit create/credentials/destroy actions.
Base stack only (server + postgres + inbucket). Admin passwords stay in
the leasing job; workers fetch their own credentials by batch index.

Co-authored-by: saturnino <saturnino@mattermost.com>
v2 iOS template assigns each worker its own SITE_1 from the leased
batch, shares SITE_2/SITE_3, fetches stack admin credentials over OIDC,
and keeps dispatch-begin / dispatch-run / summary. The detox-v2
dispatcher is reusable for main/release/CMT later.

Co-authored-by: saturnino <saturnino@mattermost.com>
New E2E v2 entry workflow. On pull_request it waits for ci (lint, format,
tsc, unit tests), then runs detox/maestro checks, separate iOS and
Android artifact builds, leases a per-worker test stack, and runs
detox-ios with @ios_pr / 8 workers. Existing v1 workflows are untouched.

Co-authored-by: saturnino <saturnino@mattermost.com>
@saturninoabril saturninoabril changed the title ci(e2e-v2): add Matterwick-free E2E pipeline after mobile CI ci(e2e-v2): New test servers (e2e-test-stack) for mobile CI Aug 17, 2026
Root Jest picks up .github/actions/**/*.test.js (same as the fingerprint
paths tests). The v2 helpers used node:test, so CI reported empty suites
and failed test-coverage. Switch them to Jest describe/it/expect.

Co-authored-by: saturnino <saturnino@mattermost.com>
@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown

Coverage Comparison Report

Generated on August 21, 2026 at 06:25:37 UTC

+-----------------+------------+------------+-----------+
| Metric          | Main       | This PR    | Diff      |
+-----------------+------------+------------+-----------+
| Lines           |     88.39% |     88.39% |     0.00% |
| Statements      |     88.25% |     88.25% |     0.00% |
| Branches        |     77.33% |     77.33% |     0.00% |
| Functions       |     87.73% |     87.70% |    -0.03% |
+-----------------+------------+------------+-----------+
| Total           |     85.42% |     85.41% |    -0.01% |
+-----------------+------------+------------+-----------+

cursoragent and others added 17 commits August 17, 2026 06:12
MM-T5114_3 failed because SendEmailNotifications was off, so the
email settings screen had no Immediately option. Set the MM env var
on the v2 stack and patch the same flag during provision.

Co-authored-by: saturnino <saturnino@mattermost.com>
MM-T4805_4 expected hardcoded 'admin', but the test-stack admin
username is sysadmin. Use adminUsername from test config instead.

Co-authored-by: saturnino <saturnino@mattermost.com>
The @ios_pr subset is green, so PR defaults now use empty include
tags and 20 SITE_1 workers. @ipad_only stays excluded.

Co-authored-by: saturnino <saturnino@mattermost.com>
Move MM_* settings into e2e-stack-create-v2.yml (SERVICEENVIRONMENT
first, then alphabetical) and omit wait_for_migrations so the toolkit
default of false applies.

Co-authored-by: saturnino <saturnino@mattermost.com>
Create now returns only batch_id and instances. Detox and iOS workers
read each site URL and admin credentials from that array instead of a
credentials fetch, site split, or MM_MOBILE_E2E_ADMIN_* secrets.

Co-authored-by: saturnino <saturnino@mattermost.com>
GitHub expressions cannot add fromJSON values, which rejected the create
workflow at parse time. Count workers plus extras in bash instead.

Post e2e-test/test-servers-created and test-servers-destroyed on the PR
SHA, and start the entry workflow from workflow_run so Actions job rows
do not become required checks. Pin v2 actions to current Node 24 SHAs.

Co-authored-by: saturnino <saturnino@mattermost.com>
Checkout, setup-node, cache, and artifacts in ci and test-coverage now
use latest stable SHA pins. Coverage PR comments use github-script so
the Node 20 thollander action is gone.

Co-authored-by: saturnino <saturnino@mattermost.com>
workflow_run only reads the default-branch file, so E2E never started
on this PR. Temporarily listen on pull_request so remaining phases can
run. Keep workflow_dispatch for the GitHub Actions UI. Switch back to
workflow_run before review.

Co-authored-by: saturnino <saturnino@mattermost.com>
Use github.run_number so hostnames are mobile-pr-<n>-<run>,
mobile-main-<run>, mobile-release-<run>, or mobile-release-cut-<run>.
The toolkit still refuses keys longer than 24 characters.

Co-authored-by: saturnino <saturnino@mattermost.com>
Masked admin passwords emptied the instances reusable-workflow output,
so every detox worker saw INSTANCES as blank. Pass response_artifact
instead and have workers download e2e-create-<batch_id>.

instance_key is mobile-pr-<n>, mobile-main, mobile-release, or
mobile-release-cut — no GitHub run number.

Co-authored-by: saturnino <saturnino@mattermost.com>
Fingerprint and cache restore now run on ubuntu-24.04. macos-26 and
ubuntu-latest-8-cores start only when that check misses, so a cache hit
does not provision the expensive builders.

Co-authored-by: saturnino <saturnino@mattermost.com>
PR E2E now runs three Detox legs against one shared test stack
(max worker count SITE_1s + two extras). iPad stays at a single
worker for now; dispatch parallelism overrides iOS and Android only.

Co-authored-by: saturnino <saturnino@mattermost.com>
iOS, Android, and iPad lease and release independent batches so
their lifetimes no longer block each other. iPad stacks are SITE_1
only (extra_count=0); phone stacks keep SITE_2 and SITE_3.

Co-authored-by: saturnino <saturnino@mattermost.com>
Maestro iOS and Android each run one worker against a SITE_1-only
stack. Create waits for the matching app artifact so a failed iOS
build does not lease iOS servers or block Android, and vice versa.

Co-authored-by: saturnino <saturnino@mattermost.com>
Test System IO leased Calls and @multi_device flows after those tags
were dropped from exclude_tags.json. iOS login also required the LDAP
placeholder, which the v2 stack does not enable.

Co-authored-by: saturnino <saturnino@mattermost.com>
Fetch instance 0 logs via the toolkit action, upload them, then release so teardown still runs if collection fails.
Live control plane requires those fields on create, destroy, fetch, and logs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants