@@ -54,6 +54,13 @@ type OperatingSystem =
5454 os : OperatingSystemIdentifier ;
5555 /** Optional runner image label. */
5656 "runner-image" ?: string ;
57+ /**
58+ * Optional CodeQL versions to run on this entry. If specified, this entry runs only these
59+ * versions. A sibling entry for the same OS that omits `codeql-versions` runs all versions
60+ * not claimed by any sibling entry. This allows pinning specific CodeQL versions to a
61+ * particular runner image while letting the remaining versions default to another.
62+ */
63+ "codeql-versions" ?: string [ ] ;
5764 } ;
5865
5966/**
@@ -352,6 +359,28 @@ function generateJobMatrix(
352359) : Array < Record < string , any > > {
353360 let matrix : Array < Record < string , any > > = [ ] ;
354361
362+ const operatingSystems = checkSpecification . operatingSystems ?? [ "ubuntu" ] ;
363+
364+ // For each OS, collect the CodeQL versions explicitly claimed by entries that specify
365+ // `codeql-versions`. A sibling entry for the same OS that omits `codeql-versions` runs all
366+ // versions not in this set.
367+ const claimedVersionsByOs = new Map < string , Set < string > > ( ) ;
368+ for ( const operatingSystemConfig of operatingSystems ) {
369+ if ( typeof operatingSystemConfig === "string" ) {
370+ continue ;
371+ }
372+ const entryVersions = operatingSystemConfig [ "codeql-versions" ] ;
373+ if ( ! entryVersions ) {
374+ continue ;
375+ }
376+ const claimed =
377+ claimedVersionsByOs . get ( operatingSystemConfig . os ) ?? new Set < string > ( ) ;
378+ for ( const entryVersion of entryVersions ) {
379+ claimed . add ( entryVersion ) ;
380+ }
381+ claimedVersionsByOs . set ( operatingSystemConfig . os , claimed ) ;
382+ }
383+
355384 for ( const version of checkSpecification . versions ?? defaultTestVersions ) {
356385 if ( version === "latest" ) {
357386 throw new Error (
@@ -364,7 +393,6 @@ function generateJobMatrix(
364393 "macos-latest" ,
365394 "windows-latest" ,
366395 ] ;
367- const operatingSystems = checkSpecification . operatingSystems ?? [ "ubuntu" ] ;
368396
369397 for ( const operatingSystemConfig of operatingSystems ) {
370398 const operatingSystem =
@@ -379,6 +407,19 @@ function generateJobMatrix(
379407 continue ;
380408 }
381409
410+ // An entry that specifies `codeql-versions` runs only those versions. A sibling entry for
411+ // the same OS that omits `codeql-versions` runs all versions not claimed by its siblings.
412+ const entryVersions =
413+ typeof operatingSystemConfig === "string"
414+ ? undefined
415+ : operatingSystemConfig [ "codeql-versions" ] ;
416+ const runsThisVersion = entryVersions
417+ ? entryVersions . includes ( version )
418+ : ! claimedVersionsByOs . get ( operatingSystem ) ?. has ( version ) ;
419+ if ( ! runsThisVersion ) {
420+ continue ;
421+ }
422+
382423 const runnerImagesForOs =
383424 typeof operatingSystemConfig === "string" ||
384425 operatingSystemConfig [ "runner-image" ] === undefined
0 commit comments