From 4bd113518f3a5462ab52c9efca7bc4bcad4681b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=93=E8=89=AF?= <1204183885@qq.com> Date: Thu, 25 Jun 2026 14:09:08 +0800 Subject: [PATCH] ci: give each CI job one home in the merge-queue flow (#5842) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the merge queue is live, each job should run in exactly one place instead of doubling up. - CodeQL and E2E leave the merge queue (CodeQL gains a merge_group guard, E2E loses its merge_group trigger). Neither is a required check, so neither gated a merge — CodeQL just ran ~30min and got cancelled at merge every time, and the three E2E jobs burned ~25/36/36min of hosted time, for nothing. They keep running post-merge on push to main. - macOS/Windows move to merge_group only (they were also running on push to main), and the ubuntu Test job stops running on push too. The queue already tests the merged tree, so re-running these gate jobs on the post-merge push is redundant. Net: PR runs ubuntu; the merge queue runs ubuntu + integration + mac + win (the gate); push to main runs CodeQL + E2E (the backstop). No job runs in two of those. --- .github/workflows/ci.yml | 32 +++++++++++++++++++------------- .github/workflows/e2e.yml | 12 +++++++----- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b00297cf1..d95b6a31d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,7 +111,9 @@ jobs: needs: 'classify_pr' # Stay running on release-sync PRs so the required Test contexts still # report; the per-step skip_ci guards below make them no-op (pass) there. - if: '${{ !cancelled() }}' + # Not on push: the merge queue already tested the merged tree, so a + # post-merge re-run on `main` would be redundant. + if: "${{ !cancelled() && github.event_name != 'push' }}" runs-on: '${{ fromJSON(needs.classify_pr.outputs.ubuntu_runner || ''["ubuntu-latest"]'') }}' permissions: contents: 'read' @@ -272,16 +274,18 @@ jobs: name: 'coverage-reports-22.x-ubuntu-latest' path: 'packages/*/coverage' - # macOS/Windows: slowest/costliest runners, rare platform regressions — skip - # on PR, run on push to `main` and in the merge queue. Two named jobs, not a - # matrix: a skipped matrix job reports one collapsed check name, never the - # per-OS required contexts, so PRs would sit "Expected" forever and never - # enter the queue. A skipped named job reports under its exact name and - # satisfies the required check (same as the Integration Tests job). + # macOS/Windows: slowest/costliest runners, rare platform regressions — run + # only in the merge queue. Skipped on PR (ubuntu is the fast PR signal) and on + # push (the queue already tested the merged tree, so a post-merge re-run is + # redundant). Two named jobs, not a matrix: a skipped matrix job reports one + # collapsed check name, never the per-OS required contexts, so PRs would sit + # "Expected" forever and never enter the queue. A skipped named job reports + # under its exact name and satisfies the required check (same as the + # Integration Tests job). test_macos: name: 'Test (macos-latest, Node 22.x)' needs: 'classify_pr' - if: "${{ !cancelled() && github.event_name != 'pull_request' }}" + if: "${{ !cancelled() && github.event_name == 'merge_group' }}" runs-on: 'macos-latest' permissions: contents: 'read' @@ -329,7 +333,7 @@ jobs: test_windows: name: 'Test (windows-latest, Node 22.x)' needs: 'classify_pr' - if: "${{ !cancelled() && github.event_name != 'pull_request' }}" + if: "${{ !cancelled() && github.event_name == 'merge_group' }}" runs-on: 'windows-2022' permissions: contents: 'read' @@ -418,10 +422,12 @@ jobs: codeql: name: 'CodeQL' needs: 'classify_pr' - # Security findings rarely change push-to-push, so a slow scan on every PR - # push is poor value. Skip on PR pushes; CodeQL still runs on push to `main` - # (and in the merge queue, once enabled) as the pre-/post-merge backstop. - if: "${{ !cancelled() && needs.classify_pr.outputs.skip_ci != 'true' && github.event_name != 'pull_request' }}" + # Security findings rarely change push-to-push, and a slow scan is poor value + # as a hard merge gate. Run CodeQL only on push to `main` (post-merge + # backstop) — not on PR pushes, and not in the merge queue where, being + # non-required, it would just burn a runner and lengthen the serial queue + # without blocking anything. + if: "${{ !cancelled() && needs.classify_pr.outputs.skip_ci != 'true' && github.event_name != 'pull_request' && github.event_name != 'merge_group' }}" runs-on: 'ubuntu-latest' # Analysis normally finishes in ~7-9 min (22 min worst case observed). Without # an explicit cap, a hosted runner that drops its heartbeat mid-analysis leaves diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index e7d7abe629..9b166ba44c 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -1,11 +1,14 @@ name: 'E2E Tests' on: + # E2E runs post-merge on `main` (per-commit signal) only. It is intentionally + # NOT in the merge queue yet: it is slow and currently flaky, so gating the + # serial queue on it would stall every merge. Promote it to `merge_group` + + # required once it is reliable. push: branches: - 'main' - 'feat/e2e/**' - merge_group: concurrency: # Key on the head ref so a `push` to a `feat/e2e/**` branch and a @@ -13,11 +16,10 @@ concurrency: # other instead of running the matrix twice for the same change. group: |- ${{ github.workflow }}-${{ github.head_ref || github.ref_name }} - # Cancel superseded PR / feature-branch runs, but let every `main` - # commit finish (complete per-commit e2e signal, matching ci.yml) and - # never cancel merge-queue runs. + # Cancel superseded feature-branch runs, but let every `main` commit finish + # (complete per-commit e2e signal, matching ci.yml). cancel-in-progress: |- - ${{ github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref != 'refs/heads/main') }} + ${{ github.event_name == 'push' && github.ref != 'refs/heads/main' }} jobs: e2e-test-linux: