diff --git a/.github/workflows/__multi-language-autodetect.yml b/.github/workflows/__multi-language-autodetect.yml index f4849b9903..4c75f5e5d5 100644 --- a/.github/workflows/__multi-language-autodetect.yml +++ b/.github/workflows/__multi-language-autodetect.yml @@ -61,19 +61,19 @@ jobs: include: - os: ubuntu-latest version: stable-v2.19.4 - - os: macos-latest-xlarge + - os: macos-15-xlarge version: stable-v2.19.4 - os: ubuntu-latest version: stable-v2.20.7 - - os: macos-latest-xlarge + - os: macos-15-xlarge version: stable-v2.20.7 - os: ubuntu-latest version: stable-v2.21.4 - - os: macos-latest-xlarge + - os: macos-15-xlarge version: stable-v2.21.4 - os: ubuntu-latest version: stable-v2.22.4 - - os: macos-latest-xlarge + - os: macos-15-xlarge version: stable-v2.22.4 - os: ubuntu-latest version: stable-v2.23.9 @@ -130,7 +130,8 @@ jobs: python-version: '3.13' - name: Use Xcode 16 - if: runner.os == 'macOS' && matrix.version != 'nightly-latest' + # Only the older CodeQL CLI versions need Xcode 16, and these run on macOS 15. + if: matrix.os == 'macos-15-xlarge' run: sudo xcode-select -s "/Applications/Xcode_16.app" - uses: ./../action/init diff --git a/.github/workflows/__swift-custom-build.yml b/.github/workflows/__swift-custom-build.yml index 83c06ffd09..23db3651b6 100644 --- a/.github/workflows/__swift-custom-build.yml +++ b/.github/workflows/__swift-custom-build.yml @@ -91,9 +91,6 @@ jobs: version: ${{ matrix.version }} use-all-platform-bundle: 'false' setup-kotlin: 'true' - - name: Use Xcode 16 - if: runner.os == 'macOS' && matrix.version != 'nightly-latest' - run: sudo xcode-select -s "/Applications/Xcode_16.app" - uses: ./../action/init id: init with: diff --git a/pr-checks/checks/multi-language-autodetect.yml b/pr-checks/checks/multi-language-autodetect.yml index fcafe5fb35..1608fcc6b7 100644 --- a/pr-checks/checks/multi-language-autodetect.yml +++ b/pr-checks/checks/multi-language-autodetect.yml @@ -4,6 +4,16 @@ operatingSystems: - ubuntu - os: macos runner-image: macos-latest-xlarge + # Older CodeQL CLI versions only support Swift up to 6.1, which requires Xcode 16. That is + # not available on macOS 26, so run these versions on macOS 15 where we select Xcode 16 + # below. See https://github.com/actions/runner-images/issues/14167. + - os: macos + runner-image: macos-15-xlarge + codeql-versions: + - stable-v2.19.4 + - stable-v2.20.7 + - stable-v2.21.4 + - stable-v2.22.4 env: CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI: true installGo: true @@ -18,7 +28,8 @@ steps: python-version: "3.13" - name: Use Xcode 16 - if: runner.os == 'macOS' && matrix.version != 'nightly-latest' + # Only the older CodeQL CLI versions need Xcode 16, and these run on macOS 15. + if: matrix.os == 'macos-15-xlarge' run: sudo xcode-select -s "/Applications/Xcode_16.app" - uses: ./../action/init diff --git a/pr-checks/checks/swift-custom-build.yml b/pr-checks/checks/swift-custom-build.yml index 7a07d5b7e2..a2d04421b8 100644 --- a/pr-checks/checks/swift-custom-build.yml +++ b/pr-checks/checks/swift-custom-build.yml @@ -11,9 +11,6 @@ installDotNet: true env: DOTNET_GENERATE_ASPNET_CERTIFICATE: "false" steps: - - name: Use Xcode 16 - if: runner.os == 'macOS' && matrix.version != 'nightly-latest' - run: sudo xcode-select -s "/Applications/Xcode_16.app" - uses: ./../action/init id: init with: diff --git a/pr-checks/sync.ts b/pr-checks/sync.ts index b969fcb937..035f5b34de 100755 --- a/pr-checks/sync.ts +++ b/pr-checks/sync.ts @@ -54,6 +54,13 @@ type OperatingSystem = os: OperatingSystemIdentifier; /** Optional runner image label. */ "runner-image"?: string; + /** + * Optional CodeQL versions to run on this entry. If specified, this entry runs only these + * versions. A sibling entry for the same OS that omits `codeql-versions` runs all versions + * not claimed by any sibling entry. This allows pinning specific CodeQL versions to a + * particular runner image while letting the remaining versions default to another. + */ + "codeql-versions"?: string[]; }; /** @@ -352,6 +359,28 @@ function generateJobMatrix( ): Array> { let matrix: Array> = []; + const operatingSystems = checkSpecification.operatingSystems ?? ["ubuntu"]; + + // For each OS, collect the CodeQL versions explicitly claimed by entries that specify + // `codeql-versions`. A sibling entry for the same OS that omits `codeql-versions` runs all + // versions not in this set. + const claimedVersionsByOs = new Map>(); + for (const operatingSystemConfig of operatingSystems) { + if (typeof operatingSystemConfig === "string") { + continue; + } + const entryVersions = operatingSystemConfig["codeql-versions"]; + if (!entryVersions) { + continue; + } + const claimed = + claimedVersionsByOs.get(operatingSystemConfig.os) ?? new Set(); + for (const entryVersion of entryVersions) { + claimed.add(entryVersion); + } + claimedVersionsByOs.set(operatingSystemConfig.os, claimed); + } + for (const version of checkSpecification.versions ?? defaultTestVersions) { if (version === "latest") { throw new Error( @@ -364,7 +393,6 @@ function generateJobMatrix( "macos-latest", "windows-latest", ]; - const operatingSystems = checkSpecification.operatingSystems ?? ["ubuntu"]; for (const operatingSystemConfig of operatingSystems) { const operatingSystem = @@ -379,6 +407,19 @@ function generateJobMatrix( continue; } + // An entry that specifies `codeql-versions` runs only those versions. A sibling entry for + // the same OS that omits `codeql-versions` runs all versions not claimed by its siblings. + const entryVersions = + typeof operatingSystemConfig === "string" + ? undefined + : operatingSystemConfig["codeql-versions"]; + const runsThisVersion = entryVersions + ? entryVersions.includes(version) + : !claimedVersionsByOs.get(operatingSystem)?.has(version); + if (!runsThisVersion) { + continue; + } + const runnerImagesForOs = typeof operatingSystemConfig === "string" || operatingSystemConfig["runner-image"] === undefined