Skip to content

Maestro (local): the global maestro-test concurrency group cancels the previously pending run whenever two PRs are waiting; queue: max would keep it one-at-a-time without losing runs #7654

Description

@andreBurnt

Steps to reproduce

  1. Have three Maestro (local) runs overlap, which happens routinely on a weekday morning: run A's Maestro test suite job is executing, run B finishes Build APK and enters the maestro-test group as pending, then run C finishes Build APK.
  2. Look at run B: its Maestro test suite job is cancelled with 0 steps run, at the second C's build completes. C then starts the moment A finishes.

Two instances from the last week (all times UTC, run pages at https://github.com/element-hq/element-x-android/actions/runs/<id>):

date A: running B: pending, then cancelled C: arrives and takes B's place
2026-08-31 33380732765, Maestro 10:13:41 to 10:24:03 33380774144 (#7434 ci/project-isolation), pending from 10:16:55, cancelled 10:20:28 33381138968, Build APK completed 10:20:27, Maestro 10:24:05
2026-09-02 33617290601, Maestro 10:12:10 to 10:24:31 33617864980 (sync-localazy), pending from 10:15:00, cancelled 10:16:14 33618091064, Build APK completed 10:16:13, Maestro 10:24:35

This is GitHub's documented default for a concurrency group: "At most one running job or workflow in a concurrency group at any time. [...] By default, any existing pending job or workflow in the same concurrency group will be canceled and the new queued job or workflow will take its place." (https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/control-the-concurrency-of-workflows-and-jobs)

The group is declared at .github/workflows/maestro-local.yml L76-79 (develop 66c5028, 2026-09-04):

    # Allow only one to run at a time, since they use the same environment.
    # Otherwise, tests running in parallel can break each other.
    concurrency:
      group: maestro-test

Outcome

What did you expect?

Runs wait their turn. One-at-a-time is the right constraint while the suite drives a single shared matrix.org account, as the comment says, but every PR should still end up with a Maestro verdict for its commit.

What happened instead?

  • Run B's PR gets no Maestro result for that commit at all, and nothing re-runs it. The workflow shows cancelled, which reads as "nobody ran it" rather than "another PR bumped it".
  • B's ~10-minute Build APK had already been paid for when the Maestro job was cancelled.
  • Whichever run happens to be pending when the next PR's build finishes loses, so on a busy morning the same PR can be bumped repeatedly.

Proposed fix

One line. GitHub's queue property on the concurrency object exists for exactly this: "To allow more than one pending job or workflow run to wait in the same concurrency group, use the optional queue property." single is the default (at most one pending); max allows up to 100 pending.

    concurrency:
      group: maestro-test
      queue: max

Pending jobs do not occupy a runner, so this adds no runner-minutes; it just stops dropping runs. Still no cancel-in-progress here, since that would cancel another PR's executing run. (The docs note ordering is FIFO by the time each run started waiting, not strictly guaranteed, which is fine for this use.)

A related, separate observation: PRs from forks also take a turn in this group only to fail immediately on the missing MAESTRO_PASSWORD secret, so they add contention for nothing. See #7653.

Your phone model

n/a (CI: reactivecircus/android-emulator-runner, pixel_7_pro, API 33, x86_64)

Operating system version

n/a

Application version and app store

develop @ 66c5028 (CI build of :app:assembleGplayDebug)

Homeserver

matrix.org (the CI test account)

Will you send logs?

No (the CI run pages linked above contain everything)

Will you submit a Pull Request?

No

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions