From 0cda0a0147ccddda9e60671f5b4e67f42f58d55e Mon Sep 17 00:00:00 2001 From: 5an7y Date: Tue, 31 Mar 2026 10:54:23 -0700 Subject: [PATCH 1/5] ci: parallelize CodeQL scanning across 4 shards Split samples alphabetically into 4 equal shards using ListAllSamples.ps1 and run each on a separate machine in parallel. ThrottleLimit stays 1 per shard for accurate CodeQL tracing. Each shard uploads SARIF with a distinct category (shard-0..shard-3) so results merge in the Security tab. On PRs the existing Build-ChangedSamples behavior is preserved (no sharding needed since only changed files are built). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/Code-Scanning.yml | 35 +++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/.github/workflows/Code-Scanning.yml b/.github/workflows/Code-Scanning.yml index 232545ada..164225553 100644 --- a/.github/workflows/Code-Scanning.yml +++ b/.github/workflows/Code-Scanning.yml @@ -1,5 +1,7 @@ # This workflow runs the latest CodeQL CLI and checks against CodeQL's Cpp library. # This is the source for the GitHub Security Code Scanning job. +# Samples are split across 4 parallel shards to reduce total wall-clock time while +# keeping ThrottleLimit 1 per shard (required for accurate CodeQL tracing). name: "CodeQL Analysis" @@ -25,7 +27,7 @@ on: jobs: analyze: - name: Analysis + name: Analysis (shard ${{ matrix.shard }}) runs-on: windows-latest permissions: actions: read @@ -35,43 +37,58 @@ jobs: strategy: fail-fast: false matrix: - include: - - language: c-cpp - build-mode: manual + language: [c-cpp] + shard: [0, 1, 2, 3] steps: - name: Checkout repository uses: actions/checkout@v4 with: submodules: 'recursive' + - name: Install Nuget Packages run: nuget restore .\packages.config -PackagesDirectory .\packages\ + - name: Get changed files id: get-changed-files uses: tj-actions/changed-files@v41 with: separator: "," + - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} - build-mode: ${{ matrix.build-mode }} + build-mode: manual config-file: microsoft/Windows-Driver-Developer-Supplemental-Tools/config/codeql-config.yml@development + - if: github.event_name == 'pull_request' + name: Build changed samples (PR) run: | $changedFiles = "${{ steps.get-changed-files.outputs.all_changed_files }}".Split(',') .\.github\scripts\Build-ChangedSamples.ps1 -ChangedFiles $changedFiles -Verbose - env: + env: WDS_Configuration: Debug WDS_Platform: x64 WDS_WipeOutputs: ${{ true }} - - if: github.event_name == 'push' - run: .\Build-Samples.ps1 -Verbose -ThrottleLimit 1 + + - if: github.event_name != 'pull_request' + name: Build sample shard ${{ matrix.shard }} of 4 + run: | + $totalShards = 4 + $shardIndex = ${{ matrix.shard }} + $allSamples = .\ListAllSamples.ps1 + $shardSize = [Math]::Ceiling($allSamples.Count / $totalShards) + $start = $shardIndex * $shardSize + $mySamples = $allSamples | Select-Object -Skip $start -First $shardSize + Write-Output "Shard $shardIndex/$totalShards — building $($mySamples.Count) of $($allSamples.Count) samples (indices $start..$($start + $mySamples.Count - 1))" + .\Build-Samples.ps1 -Samples $mySamples -Verbose -ThrottleLimit 1 env: WDS_Configuration: Debug WDS_Platform: x64 WDS_WipeOutputs: ${{ true }} + - name: Perform CodeQL analysis uses: github/codeql-action/analyze@v3 with: - category: "/language:${{matrix.language}}" + category: "/language:${{ matrix.language }}/shard-${{ matrix.shard }}" From 420e954bfdebb154f4b47cddb973909cd93748fd Mon Sep 17 00:00:00 2001 From: 5an7y Date: Tue, 31 Mar 2026 15:53:33 -0700 Subject: [PATCH 2/5] ci: upgrade codeql-action from v3 to v4 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/Code-Scanning.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Code-Scanning.yml b/.github/workflows/Code-Scanning.yml index 164225553..0084ee6e7 100644 --- a/.github/workflows/Code-Scanning.yml +++ b/.github/workflows/Code-Scanning.yml @@ -56,7 +56,7 @@ jobs: separator: "," - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} build-mode: manual @@ -89,6 +89,6 @@ jobs: WDS_WipeOutputs: ${{ true }} - name: Perform CodeQL analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 with: category: "/language:${{ matrix.language }}/shard-${{ matrix.shard }}" From ff3cc2bcc955ba82110435df67fff3905072759b Mon Sep 17 00:00:00 2001 From: 5an7y Date: Tue, 31 Mar 2026 16:26:24 -0700 Subject: [PATCH 3/5] ci: fix shard display numbering and restore build-mode in matrix - Job name and step name now show '1 of 4' through '4 of 4' (shard+1) instead of '0' through '3 of 4' which looked like an off-by-one bug - Move build-mode back into the matrix (was there before sharding) so it remains explicit and consistent with the original workflow structure Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/Code-Scanning.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/Code-Scanning.yml b/.github/workflows/Code-Scanning.yml index 0084ee6e7..2ac76b155 100644 --- a/.github/workflows/Code-Scanning.yml +++ b/.github/workflows/Code-Scanning.yml @@ -27,7 +27,7 @@ on: jobs: analyze: - name: Analysis (shard ${{ matrix.shard }}) + name: Analysis (shard ${{ matrix.shard + 1 }} of 4) runs-on: windows-latest permissions: actions: read @@ -38,6 +38,7 @@ jobs: fail-fast: false matrix: language: [c-cpp] + build-mode: [manual] shard: [0, 1, 2, 3] steps: @@ -59,7 +60,7 @@ jobs: uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} - build-mode: manual + build-mode: ${{ matrix.build-mode }} config-file: microsoft/Windows-Driver-Developer-Supplemental-Tools/config/codeql-config.yml@development - if: github.event_name == 'pull_request' @@ -73,7 +74,7 @@ jobs: WDS_WipeOutputs: ${{ true }} - if: github.event_name != 'pull_request' - name: Build sample shard ${{ matrix.shard }} of 4 + name: Build sample shard ${{ matrix.shard + 1 }} of 4 run: | $totalShards = 4 $shardIndex = ${{ matrix.shard }} @@ -81,7 +82,7 @@ jobs: $shardSize = [Math]::Ceiling($allSamples.Count / $totalShards) $start = $shardIndex * $shardSize $mySamples = $allSamples | Select-Object -Skip $start -First $shardSize - Write-Output "Shard $shardIndex/$totalShards — building $($mySamples.Count) of $($allSamples.Count) samples (indices $start..$($start + $mySamples.Count - 1))" + Write-Output "Shard $($shardIndex + 1)/$totalShards — building $($mySamples.Count) of $($allSamples.Count) samples (indices $start..$($start + $mySamples.Count - 1))" .\Build-Samples.ps1 -Samples $mySamples -Verbose -ThrottleLimit 1 env: WDS_Configuration: Debug From 41f33e6facd946dc74674d6747e7c61f9a5494f1 Mon Sep 17 00:00:00 2001 From: 5an7y Date: Tue, 31 Mar 2026 16:29:17 -0700 Subject: [PATCH 4/5] ci: fix shard numbering using 1-based matrix values GitHub Actions expressions don't support arithmetic operators so 'matrix.shard + 1' was invalid. Switch the matrix to [1, 2, 3, 4] so the job name, step name, and log output all read '1 of 4' through '4 of 4'. The PowerShell script subtracts 1 locally for the 0-based slice math. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/Code-Scanning.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/Code-Scanning.yml b/.github/workflows/Code-Scanning.yml index 2ac76b155..c28d2a527 100644 --- a/.github/workflows/Code-Scanning.yml +++ b/.github/workflows/Code-Scanning.yml @@ -27,7 +27,7 @@ on: jobs: analyze: - name: Analysis (shard ${{ matrix.shard + 1 }} of 4) + name: Analysis (shard ${{ matrix.shard }} of 4) runs-on: windows-latest permissions: actions: read @@ -39,7 +39,7 @@ jobs: matrix: language: [c-cpp] build-mode: [manual] - shard: [0, 1, 2, 3] + shard: [1, 2, 3, 4] steps: - name: Checkout repository @@ -74,15 +74,15 @@ jobs: WDS_WipeOutputs: ${{ true }} - if: github.event_name != 'pull_request' - name: Build sample shard ${{ matrix.shard + 1 }} of 4 + name: Build sample shard ${{ matrix.shard }} of 4 run: | $totalShards = 4 - $shardIndex = ${{ matrix.shard }} + $shardIndex = ${{ matrix.shard }} - 1 $allSamples = .\ListAllSamples.ps1 $shardSize = [Math]::Ceiling($allSamples.Count / $totalShards) $start = $shardIndex * $shardSize $mySamples = $allSamples | Select-Object -Skip $start -First $shardSize - Write-Output "Shard $($shardIndex + 1)/$totalShards — building $($mySamples.Count) of $($allSamples.Count) samples (indices $start..$($start + $mySamples.Count - 1))" + Write-Output "Shard ${{ matrix.shard }}/$totalShards — building $($mySamples.Count) of $($allSamples.Count) samples (indices $start..$($start + $mySamples.Count - 1))" .\Build-Samples.ps1 -Samples $mySamples -Verbose -ThrottleLimit 1 env: WDS_Configuration: Debug From 5d0fec82a01ba158be6e4393a41e113e26137d86 Mon Sep 17 00:00:00 2001 From: 5an7y Date: Tue, 31 Mar 2026 17:54:29 -0700 Subject: [PATCH 5/5] ci: split CodeQL into separate PR and push/schedule jobs The previous single-job approach with a 4-shard matrix caused PRs to spin up 4 identical runners all building the same changed files. Split into two jobs: - analyze-pr: runs only on pull_request, single runner, builds changed samples via Build-ChangedSamples.ps1. No shard matrix overhead. - analyze: runs on push/schedule, 4-shard matrix, each shard builds its slice of all samples. Also drops the now-unnecessary 'get-changed-files' step from the push path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/Code-Scanning.yml | 60 ++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/.github/workflows/Code-Scanning.yml b/.github/workflows/Code-Scanning.yml index c28d2a527..393f69dff 100644 --- a/.github/workflows/Code-Scanning.yml +++ b/.github/workflows/Code-Scanning.yml @@ -1,7 +1,8 @@ # This workflow runs the latest CodeQL CLI and checks against CodeQL's Cpp library. # This is the source for the GitHub Security Code Scanning job. -# Samples are split across 4 parallel shards to reduce total wall-clock time while -# keeping ThrottleLimit 1 per shard (required for accurate CodeQL tracing). +# On push/schedule: samples are split across 4 parallel shards to reduce wall-clock +# time while keeping ThrottleLimit 1 per shard (required for accurate CodeQL tracing). +# On pull_request: only changed samples are built in a single job (no sharding needed). name: "CodeQL Analysis" @@ -26,8 +27,12 @@ on: workflow_dispatch: jobs: - analyze: - name: Analysis (shard ${{ matrix.shard }} of 4) + # ----------------------------------------------------------------------- + # PR job: single runner, builds only changed samples + # ----------------------------------------------------------------------- + analyze-pr: + name: Analysis (PR) + if: github.event_name == 'pull_request' runs-on: windows-latest permissions: actions: read @@ -39,7 +44,6 @@ jobs: matrix: language: [c-cpp] build-mode: [manual] - shard: [1, 2, 3, 4] steps: - name: Checkout repository @@ -63,8 +67,7 @@ jobs: build-mode: ${{ matrix.build-mode }} config-file: microsoft/Windows-Driver-Developer-Supplemental-Tools/config/codeql-config.yml@development - - if: github.event_name == 'pull_request' - name: Build changed samples (PR) + - name: Build changed samples (PR) run: | $changedFiles = "${{ steps.get-changed-files.outputs.all_changed_files }}".Split(',') .\.github\scripts\Build-ChangedSamples.ps1 -ChangedFiles $changedFiles -Verbose @@ -73,8 +76,47 @@ jobs: WDS_Platform: x64 WDS_WipeOutputs: ${{ true }} - - if: github.event_name != 'pull_request' - name: Build sample shard ${{ matrix.shard }} of 4 + - name: Perform CodeQL analysis + uses: github/codeql-action/analyze@v4 + with: + category: "/language:${{ matrix.language }}" + + # ----------------------------------------------------------------------- + # Push/schedule job: 4 parallel shards, each builds a slice of all samples + # ----------------------------------------------------------------------- + analyze: + name: Analysis (shard ${{ matrix.shard }} of 4) + if: github.event_name != 'pull_request' + runs-on: windows-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [c-cpp] + build-mode: [manual] + shard: [1, 2, 3, 4] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: 'recursive' + + - name: Install Nuget Packages + run: nuget restore .\packages.config -PackagesDirectory .\packages\ + + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + config-file: microsoft/Windows-Driver-Developer-Supplemental-Tools/config/codeql-config.yml@development + + - name: Build sample shard ${{ matrix.shard }} of 4 run: | $totalShards = 4 $shardIndex = ${{ matrix.shard }} - 1