diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d02a49c50c..4bf4d1ca2b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,12 +20,15 @@ name: CI on: pull_request: branches: [main] + types: [opened, synchronize, reopened, edited] push: branches: [main] workflow_dispatch: concurrency: - group: ci-${{ github.workflow }}-${{ github.ref }} + # `edited` also covers title and body changes. Isolate those no-op runs so + # they cannot cancel the check for the current pull request revision. + group: ci-${{ github.workflow }}-${{ github.ref }}${{ github.event.action == 'edited' && github.event.changes.base.ref.from == '' && format('-ignored-{0}', github.run_id) || '' }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} permissions: @@ -35,6 +38,10 @@ jobs: # Planning and every selected Linux surface share one runner, so the core # workflow consumes one automatic job without dropping affected coverage. test: + # A base-ref edit keeps the protected `CI / test` name. Other edits create + # only a differently named skipped check, so they cannot satisfy it. + name: ${{ github.event_name == 'pull_request' && github.event.action == 'edited' && github.event.changes.base.ref.from == '' && 'ignored-edit' || 'test' }} + if: ${{ github.event_name != 'pull_request' || github.event.action != 'edited' || github.event.changes.base.ref.from != '' }} runs-on: ubuntu-latest timeout-minutes: 45 steps: diff --git a/scripts/ci-test-plan.test.mjs b/scripts/ci-test-plan.test.mjs index f06a710408..461a6a2fb3 100644 --- a/scripts/ci-test-plan.test.mjs +++ b/scripts/ci-test-plan.test.mjs @@ -279,6 +279,25 @@ test('core CI validates pull requests and the resulting main branch state', () = assert.match(workflow, /\[\[ "\$BASE_SHA" =~ \^0\+\$ \]\]/u); }); +test('core CI runs on base retargets without letting metadata edits replace the required check', () => { + const workflow = readWorkflow('ci.yml'); + + assert.match(workflow, /types: \[opened, synchronize, reopened, edited\]/u); + assert.match( + workflow, + /group: ci-\$\{\{ github\.workflow \}\}-\$\{\{ github\.ref \}\}\$\{\{ github\.event\.action == 'edited' && github\.event\.changes\.base\.ref\.from == '' && format\('-ignored-\{0\}', github\.run_id\) \|\| '' \}\}/u, + ); + assert.match(workflow, /cancel-in-progress: \$\{\{ github\.event_name == 'pull_request' \}\}/u); + assert.match( + workflow, + /name: \$\{\{ github\.event_name == 'pull_request' && github\.event\.action == 'edited' && github\.event\.changes\.base\.ref\.from == '' && 'ignored-edit' \|\| 'test' \}\}/u, + ); + assert.match( + workflow, + /if: \$\{\{ github\.event_name != 'pull_request' \|\| github\.event\.action != 'edited' \|\| github\.event\.changes\.base\.ref\.from != '' \}\}/u, + ); +}); + test('core CI uses the Windows inventory package-script authority', () => { const workflow = readWorkflow('ci.yml');