From a6a90ced8e9d812024cb3fe280d563b35a16e0e6 Mon Sep 17 00:00:00 2001 From: SquarePots <46488165+squarepots@users.noreply.github.com> Date: Sun, 4 Oct 2026 12:35:35 +0800 Subject: [PATCH] Run CI and CodeQL in a merge queue Main required every pull request to be up to date before merging, so landing several pull requests meant updating each branch and re-running every check after each merge. A merge queue tests the queued pull request on top of the current main and the entries ahead of it, then merges that exact commit, without manual updates. CI now runs on merge_group events and runs every source job for a queue entry, since its commit becomes main. CodeQL moves from default setup to a repository workflow, because default setup does not analyze merge-queue commits and its required Analyze checks would stay pending in the queue. The workflow keeps the same languages, default query suite, analysis categories, and check names, and also runs on pull requests, main pushes, and weekly. Default setup must be turned off for the workflow's results to be accepted. --- .github/workflows/ci.yml | 21 +++++++++--------- .github/workflows/codeql.yml | 41 ++++++++++++++++++++++++++++++++++++ docs/testing.md | 32 +++++++++++++++++++--------- 3 files changed, 74 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 39a682c..dfbd547 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,6 +2,7 @@ name: CI on: pull_request: + merge_group: push: branches: - main @@ -40,7 +41,7 @@ jobs: echo "platform=false" >> "$GITHUB_OUTPUT" exit 0 fi - if [[ "$BASE_SHA" =~ ^0+$ ]]; then + if [[ "$EVENT_NAME" == "merge_group" || "$BASE_SHA" =~ ^0+$ ]]; then echo "frontend=true" >> "$GITHUB_OUTPUT" echo "rust=true" >> "$GITHUB_OUTPUT" echo "platform=true" >> "$GITHUB_OUTPUT" @@ -74,7 +75,7 @@ jobs: frontend: name: Frontend needs: changes - if: github.event_name == 'push' || (github.event_name == 'pull_request' && needs.changes.outputs.frontend == 'true') + if: github.event_name == 'push' || ((github.event_name == 'pull_request' || github.event_name == 'merge_group') && needs.changes.outputs.frontend == 'true') runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -89,13 +90,13 @@ jobs: - run: pnpm install --frozen-lockfile - run: pnpm run ci:source frontend env: - GSWITCH_DIFF_BASE: ${{ github.event.pull_request.base.sha || github.event.before }} - GSWITCH_DIFF_HEAD: ${{ github.event.pull_request.head.sha || github.sha }} + GSWITCH_DIFF_BASE: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before }} + GSWITCH_DIFF_HEAD: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha || github.sha }} platform-build: name: ${{ matrix.check_name }} needs: changes - if: github.event_name == 'push' || (github.event_name == 'pull_request' && needs.changes.outputs.platform == 'true') + if: github.event_name == 'push' || ((github.event_name == 'pull_request' || github.event_name == 'merge_group') && needs.changes.outputs.platform == 'true') strategy: fail-fast: false matrix: @@ -132,13 +133,13 @@ jobs: - name: Check platform Rust targets run: pnpm run ci:source platform env: - GSWITCH_DIFF_BASE: ${{ github.event.pull_request.base.sha || github.event.before }} - GSWITCH_DIFF_HEAD: ${{ github.event.pull_request.head.sha || github.sha }} + GSWITCH_DIFF_BASE: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before }} + GSWITCH_DIFF_HEAD: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha || github.sha }} linux: name: Linux build needs: changes - if: github.event_name == 'push' || (github.event_name == 'pull_request' && needs.changes.outputs.rust == 'true') + if: github.event_name == 'push' || ((github.event_name == 'pull_request' || github.event_name == 'merge_group') && needs.changes.outputs.rust == 'true') runs-on: ubuntu-22.04 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -175,8 +176,8 @@ jobs: ${{ runner.os }}-cargo-${{ hashFiles('rust-toolchain.toml', 'src-tauri/Cargo.lock') }}- - run: pnpm run ci:source linux env: - GSWITCH_DIFF_BASE: ${{ github.event.pull_request.base.sha || github.event.before }} - GSWITCH_DIFF_HEAD: ${{ github.event.pull_request.head.sha || github.sha }} + GSWITCH_DIFF_BASE: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before }} + GSWITCH_DIFF_HEAD: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha || github.sha }} dependency-review: name: Dependency review diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..51197ac --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,41 @@ +name: CodeQL + +on: + pull_request: + merge_group: + push: + branches: + - main + schedule: + - cron: '43 4 * * 1' + +concurrency: + group: gswitch-codeql-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + strategy: + fail-fast: false + matrix: + language: + - actions + - javascript-typescript + - rust + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: github/codeql-action/init@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2 + with: + languages: ${{ matrix.language }} + build-mode: none + - uses: github/codeql-action/analyze@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2 + with: + category: /language:${{ matrix.language }} diff --git a/docs/testing.md b/docs/testing.md index 243f0fd..99fad2e 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -47,9 +47,12 @@ production frontend build. Rust changes call its Linux mode for version, frontend build, Rust formatting, Clippy, and the full Rust test suite. Frontend only changes do not start the Rust or platform workers. Changes to application or build inputs also compile all Rust targets on Windows and macOS; those jobs -do not repeat tests or create installer bundles. Node and Cargo dependencies -use runner caches, and newer runs cancel older runs for the same pull request -or branch. +do not repeat tests or create installer bundles. A merge-queue entry runs every +source job regardless of paths, because its commit, the queued pull request on +top of the current `main` and any entries ahead of it, is the commit that +becomes `main`. Node and Cargo dependencies use runner caches, and newer runs +cancel older runs for the same pull request or branch; each queue entry has its +own branch, so entries never cancel each other. `CI gate` reports whether the scoped source jobs and security checks succeeded. It runs even when a scoped source job is skipped and fails if scope detection @@ -67,14 +70,17 @@ The CI workflow has read-only repository permissions. A passing CI run proves that the checked-in revision passed those commands on those runners; it does not publish or release anything. -The `main` ruleset is the authority for current required checks, strict update -requirements, and resolved review conversations. Read the live ruleset when +The `main` ruleset is the authority for current required checks, the merge +queue and its settings, strict update requirements, and resolved review +conversations. Read the live ruleset when changing or reporting those requirements; this document describes workflow behavior and migration steps only. CI runs GitHub dependency review on every pull request (moderate-or-higher advisories in runtime, development, or unknown scopes) and RustSec's -`cargo-audit` on pull requests and main pushes, with a weekly scheduled audit. +`cargo-audit` on pull requests, merge-queue entries, and main pushes, with a +weekly scheduled audit. Dependency review does not run in the queue: a queued +combination adds no dependency that its pull requests did not. The dependency check deliberately does not impose a license policy. Both checks use a read-only token; the release workflow grants write access only to its draft-upload job. External Actions use full commit SHAs with version comments. @@ -92,10 +98,16 @@ directly records the bot as a commit author and lists it as a contributor. Recreate its change in a maintainer-authored commit and pull request, run the checks for the changed paths there, then close Renovate's pull request. -GitHub CodeQL default setup, rather than a repository workflow, scans Actions, -JavaScript/TypeScript, and Rust. Its effective language list and the -repository's SHA-pinning policy must be read from GitHub when making a claim -about current protection; these settings are not inferred from this document. +The repository's CodeQL workflow scans Actions, JavaScript/TypeScript, and Rust +with the default query suite on pull requests, merge-queue entries, main pushes, +and weekly. Its jobs report the required `Analyze (actions)`, +`Analyze (javascript-typescript)`, and `Analyze (rust)` checks. It replaces +CodeQL default setup, which does not analyze merge-queue commits and would +leave those required checks pending in the queue. Default setup must stay off: +GitHub rejects a repository workflow's results while it is on. The effective +code scanning configuration and the repository's SHA-pinning policy must be +read from GitHub when making a claim about current protection; these settings +are not inferred from this document. ## Required regression areas