2020-05-05 17:32:58 +01:00
"use strict" ;
2021-07-27 17:59:59 +01:00
var _ _createBinding = ( this && this . _ _createBinding ) || ( Object . create ? ( function ( o , m , k , k2 ) {
if ( k2 === undefined ) k2 = k ;
Object . defineProperty ( o , k2 , { enumerable : true , get : function ( ) { return m [ k ] ; } } ) ;
} ) : ( function ( o , m , k , k2 ) {
if ( k2 === undefined ) k2 = k ;
o [ k2 ] = m [ k ] ;
} ) ) ;
var _ _setModuleDefault = ( this && this . _ _setModuleDefault ) || ( Object . create ? ( function ( o , v ) {
Object . defineProperty ( o , "default" , { enumerable : true , value : v } ) ;
} ) : function ( o , v ) {
o [ "default" ] = v ;
} ) ;
2020-05-05 17:32:58 +01:00
var _ _importStar = ( this && this . _ _importStar ) || function ( mod ) {
if ( mod && mod . _ _esModule ) return mod ;
var result = { } ;
2021-07-27 17:59:59 +01:00
if ( mod != null ) for ( var k in mod ) if ( k !== "default" && Object . prototype . hasOwnProperty . call ( mod , k ) ) _ _createBinding ( result , mod , k ) ;
_ _setModuleDefault ( result , mod ) ;
2020-05-05 17:32:58 +01:00
return result ;
} ;
2020-06-24 14:12:36 +01:00
var _ _importDefault = ( this && this . _ _importDefault ) || function ( mod ) {
return ( mod && mod . _ _esModule ) ? mod : { "default" : mod } ;
} ;
2020-05-05 17:32:58 +01:00
Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
const fs = _ _importStar ( require ( "fs" ) ) ;
const path = _ _importStar ( require ( "path" ) ) ;
2020-10-01 11:03:30 +01:00
const github = _ _importStar ( require ( "@actions/github" ) ) ;
2020-09-29 14:43:37 +01:00
const ava _1 = _ _importDefault ( require ( "ava" ) ) ;
2022-08-29 12:57:46 -07:00
const yaml = _ _importStar ( require ( "js-yaml" ) ) ;
2021-08-11 13:14:56 +01:00
const sinon = _ _importStar ( require ( "sinon" ) ) ;
2020-10-01 11:03:30 +01:00
const api = _ _importStar ( require ( "./api-client" ) ) ;
2020-08-19 15:54:23 +01:00
const codeql _1 = require ( "./codeql" ) ;
2020-10-01 11:03:30 +01:00
const configUtils = _ _importStar ( require ( "./config-utils" ) ) ;
2021-12-15 13:34:29 +00:00
const feature _flags _1 = require ( "./feature-flags" ) ;
2020-08-17 13:34:55 +01:00
const languages _1 = require ( "./languages" ) ;
2020-08-25 16:19:15 +01:00
const logging _1 = require ( "./logging" ) ;
2020-06-22 12:12:14 +01:00
const testing _utils _1 = require ( "./testing-utils" ) ;
2020-10-01 11:03:30 +01:00
const util = _ _importStar ( require ( "./util" ) ) ;
2021-09-10 13:53:13 -07:00
( 0 , testing _utils _1 . setupTests ) ( ava _1 . default ) ;
2020-11-23 14:18:05 +00:00
const sampleApiDetails = {
auth : "token" ,
2021-01-04 12:31:55 +00:00
externalRepoAuth : "token" ,
2020-11-23 14:18:05 +00:00
url : "https://github.example.com" ,
2022-08-10 21:11:50 +01:00
apiURL : undefined ,
2022-08-29 12:57:46 -07:00
registriesAuthTokens : undefined ,
2020-11-23 14:18:05 +00:00
} ;
2021-02-15 09:29:10 +00:00
const gitHubVersion = { type : util . GitHubVariant . DOTCOM } ;
2020-09-08 10:00:16 +01:00
// Returns the filepath of the newly-created file
function createConfigFile ( inputFileContents , tmpDir ) {
2020-09-14 10:44:43 +01:00
const configFilePath = path . join ( tmpDir , "input" ) ;
fs . writeFileSync ( configFilePath , inputFileContents , "utf8" ) ;
2020-09-08 10:00:16 +01:00
return configFilePath ;
2020-08-28 17:20:40 +01:00
}
2020-07-07 18:32:29 +01:00
function mockGetContents ( content ) {
// Passing an auth token is required, so we just use a dummy value
2020-09-18 15:40:23 +01:00
const client = github . getOctokit ( "123" ) ;
2020-07-07 18:32:29 +01:00
const response = {
2020-09-14 10:44:43 +01:00
data : content ,
2020-07-07 18:32:29 +01:00
} ;
2021-08-11 13:14:56 +01:00
const spyGetContents = sinon
2020-09-18 15:40:23 +01:00
. stub ( client . repos , "getContent" )
2020-09-14 10:44:43 +01:00
. resolves ( response ) ;
2021-08-11 13:14:56 +01:00
sinon . stub ( api , "getApiClient" ) . value ( ( ) => client ) ;
2020-07-07 18:32:29 +01:00
return spyGetContents ;
}
2020-08-07 17:15:46 +01:00
function mockListLanguages ( languages ) {
// Passing an auth token is required, so we just use a dummy value
2020-09-18 15:40:23 +01:00
const client = github . getOctokit ( "123" ) ;
2020-08-07 17:15:46 +01:00
const response = {
data : { } ,
} ;
for ( const language of languages ) {
response . data [ language ] = 123 ;
}
2021-08-11 13:14:56 +01:00
sinon . stub ( client . repos , "listLanguages" ) . resolves ( response ) ;
sinon . stub ( api , "getApiClient" ) . value ( ( ) => client ) ;
2020-08-07 17:15:46 +01:00
}
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "load empty config" , async ( t ) => {
2020-05-05 17:32:58 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
2021-09-10 13:53:13 -07:00
const logger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
2020-09-14 10:44:43 +01:00
const languages = "javascript,python" ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( ) {
2020-06-26 15:33:59 +01:00
return {
2021-05-21 12:31:57 +02:00
byLanguage : {
javascript : { queries : [ "query1.ql" ] } ,
python : { queries : [ "query2.ql" ] } ,
} ,
2020-06-26 15:33:59 +01:00
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-06-26 15:33:59 +01:00
} ) ;
2022-09-01 16:07:26 -07:00
const config = await configUtils . initConfig ( languages , undefined , undefined , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , logger ) ;
2022-08-02 17:52:22 +01:00
t . deepEqual ( config , await configUtils . getDefaultConfig ( languages , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , logger ) ) ;
2020-05-05 17:32:58 +01:00
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "loading config saves config" , async ( t ) => {
2020-05-05 17:32:58 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
2021-09-10 13:53:13 -07:00
const logger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( ) {
2020-06-26 15:33:59 +01:00
return {
2021-05-21 12:31:57 +02:00
byLanguage : {
javascript : { queries : [ "query1.ql" ] } ,
python : { queries : [ "query2.ql" ] } ,
} ,
2020-06-26 15:33:59 +01:00
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-06-26 15:33:59 +01:00
} ) ;
2020-05-05 17:32:58 +01:00
// Sanity check the saved config file does not already exist
2020-08-19 15:11:49 +01:00
t . false ( fs . existsSync ( configUtils . getPathToParsedConfigFile ( tmpDir ) ) ) ;
2020-08-28 17:28:05 +01:00
// Sanity check that getConfig returns undefined before we have called initConfig
t . deepEqual ( await configUtils . getConfig ( tmpDir , logger ) , undefined ) ;
2022-09-01 16:07:26 -07:00
const config1 = await configUtils . initConfig ( "javascript,python" , undefined , undefined , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , logger ) ;
2020-05-05 17:32:58 +01:00
// The saved config file should now exist
2020-08-19 15:11:49 +01:00
t . true ( fs . existsSync ( configUtils . getPathToParsedConfigFile ( tmpDir ) ) ) ;
2020-07-15 17:36:49 +01:00
// And that same newly-initialised config should now be returned by getConfig
2020-08-25 16:19:15 +01:00
const config2 = await configUtils . getConfig ( tmpDir , logger ) ;
2022-02-01 18:01:11 +00:00
t . not ( config2 , undefined ) ;
if ( config2 !== undefined ) {
2022-06-19 16:44:24 -07:00
// removes properties assigned to undefined.
const expectedConfig = JSON . parse ( JSON . stringify ( config1 ) ) ;
t . deepEqual ( expectedConfig , config2 ) ;
2022-02-01 18:01:11 +00:00
}
2020-05-05 17:32:58 +01:00
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "load input outside of workspace" , async ( t ) => {
2020-05-05 17:32:58 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
try {
2022-09-01 16:07:26 -07:00
await configUtils . initConfig ( undefined , undefined , undefined , undefined , "../input" , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , ( 0 , codeql _1 . getCachedCodeQL ) ( ) , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-05-05 17:32:58 +01:00
}
catch ( err ) {
2020-09-14 10:44:43 +01:00
t . deepEqual ( err , new Error ( configUtils . getConfigFileOutsideWorkspaceErrorMessage ( path . join ( tmpDir , "../input" ) ) ) ) ;
2020-05-05 17:32:58 +01:00
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "load non-local input with invalid repo syntax" , async ( t ) => {
2020-06-25 13:21:46 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
// no filename given, just a repo
2020-09-14 10:44:43 +01:00
const configFile = "octo-org/codeql-config@main" ;
2020-06-25 13:21:46 +01:00
try {
2022-09-01 16:07:26 -07:00
await configUtils . initConfig ( undefined , undefined , undefined , undefined , configFile , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , ( 0 , codeql _1 . getCachedCodeQL ) ( ) , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-06-25 13:21:46 +01:00
}
catch ( err ) {
2020-09-14 10:44:43 +01:00
t . deepEqual ( err , new Error ( configUtils . getConfigFileRepoFormatInvalidMessage ( "octo-org/codeql-config@main" ) ) ) ;
2020-06-25 13:21:46 +01:00
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "load non-existent input" , async ( t ) => {
2020-05-05 17:32:58 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
const configFile = "input" ;
2020-08-25 16:19:15 +01:00
t . false ( fs . existsSync ( path . join ( tmpDir , configFile ) ) ) ;
2020-05-05 17:32:58 +01:00
try {
2022-09-01 16:07:26 -07:00
await configUtils . initConfig ( languages , undefined , undefined , undefined , configFile , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , ( 0 , codeql _1 . getCachedCodeQL ) ( ) , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-05-05 17:32:58 +01:00
}
catch ( err ) {
2020-09-14 10:44:43 +01:00
t . deepEqual ( err , new Error ( configUtils . getConfigFileDoesNotExistErrorMessage ( path . join ( tmpDir , "input" ) ) ) ) ;
2020-05-05 17:32:58 +01:00
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "load non-empty input" , async ( t ) => {
2020-05-05 17:32:58 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( ) {
2020-06-26 15:33:59 +01:00
return {
byLanguage : {
2020-09-14 10:44:43 +01:00
javascript : {
"/foo/a.ql" : { } ,
"/bar/b.ql" : { } ,
2020-06-26 15:33:59 +01:00
} ,
} ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-06-26 15:33:59 +01:00
} ) ;
2020-05-05 17:32:58 +01:00
// Just create a generic config object with non-default values for all fields
const inputFileContents = `
name: my config
disable-default-queries: true
queries:
- uses: ./foo
paths-ignore:
- a
- b
paths:
- c/d ` ;
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "foo" ) ) ;
2020-05-05 17:32:58 +01:00
// And the config we expect it to parse to
2020-06-26 15:33:59 +01:00
const expectedConfig = {
2020-08-17 13:34:55 +01:00
languages : [ languages _1 . Language . javascript ] ,
2020-09-18 09:52:44 +01:00
queries : {
javascript : {
2020-09-10 18:02:33 +01:00
builtin : [ ] ,
2021-04-01 12:38:13 +01:00
custom : [
{
queries : [ "/foo/a.ql" , "/bar/b.ql" ] ,
searchPath : tmpDir ,
} ,
] ,
2020-09-18 09:52:44 +01:00
} ,
} ,
2020-09-14 10:44:43 +01:00
pathsIgnore : [ "a" , "b" ] ,
paths : [ "c/d" ] ,
2020-07-20 16:33:37 +01:00
originalUserInput : {
2020-09-14 10:44:43 +01:00
name : "my config" ,
"disable-default-queries" : true ,
queries : [ { uses : "./foo" } ] ,
"paths-ignore" : [ "a" , "b" ] ,
paths : [ "c/d" ] ,
2020-07-20 16:33:37 +01:00
} ,
2020-08-19 15:11:49 +01:00
tempDir : tmpDir ,
2020-08-19 15:54:23 +01:00
codeQLCmd : codeQL . getPath ( ) ,
2020-11-30 16:33:38 +00:00
gitHubVersion ,
2021-05-17 10:35:09 +01:00
dbLocation : path . resolve ( tmpDir , "codeql_databases" ) ,
2021-06-03 09:32:44 -07:00
packs : { } ,
2021-10-28 14:15:22 +01:00
debugMode : false ,
2022-01-07 13:11:51 +00:00
debugArtifactName : "my-artifact" ,
debugDatabaseName : "my-db" ,
2022-08-10 15:42:45 -07:00
augmentationProperties : configUtils . defaultAugmentationProperties ,
2022-08-02 17:52:22 +01:00
trapCaches : { } ,
2022-08-15 14:44:43 +01:00
trapCacheDownloadTime : 0 ,
2020-06-26 15:33:59 +01:00
} ;
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
2020-09-08 10:14:51 +01:00
const configFilePath = createConfigFile ( inputFileContents , tmpDir ) ;
2022-09-01 16:07:26 -07:00
const actualConfig = await configUtils . initConfig ( languages , undefined , undefined , undefined , configFilePath , undefined , false , false , "my-artifact" , "my-db" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-05-05 17:32:58 +01:00
// Should exactly equal the object we constructed earlier
t . deepEqual ( actualConfig , expectedConfig ) ;
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Default queries are used" , async ( t ) => {
2020-07-21 10:53:14 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
// Check that the default behaviour is to add the default queries.
2020-07-21 12:19:37 +01:00
// In this case if a config file is specified but does not include
2020-07-21 10:53:14 +01:00
// the disable-default-queries field.
// We determine this by whether CodeQL.resolveQueries is called
// with the correct arguments.
const resolveQueriesArgs = [ ] ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( queries , extraSearchPath ) {
2020-07-21 10:53:14 +01:00
resolveQueriesArgs . push ( { queries , extraSearchPath } ) ;
return {
byLanguage : {
2020-09-14 10:44:43 +01:00
javascript : {
"foo.ql" : { } ,
2020-08-04 10:39:47 +01:00
} ,
2020-07-21 10:53:14 +01:00
} ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-07-21 10:53:14 +01:00
} ) ;
2020-07-21 12:46:19 +01:00
// The important point of this config is that it doesn't specify
2020-07-21 12:19:37 +01:00
// the disable-default-queries field.
2020-11-20 11:35:59 +01:00
// Any other details are hopefully irrelevant for this test.
2020-07-21 10:53:14 +01:00
const inputFileContents = `
paths:
- foo ` ;
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "foo" ) ) ;
const languages = "javascript" ;
2020-09-08 10:14:51 +01:00
const configFilePath = createConfigFile ( inputFileContents , tmpDir ) ;
2022-09-01 16:07:26 -07:00
await configUtils . initConfig ( languages , undefined , undefined , undefined , configFilePath , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-07-21 10:53:14 +01:00
// Check resolve queries was called correctly
t . deepEqual ( resolveQueriesArgs . length , 1 ) ;
2020-09-14 10:44:43 +01:00
t . deepEqual ( resolveQueriesArgs [ 0 ] . queries , [
"javascript-code-scanning.qls" ,
] ) ;
2020-07-21 10:53:14 +01:00
t . deepEqual ( resolveQueriesArgs [ 0 ] . extraSearchPath , undefined ) ;
} ) ;
} ) ;
2020-08-28 17:12:54 +01:00
/**
* Returns the provided queries, just in the right format for a resolved query
* This way we can test by seeing which returned items are in the final
* configuration.
*/
function queriesToResolvedQueryForm ( queries ) {
const dummyResolvedQueries = { } ;
2020-09-20 17:03:01 +08:00
for ( const q of queries ) {
2020-09-14 10:44:43 +01:00
dummyResolvedQueries [ q ] = { } ;
2020-09-20 17:03:01 +08:00
}
2020-08-28 17:12:54 +01:00
return {
byLanguage : {
2020-09-14 10:44:43 +01:00
javascript : dummyResolvedQueries ,
2020-08-28 17:12:54 +01:00
} ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
}
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Queries can be specified in config file" , async ( t ) => {
2020-08-24 15:37:07 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
const inputFileContents = `
name: my config
queries:
- uses: ./foo ` ;
2020-09-08 10:14:51 +01:00
const configFilePath = createConfigFile ( inputFileContents , tmpDir ) ;
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "foo" ) ) ;
2020-08-24 15:37:07 +01:00
const resolveQueriesArgs = [ ] ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( queries , extraSearchPath ) {
2020-08-24 15:37:07 +01:00
resolveQueriesArgs . push ( { queries , extraSearchPath } ) ;
2020-08-28 17:12:54 +01:00
return queriesToResolvedQueryForm ( queries ) ;
2020-08-24 15:37:07 +01:00
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-08-24 15:37:07 +01:00
} ) ;
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
2022-09-01 16:07:26 -07:00
const config = await configUtils . initConfig ( languages , undefined , undefined , undefined , configFilePath , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-08-24 15:37:07 +01:00
// Check resolveQueries was called correctly
// It'll be called once for the default queries
// and once for `./foo` from the config file.
t . deepEqual ( resolveQueriesArgs . length , 2 ) ;
t . deepEqual ( resolveQueriesArgs [ 1 ] . queries . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( resolveQueriesArgs [ 1 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } foo ` ) ) ;
2020-08-24 15:37:07 +01:00
// Now check that the end result contains the default queries and the query from config
2020-09-18 09:52:44 +01:00
t . deepEqual ( config . queries [ "javascript" ] . builtin . length , 1 ) ;
t . deepEqual ( config . queries [ "javascript" ] . custom . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( config . queries [ "javascript" ] . builtin [ 0 ] . endsWith ( "javascript-code-scanning.qls" ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 0 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } foo ` ) ) ;
2020-08-24 15:37:07 +01:00
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Queries from config file can be overridden in workflow file" , async ( t ) => {
2020-07-27 11:03:57 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
const inputFileContents = `
name: my config
queries:
- uses: ./foo ` ;
2020-09-08 10:14:51 +01:00
const configFilePath = createConfigFile ( inputFileContents , tmpDir ) ;
2020-08-24 14:33:02 +01:00
// This config item should take precedence over the config file but shouldn't affect the default queries.
2020-11-19 23:03:45 +01:00
const testQueries = "./override" ;
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "foo" ) ) ;
fs . mkdirSync ( path . join ( tmpDir , "override" ) ) ;
2020-07-27 11:03:57 +01:00
const resolveQueriesArgs = [ ] ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( queries , extraSearchPath ) {
2020-07-27 11:03:57 +01:00
resolveQueriesArgs . push ( { queries , extraSearchPath } ) ;
2020-08-28 17:12:54 +01:00
return queriesToResolvedQueryForm ( queries ) ;
2020-07-27 11:03:57 +01:00
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-07-27 11:03:57 +01:00
} ) ;
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
2022-09-01 16:07:26 -07:00
const config = await configUtils . initConfig ( languages , testQueries , undefined , undefined , configFilePath , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-07-27 11:03:57 +01:00
// Check resolveQueries was called correctly
2020-08-24 14:33:02 +01:00
// It'll be called once for the default queries and once for `./override`,
// but won't be called for './foo' from the config file.
t . deepEqual ( resolveQueriesArgs . length , 2 ) ;
t . deepEqual ( resolveQueriesArgs [ 1 ] . queries . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( resolveQueriesArgs [ 1 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } override ` ) ) ;
2020-08-24 14:33:02 +01:00
// Now check that the end result contains only the default queries and the override query
2020-09-18 09:52:44 +01:00
t . deepEqual ( config . queries [ "javascript" ] . builtin . length , 1 ) ;
t . deepEqual ( config . queries [ "javascript" ] . custom . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( config . queries [ "javascript" ] . builtin [ 0 ] . endsWith ( "javascript-code-scanning.qls" ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 0 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } override ` ) ) ;
2020-07-27 11:03:57 +01:00
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Queries in workflow file can be used in tandem with the 'disable default queries' option" , async ( t ) => {
2020-08-28 16:53:11 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
2020-09-14 10:44:43 +01:00
process . env [ "RUNNER_TEMP" ] = tmpDir ;
process . env [ "GITHUB_WORKSPACE" ] = tmpDir ;
2020-08-28 16:53:11 +01:00
const inputFileContents = `
name: my config
disable-default-queries: true ` ;
2020-09-08 10:14:51 +01:00
const configFilePath = createConfigFile ( inputFileContents , tmpDir ) ;
2020-11-19 23:03:45 +01:00
const testQueries = "./workflow-query" ;
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "workflow-query" ) ) ;
2020-08-28 16:53:11 +01:00
const resolveQueriesArgs = [ ] ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( queries , extraSearchPath ) {
2020-08-28 16:53:11 +01:00
resolveQueriesArgs . push ( { queries , extraSearchPath } ) ;
2020-08-28 17:12:54 +01:00
return queriesToResolvedQueryForm ( queries ) ;
2020-08-28 16:53:11 +01:00
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-08-28 16:53:11 +01:00
} ) ;
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
2022-09-01 16:07:26 -07:00
const config = await configUtils . initConfig ( languages , testQueries , undefined , undefined , configFilePath , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-08-28 16:53:11 +01:00
// Check resolveQueries was called correctly
// It'll be called once for `./workflow-query`,
// but won't be called for the default one since that was disabled
t . deepEqual ( resolveQueriesArgs . length , 1 ) ;
t . deepEqual ( resolveQueriesArgs [ 0 ] . queries . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( resolveQueriesArgs [ 0 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } workflow-query ` ) ) ;
2020-08-28 16:53:11 +01:00
// Now check that the end result contains only the workflow query, and not the default one
2020-09-18 09:52:44 +01:00
t . deepEqual ( config . queries [ "javascript" ] . builtin . length , 0 ) ;
t . deepEqual ( config . queries [ "javascript" ] . custom . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( config . queries [ "javascript" ] . custom [ 0 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } workflow-query ` ) ) ;
2020-08-28 16:53:11 +01:00
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Multiple queries can be specified in workflow file, no config file required" , async ( t ) => {
2020-07-27 15:41:17 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "override1" ) ) ;
fs . mkdirSync ( path . join ( tmpDir , "override2" ) ) ;
2020-11-19 23:03:45 +01:00
const testQueries = "./override1,./override2" ;
2020-07-27 15:41:17 +01:00
const resolveQueriesArgs = [ ] ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( queries , extraSearchPath ) {
2020-07-27 15:41:17 +01:00
resolveQueriesArgs . push ( { queries , extraSearchPath } ) ;
2020-08-28 17:12:54 +01:00
return queriesToResolvedQueryForm ( queries ) ;
2020-07-27 15:41:17 +01:00
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-07-27 15:41:17 +01:00
} ) ;
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
2022-09-01 16:07:26 -07:00
const config = await configUtils . initConfig ( languages , testQueries , undefined , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-07-27 15:41:17 +01:00
// Check resolveQueries was called correctly:
// It'll be called once for the default queries,
2020-08-24 14:33:02 +01:00
// and then once for each of the two queries from the workflow
2020-07-27 15:41:17 +01:00
t . deepEqual ( resolveQueriesArgs . length , 3 ) ;
t . deepEqual ( resolveQueriesArgs [ 1 ] . queries . length , 1 ) ;
t . deepEqual ( resolveQueriesArgs [ 2 ] . queries . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( resolveQueriesArgs [ 1 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } override1 ` ) ) ;
t . true ( resolveQueriesArgs [ 2 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } override2 ` ) ) ;
2020-08-24 14:33:02 +01:00
// Now check that the end result contains both the queries from the workflow, as well as the defaults
2020-09-18 09:52:44 +01:00
t . deepEqual ( config . queries [ "javascript" ] . builtin . length , 1 ) ;
t . deepEqual ( config . queries [ "javascript" ] . custom . length , 2 ) ;
2022-06-16 16:21:19 -07:00
t . true ( config . queries [ "javascript" ] . builtin [ 0 ] . endsWith ( "javascript-code-scanning.qls" ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 0 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } override1 ` ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 1 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } override2 ` ) ) ;
2020-07-27 15:41:17 +01:00
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Queries in workflow file can be added to the set of queries without overriding config file" , async ( t ) => {
2020-08-27 17:11:56 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
2020-09-14 10:44:43 +01:00
process . env [ "RUNNER_TEMP" ] = tmpDir ;
process . env [ "GITHUB_WORKSPACE" ] = tmpDir ;
2020-08-27 17:11:56 +01:00
const inputFileContents = `
name: my config
queries:
- uses: ./foo ` ;
2020-09-08 10:14:51 +01:00
const configFilePath = createConfigFile ( inputFileContents , tmpDir ) ;
2020-08-27 17:11:56 +01:00
// These queries shouldn't override anything, because the value is prefixed with "+"
2020-11-19 23:03:45 +01:00
const testQueries = "+./additional1,./additional2" ;
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "foo" ) ) ;
fs . mkdirSync ( path . join ( tmpDir , "additional1" ) ) ;
fs . mkdirSync ( path . join ( tmpDir , "additional2" ) ) ;
2020-08-27 17:11:56 +01:00
const resolveQueriesArgs = [ ] ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( queries , extraSearchPath ) {
2020-08-27 17:11:56 +01:00
resolveQueriesArgs . push ( { queries , extraSearchPath } ) ;
2020-08-28 17:12:54 +01:00
return queriesToResolvedQueryForm ( queries ) ;
2020-08-27 17:11:56 +01:00
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-08-27 17:11:56 +01:00
} ) ;
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
2022-09-01 16:07:26 -07:00
const config = await configUtils . initConfig ( languages , testQueries , undefined , undefined , configFilePath , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-08-27 17:11:56 +01:00
// Check resolveQueries was called correctly
// It'll be called once for the default queries,
// once for each of additional1 and additional2,
// and once for './foo' from the config file
t . deepEqual ( resolveQueriesArgs . length , 4 ) ;
t . deepEqual ( resolveQueriesArgs [ 1 ] . queries . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( resolveQueriesArgs [ 1 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } additional1 ` ) ) ;
2020-08-27 17:11:56 +01:00
t . deepEqual ( resolveQueriesArgs [ 2 ] . queries . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( resolveQueriesArgs [ 2 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } additional2 ` ) ) ;
2020-08-27 17:11:56 +01:00
t . deepEqual ( resolveQueriesArgs [ 3 ] . queries . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( resolveQueriesArgs [ 3 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } foo ` ) ) ;
2020-08-27 17:11:56 +01:00
// Now check that the end result contains all the queries
2020-09-18 09:52:44 +01:00
t . deepEqual ( config . queries [ "javascript" ] . builtin . length , 1 ) ;
t . deepEqual ( config . queries [ "javascript" ] . custom . length , 3 ) ;
2022-06-16 16:21:19 -07:00
t . true ( config . queries [ "javascript" ] . builtin [ 0 ] . endsWith ( "javascript-code-scanning.qls" ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 0 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } additional1 ` ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 1 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } additional2 ` ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 2 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } foo ` ) ) ;
2020-08-27 17:11:56 +01:00
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Invalid queries in workflow file handled correctly" , async ( t ) => {
2020-08-24 16:44:59 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
2020-09-14 10:44:43 +01:00
const queries = "foo/bar@v1@v3" ;
const languages = "javascript" ;
2020-08-24 16:44:59 +01:00
// This function just needs to be type-correct; it doesn't need to do anything,
// since we're deliberately passing in invalid data
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2021-01-15 18:40:06 +01:00
async resolveQueries ( ) {
2020-08-24 16:44:59 +01:00
return {
byLanguage : {
2020-09-14 10:44:43 +01:00
javascript : { } ,
2020-08-24 16:44:59 +01:00
} ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-08-24 16:44:59 +01:00
} ) ;
try {
2022-09-01 16:07:26 -07:00
await configUtils . initConfig ( languages , queries , undefined , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
t . fail ( "initConfig did not throw error" ) ;
2020-08-24 16:44:59 +01:00
}
catch ( err ) {
t . deepEqual ( err , new Error ( configUtils . getQueryUsesInvalid ( undefined , "foo/bar@v1@v3" ) ) ) ;
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "API client used when reading remote config" , async ( t ) => {
2020-06-25 15:06:15 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( ) {
2020-06-26 15:33:59 +01:00
return {
2020-08-04 10:39:47 +01:00
byLanguage : {
2020-09-14 10:44:43 +01:00
javascript : {
"foo.ql" : { } ,
2020-08-04 10:39:47 +01:00
} ,
} ,
2020-06-26 15:33:59 +01:00
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-06-26 15:33:59 +01:00
} ) ;
2020-06-25 15:06:15 +01:00
const inputFileContents = `
name: my config
disable-default-queries: true
queries:
- uses: ./
2020-06-26 15:33:59 +01:00
- uses: ./foo
- uses: foo/bar@dev
2020-06-25 15:06:15 +01:00
paths-ignore:
- a
- b
paths:
- c/d ` ;
2020-06-26 13:51:14 +01:00
const dummyResponse = {
2020-07-07 18:32:29 +01:00
content : Buffer . from ( inputFileContents ) . toString ( "base64" ) ,
2020-06-26 13:51:14 +01:00
} ;
2020-07-07 18:32:29 +01:00
const spyGetContents = mockGetContents ( dummyResponse ) ;
2020-06-26 15:33:59 +01:00
// Create checkout directory for remote queries repository
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "foo/bar/dev" ) , { recursive : true } ) ;
const configFile = "octo-org/codeql-config/config.yaml@main" ;
const languages = "javascript" ;
2022-09-01 16:07:26 -07:00
await configUtils . initConfig ( languages , undefined , undefined , undefined , configFile , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-06-26 09:32:44 +01:00
t . assert ( spyGetContents . called ) ;
2020-06-25 15:06:15 +01:00
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Remote config handles the case where a directory is provided" , async ( t ) => {
2020-06-26 15:56:33 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
2020-07-07 18:32:29 +01:00
const dummyResponse = [ ] ; // directories are returned as arrays
mockGetContents ( dummyResponse ) ;
2020-09-14 10:44:43 +01:00
const repoReference = "octo-org/codeql-config/config.yaml@main" ;
2020-06-26 15:56:33 +01:00
try {
2022-09-01 16:07:26 -07:00
await configUtils . initConfig ( undefined , undefined , undefined , undefined , repoReference , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , ( 0 , codeql _1 . getCachedCodeQL ) ( ) , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-06-26 15:56:33 +01:00
}
catch ( err ) {
t . deepEqual ( err , new Error ( configUtils . getConfigFileDirectoryGivenMessage ( repoReference ) ) ) ;
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Invalid format of remote config handled correctly" , async ( t ) => {
2020-06-26 15:56:33 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
const dummyResponse = {
2020-07-07 18:32:29 +01:00
// note no "content" property here
2020-06-26 15:56:33 +01:00
} ;
2020-07-07 18:32:29 +01:00
mockGetContents ( dummyResponse ) ;
2020-09-14 10:44:43 +01:00
const repoReference = "octo-org/codeql-config/config.yaml@main" ;
2020-06-26 15:56:33 +01:00
try {
2022-09-01 16:07:26 -07:00
await configUtils . initConfig ( undefined , undefined , undefined , undefined , repoReference , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , ( 0 , codeql _1 . getCachedCodeQL ) ( ) , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-06-26 15:56:33 +01:00
}
catch ( err ) {
t . deepEqual ( err , new Error ( configUtils . getConfigFileFormatInvalidMessage ( repoReference ) ) ) ;
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "No detected languages" , async ( t ) => {
2020-08-06 17:45:42 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
2020-08-07 17:15:46 +01:00
mockListLanguages ( [ ] ) ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2021-05-23 16:27:46 +02:00
async resolveLanguages ( ) {
return { } ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2021-05-23 16:27:46 +02:00
} ) ;
2020-08-06 17:45:42 +01:00
try {
2022-09-01 16:07:26 -07:00
await configUtils . initConfig ( undefined , undefined , undefined , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-08-06 17:45:42 +01:00
}
catch ( err ) {
t . deepEqual ( err , new Error ( configUtils . getNoLanguagesError ( ) ) ) ;
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Unknown languages" , async ( t ) => {
2020-08-06 17:45:42 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
2021-05-21 11:49:50 +02:00
const languages = "rubbish,english" ;
2020-08-06 17:45:42 +01:00
try {
2022-09-01 16:07:26 -07:00
await configUtils . initConfig ( languages , undefined , undefined , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , ( 0 , codeql _1 . getCachedCodeQL ) ( ) , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-08-06 17:45:42 +01:00
}
catch ( err ) {
2021-05-21 11:49:50 +02:00
t . deepEqual ( err , new Error ( configUtils . getUnknownLanguagesError ( [ "rubbish" , "english" ] ) ) ) ;
2020-08-06 17:45:42 +01:00
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Config specifies packages" , async ( t ) => {
2021-06-03 09:32:44 -07:00
return await util . withTmpDir ( async ( tmpDir ) => {
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2021-06-03 09:32:44 -07:00
async resolveQueries ( ) {
return {
byLanguage : { } ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2021-06-03 09:32:44 -07:00
} ) ;
const inputFileContents = `
name: my config
disable-default-queries: true
packs:
- a/b@1.2.3
` ;
const configFile = path . join ( tmpDir , "codeql-config.yaml" ) ;
fs . writeFileSync ( configFile , inputFileContents ) ;
const languages = "javascript" ;
2022-09-01 16:07:26 -07:00
const { packs } = await configUtils . initConfig ( languages , undefined , undefined , undefined , configFile , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2021-06-03 09:32:44 -07:00
t . deepEqual ( packs , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . javascript ] : [ "a/b@1.2.3" ] ,
2021-06-03 09:32:44 -07:00
} ) ;
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Config specifies packages for multiple languages" , async ( t ) => {
2021-06-03 09:32:44 -07:00
return await util . withTmpDir ( async ( tmpDir ) => {
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2021-06-03 09:32:44 -07:00
async resolveQueries ( ) {
return {
byLanguage : {
cpp : { "/foo/a.ql" : { } } ,
} ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2021-06-03 09:32:44 -07:00
} ) ;
const inputFileContents = `
name: my config
disable-default-queries: true
queries:
- uses: ./foo
packs:
javascript:
- a/b@1.2.3
python:
- c/d@1.2.3
` ;
const configFile = path . join ( tmpDir , "codeql-config.yaml" ) ;
fs . writeFileSync ( configFile , inputFileContents ) ;
fs . mkdirSync ( path . join ( tmpDir , "foo" ) ) ;
const languages = "javascript,python,cpp" ;
2022-09-01 16:07:26 -07:00
const { packs , queries } = await configUtils . initConfig ( languages , undefined , undefined , undefined , configFile , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2021-06-03 09:32:44 -07:00
t . deepEqual ( packs , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . javascript ] : [ "a/b@1.2.3" ] ,
[ languages _1 . Language . python ] : [ "c/d@1.2.3" ] ,
2021-06-03 09:32:44 -07:00
} ) ;
t . deepEqual ( queries , {
cpp : {
builtin : [ ] ,
custom : [
{
queries : [ "/foo/a.ql" ] ,
searchPath : tmpDir ,
} ,
] ,
} ,
javascript : {
builtin : [ ] ,
custom : [ ] ,
} ,
python : {
builtin : [ ] ,
custom : [ ] ,
} ,
} ) ;
} ) ;
} ) ;
2020-05-26 19:23:28 +01:00
function doInvalidInputTest ( testName , inputFileContents , expectedErrorMessageGenerator ) {
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( ` load invalid input - ${ testName } ` , async ( t ) => {
2020-05-05 17:32:58 +01:00
return await util . withTmpDir ( async ( tmpDir ) => {
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( ) {
2020-07-21 11:05:23 +01:00
return {
byLanguage : { } ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-07-21 11:05:23 +01:00
} ) ;
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
const configFile = "input" ;
2020-08-25 16:19:15 +01:00
const inputFile = path . join ( tmpDir , configFile ) ;
2020-09-14 10:44:43 +01:00
fs . writeFileSync ( inputFile , inputFileContents , "utf8" ) ;
2020-05-05 17:32:58 +01:00
try {
2022-09-01 16:07:26 -07:00
await configUtils . initConfig ( languages , undefined , undefined , undefined , configFile , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-05-05 17:32:58 +01:00
}
catch ( err ) {
2020-05-26 19:23:28 +01:00
t . deepEqual ( err , new Error ( expectedErrorMessageGenerator ( inputFile ) ) ) ;
2020-05-05 17:32:58 +01:00
}
} ) ;
} ) ;
}
2020-09-14 10:44:43 +01:00
doInvalidInputTest ( "name invalid type" , `
2020-05-26 19:23:28 +01:00
name:
- foo: bar ` , configUtils . getNameInvalid ) ;
2020-09-14 10:44:43 +01:00
doInvalidInputTest ( "disable-default-queries invalid type" , ` disable-default-queries: 42 ` , configUtils . getDisableDefaultQueriesInvalid ) ;
doInvalidInputTest ( "queries invalid type" , ` queries: foo ` , configUtils . getQueriesInvalid ) ;
doInvalidInputTest ( "paths-ignore invalid type" , ` paths-ignore: bar ` , configUtils . getPathsIgnoreInvalid ) ;
doInvalidInputTest ( "paths invalid type" , ` paths: 17 ` , configUtils . getPathsInvalid ) ;
doInvalidInputTest ( "queries uses invalid type" , `
2020-05-26 19:23:28 +01:00
queries:
- uses:
2022-08-23 09:25:59 -07:00
- hello: world ` , configUtils . getQueriesMissingUses ) ;
2020-06-08 13:40:17 +01:00
function doInvalidQueryUsesTest ( input , expectedErrorMessageGenerator ) {
2020-05-26 19:23:28 +01:00
// Invalid contents of a "queries.uses" field.
// Should fail with the expected error message
const inputFileContents = `
name: my config
queries:
- name: foo
2020-09-14 10:44:43 +01:00
uses: ${ input } ` ;
doInvalidInputTest ( ` queries uses " ${ input } " ` , inputFileContents , expectedErrorMessageGenerator ) ;
2020-05-26 19:23:28 +01:00
}
// Various "uses" fields, and the errors they should produce
2020-09-14 10:44:43 +01:00
doInvalidQueryUsesTest ( "''" , ( c ) => configUtils . getQueryUsesInvalid ( c , undefined ) ) ;
doInvalidQueryUsesTest ( "foo/bar" , ( c ) => configUtils . getQueryUsesInvalid ( c , "foo/bar" ) ) ;
doInvalidQueryUsesTest ( "foo/bar@v1@v2" , ( c ) => configUtils . getQueryUsesInvalid ( c , "foo/bar@v1@v2" ) ) ;
doInvalidQueryUsesTest ( "foo@master" , ( c ) => configUtils . getQueryUsesInvalid ( c , "foo@master" ) ) ;
doInvalidQueryUsesTest ( "https://github.com/foo/bar@master" , ( c ) => configUtils . getQueryUsesInvalid ( c , "https://github.com/foo/bar@master" ) ) ;
doInvalidQueryUsesTest ( "./foo" , ( c ) => configUtils . getLocalPathDoesNotExist ( c , "foo" ) ) ;
doInvalidQueryUsesTest ( "./.." , ( c ) => configUtils . getLocalPathOutsideOfRepository ( c , ".." ) ) ;
2020-07-08 15:06:45 +01:00
const validPaths = [
2020-09-14 10:44:43 +01:00
"foo" ,
"foo/" ,
"foo/**" ,
"foo/**/" ,
"foo/**/**" ,
"foo/**/bar/**/baz" ,
"**/" ,
"**/foo" ,
"/foo" ,
2020-07-08 15:06:45 +01:00
] ;
2020-09-14 10:44:43 +01:00
const invalidPaths = [ "a/***/b" , "a/**b" , "a/b**" , "**" ] ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "path validations" , ( t ) => {
2020-07-08 15:06:45 +01:00
// Dummy values to pass to validateAndSanitisePath
2020-09-14 10:44:43 +01:00
const propertyName = "paths" ;
const configFile = "./.github/codeql/config.yml" ;
2020-11-19 23:03:45 +01:00
for ( const validPath of validPaths ) {
2021-09-10 13:53:13 -07:00
t . truthy ( configUtils . validateAndSanitisePath ( validPath , propertyName , configFile , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ) ;
2020-07-08 15:06:45 +01:00
}
2020-11-19 23:03:45 +01:00
for ( const invalidPath of invalidPaths ) {
2021-09-10 13:53:13 -07:00
t . throws ( ( ) => configUtils . validateAndSanitisePath ( invalidPath , propertyName , configFile , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ) ;
2020-07-08 15:06:45 +01:00
}
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "path sanitisation" , ( t ) => {
2020-07-08 15:06:45 +01:00
// Dummy values to pass to validateAndSanitisePath
2020-09-14 10:44:43 +01:00
const propertyName = "paths" ;
const configFile = "./.github/codeql/config.yml" ;
2020-07-08 15:06:45 +01:00
// Valid paths are not modified
2021-09-10 13:53:13 -07:00
t . deepEqual ( configUtils . validateAndSanitisePath ( "foo/bar" , propertyName , configFile , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) , "foo/bar" ) ;
2020-07-08 15:06:45 +01:00
// Trailing stars are stripped
2021-09-10 13:53:13 -07:00
t . deepEqual ( configUtils . validateAndSanitisePath ( "foo/**" , propertyName , configFile , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) , "foo/" ) ;
2020-07-08 15:06:45 +01:00
} ) ;
2021-06-03 09:32:44 -07:00
/**
* Test macro for ensuring the packs block is valid
*/
2022-02-01 18:01:11 +00:00
const parsePacksMacro = ava _1 . default . macro ( {
2022-06-22 13:06:19 -07:00
exec : ( t , packsByLanguage , languages , expected ) => t . deepEqual ( configUtils . parsePacksFromConfig ( packsByLanguage , languages , "/a/b" , mockLogger ) , expected ) ,
2022-02-01 18:01:11 +00:00
title : ( providedTitle = "" ) => ` Parse Packs: ${ providedTitle } ` ,
} ) ;
2021-06-03 09:32:44 -07:00
/**
* Test macro for testing when the packs block is invalid
*/
2022-02-01 18:01:11 +00:00
const parsePacksErrorMacro = ava _1 . default . macro ( {
2022-06-22 13:06:19 -07:00
exec : ( t , packsByLanguage , languages , expected ) => t . throws ( ( ) => configUtils . parsePacksFromConfig ( packsByLanguage , languages , "/a/b" , { } ) , {
2021-06-03 09:32:44 -07:00
message : expected ,
2022-02-01 18:01:11 +00:00
} ) ,
title : ( providedTitle = "" ) => ` Parse Packs Error: ${ providedTitle } ` ,
} ) ;
2021-06-23 15:41:52 -07:00
/**
* Test macro for testing when the packs block is invalid
*/
2022-02-01 18:01:11 +00:00
const invalidPackNameMacro = ava _1 . default . macro ( {
exec : ( t , name ) => parsePacksErrorMacro . exec ( t , { [ languages _1 . Language . cpp ] : [ name ] } , [ languages _1 . Language . cpp ] , new RegExp ( ` The configuration file "/a/b" is invalid: property "packs" " ${ name } " is not a valid pack ` ) ) ,
title : ( _providedTitle , arg ) => ` Invalid pack string: ${ arg } ` ,
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "no packs" , parsePacksMacro , { } , [ ] , { } ) ;
( 0 , ava _1 . default ) ( "two packs" , parsePacksMacro , [ "a/b" , "c/d@1.2.3" ] , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
2021-06-03 09:32:44 -07:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "two packs with spaces" , parsePacksMacro , [ " a/b " , " c/d@1.2.3 " ] , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
2021-06-23 15:41:52 -07:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "two packs with language" , parsePacksMacro , {
2021-06-03 09:32:44 -07:00
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
[ languages _1 . Language . java ] : [ "d/e" , "f/g@1.2.3" ] ,
} , [ languages _1 . Language . cpp , languages _1 . Language . java , languages _1 . Language . csharp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
[ languages _1 . Language . java ] : [ "d/e" , "f/g@1.2.3" ] ,
} ) ;
2022-06-22 13:06:19 -07:00
( 0 , ava _1 . default ) ( "two packs with unused language in config" , parsePacksMacro , {
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
[ languages _1 . Language . java ] : [ "d/e" , "f/g@1.2.3" ] ,
} , [ languages _1 . Language . cpp , languages _1 . Language . csharp ] , {
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
} ) ;
2022-04-26 19:47:59 -07:00
( 0 , ava _1 . default ) ( "packs with other valid names" , parsePacksMacro , [
// ranges are ok
"c/d@1.0" ,
"c/d@~1.0.0" ,
"c/d@~1.0.0:a/b" ,
"c/d@~1.0.0+abc:a/b" ,
"c/d@~1.0.0-abc:a/b" ,
"c/d:a/b" ,
// whitespace is removed
" c/d @ ~1.0.0 : b.qls " ,
// and it is retained within a path
" c/d @ ~1.0.0 : b/a path with/spaces.qls " ,
// this is valid. the path is '@'. It will probably fail when passed to the CLI
"c/d@1.2.3:@" ,
// this is valid, too. It will fail if it doesn't match a path
// (globbing is not done)
"c/d@1.2.3:+*)_(" ,
] , [ languages _1 . Language . cpp ] , {
2021-06-03 09:32:44 -07:00
[ languages _1 . Language . cpp ] : [
2022-04-26 19:47:59 -07:00
"c/d@1.0" ,
"c/d@~1.0.0" ,
"c/d@~1.0.0:a/b" ,
"c/d@~1.0.0+abc:a/b" ,
"c/d@~1.0.0-abc:a/b" ,
"c/d:a/b" ,
"c/d@~1.0.0:b.qls" ,
"c/d@~1.0.0:b/a path with/spaces.qls" ,
"c/d@1.2.3:@" ,
"c/d@1.2.3:+*)_(" ,
2021-06-03 09:32:44 -07:00
] ,
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "no language" , parsePacksErrorMacro , [ "a/b@1.2.3" ] , [ languages _1 . Language . java , languages _1 . Language . python ] , /The configuration file "\/a\/b" is invalid: property "packs" must split packages by language/ ) ;
( 0 , ava _1 . default ) ( "not an array" , parsePacksErrorMacro , { [ languages _1 . Language . cpp ] : "c/d" } , [ languages _1 . Language . cpp ] , /The configuration file "\/a\/b" is invalid: property "packs" must be an array of non-empty strings/ ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c" ) ; // all packs require at least a scope and a name
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c-/d" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "-c/d" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d_d" ) ;
2022-04-26 19:47:59 -07:00
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d@@" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d@1.0.0:" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d:" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d:/a" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "@1.0.0:a" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d@../a" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d@b/../a" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d:z@1" ) ;
2022-06-27 13:13:55 -07:00
/**
* Test macro for pretty printing pack specs
*/
const packSpecPrettyPrintingMacro = ava _1 . default . macro ( {
exec : ( t , packStr , packObj ) => {
const parsed = configUtils . parsePacksSpecification ( packStr ) ;
t . deepEqual ( parsed , packObj , "parsed pack spec is correct" ) ;
const stringified = configUtils . prettyPrintPack ( packObj ) ;
t . deepEqual ( stringified , packStr . trim ( ) , "pretty-printed pack spec is correct" ) ;
t . deepEqual ( configUtils . validatePackSpecification ( packStr ) , packStr . trim ( ) , "pack spec is valid" ) ;
} ,
title : ( _providedTitle , packStr ,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_packObj ) => ` Prettyprint pack spec: ' ${ packStr } ' ` ,
} ) ;
( 0 , ava _1 . default ) ( packSpecPrettyPrintingMacro , "a/b" , {
name : "a/b" ,
version : undefined ,
path : undefined ,
} ) ;
( 0 , ava _1 . default ) ( packSpecPrettyPrintingMacro , "a/b@~1.2.3" , {
name : "a/b" ,
version : "~1.2.3" ,
path : undefined ,
} ) ;
( 0 , ava _1 . default ) ( packSpecPrettyPrintingMacro , "a/b@~1.2.3:abc/def" , {
name : "a/b" ,
version : "~1.2.3" ,
path : "abc/def" ,
} ) ;
( 0 , ava _1 . default ) ( packSpecPrettyPrintingMacro , "a/b:abc/def" , {
name : "a/b" ,
version : undefined ,
path : "abc/def" ,
} ) ;
( 0 , ava _1 . default ) ( packSpecPrettyPrintingMacro , " a/b:abc/def " , {
name : "a/b" ,
version : undefined ,
path : "abc/def" ,
} ) ;
2021-06-23 15:41:52 -07:00
/**
* Test macro for testing the packs block and the packs input
*/
function parseInputAndConfigMacro ( t , packsFromConfig , packsFromInput , languages , expected ) {
2022-08-11 09:56:08 -07:00
t . deepEqual ( configUtils . parsePacks ( packsFromConfig , packsFromInput , ! ! ( packsFromInput === null || packsFromInput === void 0 ? void 0 : packsFromInput . trim ( ) . startsWith ( "+" ) ) , // coerce to boolean
languages , "/a/b" , mockLogger ) , expected ) ;
2021-06-23 15:41:52 -07:00
}
parseInputAndConfigMacro . title = ( providedTitle ) => ` Parse Packs input and config: ${ providedTitle } ` ;
2022-06-22 13:06:19 -07:00
const mockLogger = {
info : ( message ) => {
console . log ( message ) ;
} ,
} ;
2022-06-19 16:44:24 -07:00
function parseInputAndConfigErrorMacro ( t , packsFromConfig , packsFromInput , languages , packsFromInputOverride , expected ) {
2021-06-23 15:41:52 -07:00
t . throws ( ( ) => {
2022-06-19 16:44:24 -07:00
configUtils . parsePacks ( packsFromConfig , packsFromInput , packsFromInputOverride , languages , "/a/b" , mockLogger ) ;
2021-06-23 15:41:52 -07:00
} , {
message : expected ,
} ) ;
}
parseInputAndConfigErrorMacro . title = ( providedTitle ) => ` Parse Packs input and config Error: ${ providedTitle } ` ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "input only" , parseInputAndConfigMacro , { } , " c/d " , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "c/d" ] ,
2021-06-23 15:41:52 -07:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "input only with multiple" , parseInputAndConfigMacro , { } , "a/b , c/d@1.2.3" , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
2021-06-23 15:41:52 -07:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "input only with +" , parseInputAndConfigMacro , { } , " + a/b , c/d@1.2.3 " , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
2021-06-23 15:41:52 -07:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "config only" , parseInputAndConfigMacro , [ "a/b" , "c/d" ] , " " , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d" ] ,
2021-06-23 15:41:52 -07:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "input overrides" , parseInputAndConfigMacro , [ "a/b" , "c/d" ] , " e/f, g/h@1.2.3 " , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "e/f" , "g/h@1.2.3" ] ,
2021-06-23 15:41:52 -07:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "input and config" , parseInputAndConfigMacro , [ "a/b" , "c/d" ] , " +e/f, g/h@1.2.3 " , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "e/f" , "g/h@1.2.3" , "a/b" , "c/d" ] ,
2021-06-23 15:41:52 -07:00
} ) ;
2022-06-19 16:44:24 -07:00
( 0 , ava _1 . default ) ( "input with no language" , parseInputAndConfigErrorMacro , { } , "c/d" , [ ] , false , /No languages specified/ ) ;
( 0 , ava _1 . default ) ( "input with two languages" , parseInputAndConfigErrorMacro , { } , "c/d" , [ languages _1 . Language . cpp , languages _1 . Language . csharp ] , false , /multi-language analysis/ ) ;
( 0 , ava _1 . default ) ( "input with + only" , parseInputAndConfigErrorMacro , { } , " + " , [ languages _1 . Language . cpp ] , true , /remove the '\+'/ ) ;
( 0 , ava _1 . default ) ( "input with invalid pack name" , parseInputAndConfigErrorMacro , { } , " xxx" , [ languages _1 . Language . cpp ] , false , /"xxx" is not a valid pack/ ) ;
2022-02-01 18:01:11 +00:00
const mlPoweredQueriesMacro = ava _1 . default . macro ( {
2022-02-04 16:28:09 +00:00
exec : async ( t , codeQLVersion , isMlPoweredQueriesFlagEnabled , packsInput , queriesInput , expectedVersionString ) => {
2022-02-01 18:01:11 +00:00
return await util . withTmpDir ( async ( tmpDir ) => {
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
async getVersion ( ) {
return codeQLVersion ;
} ,
async resolveQueries ( ) {
return {
byLanguage : {
javascript : { "fake-query.ql" : { } } ,
} ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2021-12-16 17:12:25 +00:00
} ) ;
2022-09-01 16:07:26 -07:00
const { packs } = await configUtils . initConfig ( "javascript" , queriesInput , packsInput , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example " } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , feature _flags _1 . createFeatureFlags ) ( isMlPoweredQueriesFlagEnabled
2022-02-01 18:01:11 +00:00
? [ feature _flags _1 . FeatureFlag . MlPoweredQueriesEnabled ]
: [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2022-02-04 16:28:09 +00:00
if ( expectedVersionString !== undefined ) {
2022-02-01 18:01:11 +00:00
t . deepEqual ( packs , {
[ languages _1 . Language . javascript ] : [
2022-04-26 19:47:59 -07:00
` codeql/javascript-experimental-atm-queries@ ${ expectedVersionString } ` ,
2022-02-01 18:01:11 +00:00
] ,
} ) ;
}
else {
t . deepEqual ( packs , { } ) ;
}
} ) ;
} ,
2022-02-04 16:28:09 +00:00
title : ( _providedTitle , codeQLVersion , isMlPoweredQueriesFlagEnabled , packsInput , queriesInput , expectedVersionString ) => ` ML-powered queries ${ expectedVersionString !== undefined
? ` ${ expectedVersionString } are `
: "aren't" } loaded for packs: ${ packsInput } , queries: ${ queriesInput } using CLI v ${ codeQLVersion } when feature flag is ${ isMlPoweredQueriesFlagEnabled ? "enabled" : "disabled" } ` ,
} ) ;
2022-03-30 18:05:12 +01:00
// macro, codeQLVersion, isMlPoweredQueriesFlagEnabled, packsInput, queriesInput, expectedVersionString
2022-03-30 18:17:06 +01:00
// Test that ML-powered queries aren't run on v2.7.4 of the CLI.
2022-02-04 16:28:09 +00:00
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.7.4" , true , undefined , "security-extended" , undefined ) ;
2022-03-30 18:17:06 +01:00
// Test that ML-powered queries aren't run when the feature flag is off.
2022-02-04 16:28:09 +00:00
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.7.5" , false , undefined , "security-extended" , undefined ) ;
2022-04-28 17:00:18 +01:00
// Test that the ~0.1.0 version of ML-powered queries is run on v2.8.3 of the CLI.
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.8.3" , true , undefined , "security-extended" , process . platform === "win32" ? undefined : "~0.1.0" ) ;
2022-03-30 18:17:06 +01:00
// Test that ML-powered queries aren't run when the user hasn't specified that we should run the
// `security-extended` or `security-and-quality` query suite.
2022-02-04 16:28:09 +00:00
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.7.5" , true , undefined , undefined , undefined ) ;
2022-04-28 17:00:18 +01:00
// Test that ML-powered queries are run on non-Windows platforms running `security-extended` on
// versions of the CodeQL CLI prior to 2.9.0.
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.8.5" , true , undefined , "security-extended" , process . platform === "win32" ? undefined : "~0.2.0" ) ;
// Test that ML-powered queries are run on non-Windows platforms running `security-and-quality` on
// versions of the CodeQL CLI prior to 2.9.0.
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.8.5" , true , undefined , "security-and-quality" , process . platform === "win32" ? undefined : "~0.2.0" ) ;
// Test that ML-powered queries are run on all platforms running `security-extended` on CodeQL CLI
// 2.9.0+.
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.9.0" , true , undefined , "security-extended" , "~0.2.0" ) ;
// Test that ML-powered queries are run on all platforms running `security-and-quality` on CodeQL
// CLI 2.9.0+.
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.9.0" , true , undefined , "security-and-quality" , "~0.2.0" ) ;
2022-03-30 18:17:06 +01:00
// Test that we don't inject an ML-powered query pack if the user has already specified one.
2022-04-29 18:18:19 +01:00
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.9.0" , true , "codeql/javascript-experimental-atm-queries@0.0.1" , "security-and-quality" , "0.0.1" ) ;
2022-06-15 10:56:18 +01:00
// Test that ML-powered queries are run on all platforms running `security-extended` on CodeQL
// CLI 2.9.3+.
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.9.3" , true , undefined , "security-extended" , "~0.3.0" ) ;
2022-06-13 15:46:39 +01:00
// Test that ML-powered queries are run on all platforms running `security-and-quality` on CodeQL
// CLI 2.9.3+.
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.9.3" , true , undefined , "security-and-quality" , "~0.3.0" ) ;
2022-06-19 16:44:24 -07:00
const calculateAugmentationMacro = ava _1 . default . macro ( {
exec : async ( t , _title , rawPacksInput , rawQueriesInput , languages , expectedAugmentationProperties ) => {
const actualAugmentationProperties = configUtils . calculateAugmentation ( rawPacksInput , rawQueriesInput , languages ) ;
t . deepEqual ( actualAugmentationProperties , expectedAugmentationProperties ) ;
} ,
title : ( _ , title ) => ` Calculate Augmentation: ${ title } ` ,
} ) ;
( 0 , ava _1 . default ) ( calculateAugmentationMacro , "All empty" , undefined , undefined , [ languages _1 . Language . javascript ] , {
queriesInputCombines : false ,
queriesInput : undefined ,
packsInputCombines : false ,
packsInput : undefined ,
injectedMlQueries : false ,
} ) ;
( 0 , ava _1 . default ) ( calculateAugmentationMacro , "With queries" , undefined , " a, b , c, d" , [ languages _1 . Language . javascript ] , {
queriesInputCombines : false ,
queriesInput : [ { uses : "a" } , { uses : "b" } , { uses : "c" } , { uses : "d" } ] ,
packsInputCombines : false ,
packsInput : undefined ,
injectedMlQueries : false ,
} ) ;
( 0 , ava _1 . default ) ( calculateAugmentationMacro , "With queries combining" , undefined , " + a, b , c, d " , [ languages _1 . Language . javascript ] , {
queriesInputCombines : true ,
queriesInput : [ { uses : "a" } , { uses : "b" } , { uses : "c" } , { uses : "d" } ] ,
packsInputCombines : false ,
packsInput : undefined ,
injectedMlQueries : false ,
} ) ;
( 0 , ava _1 . default ) ( calculateAugmentationMacro , "With packs" , " codeql/a , codeql/b , codeql/c , codeql/d " , undefined , [ languages _1 . Language . javascript ] , {
queriesInputCombines : false ,
queriesInput : undefined ,
packsInputCombines : false ,
packsInput : [ "codeql/a" , "codeql/b" , "codeql/c" , "codeql/d" ] ,
injectedMlQueries : false ,
} ) ;
( 0 , ava _1 . default ) ( calculateAugmentationMacro , "With packs combining" , " + codeql/a, codeql/b, codeql/c, codeql/d" , undefined , [ languages _1 . Language . javascript ] , {
queriesInputCombines : false ,
queriesInput : undefined ,
packsInputCombines : true ,
packsInput : [ "codeql/a" , "codeql/b" , "codeql/c" , "codeql/d" ] ,
injectedMlQueries : false ,
} ) ;
const calculateAugmentationErrorMacro = ava _1 . default . macro ( {
exec : async ( t , _title , rawPacksInput , rawQueriesInput , languages , expectedError ) => {
t . throws ( ( ) => configUtils . calculateAugmentation ( rawPacksInput , rawQueriesInput , languages ) , { message : expectedError } ) ;
} ,
title : ( _ , title ) => ` Calculate Augmentation Error: ${ title } ` ,
} ) ;
( 0 , ava _1 . default ) ( calculateAugmentationErrorMacro , "Plus (+) with nothing else (queries)" , undefined , " + " , [ languages _1 . Language . javascript ] , /The workflow property "queries" is invalid/ ) ;
( 0 , ava _1 . default ) ( calculateAugmentationErrorMacro , "Plus (+) with nothing else (packs)" , " + " , undefined , [ languages _1 . Language . javascript ] , /The workflow property "packs" is invalid/ ) ;
( 0 , ava _1 . default ) ( calculateAugmentationErrorMacro , "Packs input with multiple languages" , " + a/b, c/d " , undefined , [ languages _1 . Language . javascript , languages _1 . Language . java ] , /Cannot specify a 'packs' input in a multi-language analysis/ ) ;
( 0 , ava _1 . default ) ( calculateAugmentationErrorMacro , "Packs input with no languages" , " + a/b, c/d " , undefined , [ ] , /No languages specified/ ) ;
( 0 , ava _1 . default ) ( calculateAugmentationErrorMacro , "Invalid packs" , " a-pack-without-a-scope " , undefined , [ languages _1 . Language . javascript ] , /"a-pack-without-a-scope" is not a valid pack/ ) ;
2022-08-29 12:57:46 -07:00
( 0 , ava _1 . default ) ( "downloadPacks-no-registries" , async ( t ) => {
return await util . withTmpDir ( async ( tmpDir ) => {
const packDownloadStub = sinon . stub ( ) ;
packDownloadStub . callsFake ( ( packs ) => ( {
packs ,
} ) ) ;
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
packDownload : packDownloadStub ,
} ) ;
const logger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
// packs are supplied for go, java, and python
// analyzed languages are java, javascript, and python
await configUtils . downloadPacks ( codeQL , [ languages _1 . Language . javascript , languages _1 . Language . java , languages _1 . Language . python ] , {
java : [ "a" , "b" ] ,
go : [ "c" , "d" ] ,
python : [ "e" , "f" ] ,
2022-09-06 10:41:32 -07:00
} , undefined , // registries
sampleApiDetails , tmpDir , logger ) ;
// Expecting packs to be downloaded once for java and once for python
2022-08-29 12:57:46 -07:00
t . deepEqual ( packDownloadStub . callCount , 2 ) ;
// no config file was created, so pass `undefined` as the config file path
t . deepEqual ( packDownloadStub . firstCall . args , [ [ "a" , "b" ] , undefined ] ) ;
t . deepEqual ( packDownloadStub . secondCall . args , [ [ "e" , "f" ] , undefined ] ) ;
} ) ;
} ) ;
( 0 , ava _1 . default ) ( "downloadPacks-with-registries" , async ( t ) => {
// same thing, but this time include a registries block and
// associated env vars
return await util . withTmpDir ( async ( tmpDir ) => {
process . env . GITHUB _TOKEN = "not-a-token" ;
process . env . CODEQL _REGISTRIES _AUTH = "not-a-registries-auth" ;
const logger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
const registries = [
{
2022-09-07 20:32:47 -07:00
// no slash
2022-08-29 12:57:46 -07:00
url : "http://ghcr.io" ,
packages : [ "codeql/*" , "dsp-testing/*" ] ,
2022-09-01 16:07:26 -07:00
token : "not-a-token" ,
2022-08-29 12:57:46 -07:00
} ,
{
2022-09-07 20:32:47 -07:00
// with slash
2022-08-29 12:57:46 -07:00
url : "https://containers.GHEHOSTNAME1/v2/" ,
packages : "semmle/*" ,
2022-09-06 10:41:32 -07:00
token : "still-not-a-token" ,
2022-08-29 12:57:46 -07:00
} ,
] ;
2022-09-07 20:32:47 -07:00
// append a slash to the first url
const expectedRegistries = registries . map ( ( r , i ) => ( {
packages : r . packages ,
url : i === 0 ? ` ${ r . url } / ` : r . url ,
} ) ) ;
2022-08-29 12:57:46 -07:00
const expectedConfigFile = path . join ( tmpDir , "qlconfig.yml" ) ;
const packDownloadStub = sinon . stub ( ) ;
packDownloadStub . callsFake ( ( packs , configFile ) => {
t . deepEqual ( configFile , expectedConfigFile ) ;
// verify the env vars were set correctly
2022-09-06 10:41:32 -07:00
t . deepEqual ( process . env . GITHUB _TOKEN , sampleApiDetails . auth ) ;
2022-09-06 10:45:02 -07:00
t . deepEqual ( process . env . CODEQL _REGISTRIES _AUTH , "http://ghcr.io=not-a-token,https://containers.GHEHOSTNAME1/v2/=still-not-a-token" ) ;
2022-08-29 12:57:46 -07:00
// verify the config file contents were set correctly
const config = yaml . load ( fs . readFileSync ( configFile , "utf8" ) ) ;
2022-09-07 20:32:47 -07:00
t . deepEqual ( config . registries , expectedRegistries ) ;
2022-08-29 12:57:46 -07:00
return {
packs ,
} ;
} ) ;
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
packDownload : packDownloadStub ,
2022-09-07 15:26:30 -07:00
getVersion : ( ) => Promise . resolve ( "2.10.5" ) ,
2022-08-29 12:57:46 -07:00
} ) ;
// packs are supplied for go, java, and python
// analyzed languages are java, javascript, and python
await configUtils . downloadPacks ( codeQL , [ languages _1 . Language . javascript , languages _1 . Language . java , languages _1 . Language . python ] , {
java : [ "a" , "b" ] ,
go : [ "c" , "d" ] ,
python : [ "e" , "f" ] ,
2022-09-01 16:07:26 -07:00
} , registries , sampleApiDetails , tmpDir , logger ) ;
2022-08-29 12:57:46 -07:00
// Same packs are downloaded as in previous test
t . deepEqual ( packDownloadStub . callCount , 2 ) ;
t . deepEqual ( packDownloadStub . firstCall . args , [
[ "a" , "b" ] ,
expectedConfigFile ,
] ) ;
t . deepEqual ( packDownloadStub . secondCall . args , [
[ "e" , "f" ] ,
expectedConfigFile ,
] ) ;
// Verify that the env vars were unset.
t . deepEqual ( process . env . GITHUB _TOKEN , "not-a-token" ) ;
t . deepEqual ( process . env . CODEQL _REGISTRIES _AUTH , "not-a-registries-auth" ) ;
2022-08-26 13:48:08 -07:00
} ) ;
} ) ;
2022-09-07 15:26:30 -07:00
( 0 , ava _1 . default ) ( "downloadPacks-with-registries fails on 2.10.3" , async ( t ) => {
// same thing, but this time include a registries block and
// associated env vars
return await util . withTmpDir ( async ( tmpDir ) => {
process . env . GITHUB _TOKEN = "not-a-token" ;
process . env . CODEQL _REGISTRIES _AUTH = "not-a-registries-auth" ;
const logger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
const registries = [
{
url : "http://ghcr.io" ,
packages : [ "codeql/*" , "dsp-testing/*" ] ,
token : "not-a-token" ,
} ,
{
url : "https://containers.GHEHOSTNAME1/v2/" ,
packages : "semmle/*" ,
token : "still-not-a-token" ,
} ,
] ;
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
getVersion : ( ) => Promise . resolve ( "2.10.3" ) ,
} ) ;
await t . throwsAsync ( async ( ) => {
return await configUtils . downloadPacks ( codeQL , [ languages _1 . Language . javascript , languages _1 . Language . java , languages _1 . Language . python ] , { } , registries , sampleApiDetails , tmpDir , logger ) ;
2022-09-07 20:32:47 -07:00
} , { instanceOf : Error } , "'registries' input is not supported on CodeQL versions less than 2.10.4." ) ;
} ) ;
} ) ;
( 0 , ava _1 . default ) ( "downloadPacks-with-registries fails with invalid registries block" , async ( t ) => {
// same thing, but this time include a registries block and
// associated env vars
return await util . withTmpDir ( async ( tmpDir ) => {
process . env . GITHUB _TOKEN = "not-a-token" ;
process . env . CODEQL _REGISTRIES _AUTH = "not-a-registries-auth" ;
const logger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
const registries = [
{
// missing url property
packages : [ "codeql/*" , "dsp-testing/*" ] ,
token : "not-a-token" ,
} ,
{
url : "https://containers.GHEHOSTNAME1/v2/" ,
packages : "semmle/*" ,
token : "still-not-a-token" ,
} ,
] ;
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
getVersion : ( ) => Promise . resolve ( "2.10.4" ) ,
} ) ;
await t . throwsAsync ( async ( ) => {
return await configUtils . downloadPacks ( codeQL , [ languages _1 . Language . javascript , languages _1 . Language . java , languages _1 . Language . python ] , { } , registries , sampleApiDetails , tmpDir , logger ) ;
} , { instanceOf : Error } , "Invalid 'registries' input. Must be an array of objects with 'url' and 'packages' properties." ) ;
2022-09-07 15:26:30 -07:00
} ) ;
} ) ;
2020-05-05 17:32:58 +01:00
//# sourceMappingURL=config-utils.test.js.map