@@ -55,9 +55,10 @@ type OperatingSystem =
5555 /** Optional runner image label. */
5656 "runner-image" ?: string ;
5757 /**
58- * Optional CodeQL versions to run on this entry. If specified, only these versions are
59- * tested on this runner image. This allows running different runner images for different
60- * CodeQL versions of the same OS.
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.
6162 */
6263 "codeql-versions" ?: string [ ] ;
6364 } ;
@@ -358,6 +359,28 @@ function generateJobMatrix(
358359) : Array < Record < string , any > > {
359360 let matrix : Array < Record < string , any > > = [ ] ;
360361
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+
361384 for ( const version of checkSpecification . versions ?? defaultTestVersions ) {
362385 if ( version === "latest" ) {
363386 throw new Error (
@@ -370,7 +393,6 @@ function generateJobMatrix(
370393 "macos-latest" ,
371394 "windows-latest" ,
372395 ] ;
373- const operatingSystems = checkSpecification . operatingSystems ?? [ "ubuntu" ] ;
374396
375397 for ( const operatingSystemConfig of operatingSystems ) {
376398 const operatingSystem =
@@ -385,12 +407,16 @@ function generateJobMatrix(
385407 continue ;
386408 }
387409
388- // If this OS entry restricts itself to specific CodeQL versions, skip other versions.
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.
389412 const entryVersions =
390413 typeof operatingSystemConfig === "string"
391414 ? undefined
392415 : operatingSystemConfig [ "codeql-versions" ] ;
393- if ( entryVersions && ! entryVersions . includes ( version ) ) {
416+ const runsThisVersion = entryVersions
417+ ? entryVersions . includes ( version )
418+ : ! claimedVersionsByOs . get ( operatingSystem ) ?. has ( version ) ;
419+ if ( ! runsThisVersion ) {
394420 continue ;
395421 }
396422
0 commit comments