2020-06-26 17:22:19 +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 ;
2023-01-18 20:00:33 +00:00
var desc = Object . getOwnPropertyDescriptor ( m , k ) ;
if ( ! desc || ( "get" in desc ? ! m . _ _esModule : desc . writable || desc . configurable ) ) {
desc = { enumerable : true , get : function ( ) { return m [ k ] ; } } ;
}
Object . defineProperty ( o , k2 , desc ) ;
2021-07-27 17:59:59 +01:00
} ) : ( 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 ;
} ) ;
2024-12-03 18:39:38 +00:00
var _ _importStar = ( this && this . _ _importStar ) || ( function ( ) {
var ownKeys = function ( o ) {
ownKeys = Object . getOwnPropertyNames || function ( o ) {
var ar = [ ] ;
for ( var k in o ) if ( Object . prototype . hasOwnProperty . call ( o , k ) ) ar [ ar . length ] = k ;
return ar ;
} ;
return ownKeys ( o ) ;
} ;
return function ( mod ) {
if ( mod && mod . _ _esModule ) return mod ;
var result = { } ;
if ( mod != null ) for ( var k = ownKeys ( mod ) , i = 0 ; i < k . length ; i ++ ) if ( k [ i ] !== "default" ) _ _createBinding ( result , mod , k [ i ] ) ;
_ _setModuleDefault ( result , mod ) ;
return result ;
} ;
} ) ( ) ;
2020-06-26 17:22:19 +01:00
Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
2024-06-25 09:21:42 +00:00
exports . setupCodeQL = setupCodeQL ;
exports . getCodeQL = getCodeQL ;
exports . setCodeQL = setCodeQL ;
exports . getCachedCodeQL = getCachedCodeQL ;
exports . getCodeQLForTesting = getCodeQLForTesting ;
exports . getCodeQLForCmd = getCodeQLForCmd ;
exports . getExtraOptions = getExtraOptions ;
exports . getTrapCachingExtractorConfigArgs = getTrapCachingExtractorConfigArgs ;
exports . getTrapCachingExtractorConfigArgsForLang = getTrapCachingExtractorConfigArgsForLang ;
exports . getGeneratedCodeScanningConfigPath = getGeneratedCodeScanningConfigPath ;
2020-06-26 17:22:19 +01:00
const fs = _ _importStar ( require ( "fs" ) ) ;
const path = _ _importStar ( require ( "path" ) ) ;
2023-07-06 11:56:49 +01:00
const core = _ _importStar ( require ( "@actions/core" ) ) ;
2020-11-20 11:35:59 +01:00
const toolrunner = _ _importStar ( require ( "@actions/exec/lib/toolrunner" ) ) ;
2022-06-16 18:10:13 -07:00
const yaml = _ _importStar ( require ( "js-yaml" ) ) ;
2020-09-29 14:43:37 +01:00
const actions _util _1 = require ( "./actions-util" ) ;
2024-02-08 09:20:03 -08:00
const cli _errors _1 = require ( "./cli-errors" ) ;
2024-07-23 14:16:18 +02:00
const doc _url _1 = require ( "./doc-url" ) ;
2023-07-06 12:28:03 +01:00
const environment _1 = require ( "./environment" ) ;
2023-03-09 16:44:45 +00:00
const feature _flags _1 = require ( "./feature-flags" ) ;
2024-12-09 14:44:56 -08:00
const git _utils _1 = require ( "./git-utils" ) ;
2024-11-07 14:49:38 -05:00
const languages _1 = require ( "./languages" ) ;
2025-03-10 13:31:46 -07:00
const overlay _database _utils _1 = require ( "./overlay-database-utils" ) ;
2023-01-10 13:16:22 +00:00
const setupCodeql = _ _importStar ( require ( "./setup-codeql" ) ) ;
2024-01-30 21:53:24 +00:00
const tools _features _1 = require ( "./tools-features" ) ;
2024-04-11 20:31:01 +01:00
const tracer _config _1 = require ( "./tracer-config" ) ;
2020-10-01 11:03:30 +01:00
const util = _ _importStar ( require ( "./util" ) ) ;
2023-04-06 17:04:21 +01:00
const util _1 = require ( "./util" ) ;
2020-06-26 15:33:59 +01:00
/**
2020-07-15 17:36:49 +01:00
* Stores the CodeQL object, and is populated by `setupCodeQL` or `getCodeQL`.
2020-06-26 15:33:59 +01:00
* Can be overridden in tests using `setCodeQL`.
*/
let cachedCodeQL = undefined ;
2021-08-18 10:15:48 +01:00
/**
* The oldest version of CodeQL that the Action will run with. This should be
2022-11-11 18:00:58 +00:00
* at least three minor versions behind the current version and must include the
* CLI versions shipped with each supported version of GHES.
2021-08-18 10:15:48 +01:00
*
2022-11-11 18:00:58 +00:00
* The version flags below can be used to conditionally enable certain features
* on versions newer than this.
2021-08-18 10:15:48 +01:00
*/
2024-12-16 15:01:37 -08:00
const CODEQL _MINIMUM _VERSION = "2.15.5" ;
2023-07-06 11:56:49 +01:00
/**
* This version will shortly become the oldest version of CodeQL that the Action will run with.
*/
2025-05-14 17:13:10 +01:00
const CODEQL _NEXT _MINIMUM _VERSION = "2.16.6" ;
2023-09-14 16:34:07 +01:00
/**
* This is the version of GHES that was most recently deprecated.
*/
2025-05-14 17:13:10 +01:00
const GHES _VERSION _MOST _RECENTLY _DEPRECATED = "3.12" ;
2023-09-14 16:34:07 +01:00
/**
* This is the deprecation date for the version of GHES that was most recently deprecated.
*/
2025-05-14 17:13:10 +01:00
const GHES _MOST _RECENT _DEPRECATION _DATE = "2025-04-03" ;
2024-03-13 14:50:33 +00:00
/** The CLI verbosity level to use for extraction in debug mode. */
const EXTRACTION _DEBUG _MODE _VERBOSITY = "progress++" ;
2023-09-27 16:16:13 +01:00
/*
2024-02-14 05:57:38 -08:00
* Deprecated in favor of ToolsFeature.
*
2021-08-18 09:44:49 +01:00
* Versions of CodeQL that version-flag certain functionality in the Action.
2021-08-18 10:15:48 +01:00
* For convenience, please keep these in descending order. Once a version
* flag is older than the oldest supported version above, it may be removed.
2021-08-18 09:44:49 +01:00
*/
2024-09-02 08:32:47 +02:00
/**
* Versions 2.17.1+ of the CodeQL CLI support the `--cache-cleanup` option.
*/
const CODEQL _VERSION _CACHE _CLEANUP = "2.17.1" ;
2022-03-17 10:07:29 -07:00
/**
* Set up CodeQL CLI access.
*
2023-01-05 16:54:18 +00:00
* @param toolsInput
2022-03-17 10:07:29 -07:00
* @param apiDetails
* @param tempDir
* @param variant
2023-01-10 13:16:22 +00:00
* @param defaultCliVersion
2022-03-17 10:07:29 -07:00
* @param logger
* @param checkVersion Whether to check that CodeQL CLI meets the minimum
* version requirement. Must be set to true outside tests.
2022-10-05 09:16:42 -07:00
* @returns a { CodeQL, toolsVersion } object.
2022-03-17 10:07:29 -07:00
*/
2024-11-12 17:59:47 +00:00
async function setupCodeQL ( toolsInput , apiDetails , tempDir , variant , defaultCliVersion , logger , features , checkVersion ) {
2020-06-26 17:22:19 +01:00
try {
2024-11-12 17:59:47 +00:00
const { codeqlFolder , toolsDownloadStatusReport , toolsSource , toolsVersion , zstdAvailability , } = await setupCodeql . setupCodeQLBundle ( toolsInput , apiDetails , tempDir , variant , features , defaultCliVersion , logger ) ;
2024-08-13 15:56:38 +01:00
logger . debug ( ` Bundle download status report: ${ JSON . stringify ( toolsDownloadStatusReport ) } ` ) ;
2020-09-14 10:44:43 +01:00
let codeqlCmd = path . join ( codeqlFolder , "codeql" , "codeql" ) ;
if ( process . platform === "win32" ) {
2020-06-26 17:22:19 +01:00
codeqlCmd += ".exe" ;
}
2020-09-14 10:44:43 +01:00
else if ( process . platform !== "linux" && process . platform !== "darwin" ) {
2024-02-08 09:20:03 -08:00
throw new util . ConfigurationError ( ` Unsupported platform: ${ process . platform } ` ) ;
2020-06-26 17:22:19 +01:00
}
2021-08-18 10:15:48 +01:00
cachedCodeQL = await getCodeQLForCmd ( codeqlCmd , checkVersion ) ;
2023-01-25 11:09:18 -08:00
return {
codeql : cachedCodeQL ,
2024-08-08 17:46:21 +01:00
toolsDownloadStatusReport ,
2023-01-25 11:09:18 -08:00
toolsSource ,
toolsVersion ,
2024-09-23 20:19:33 +01:00
zstdAvailability ,
2023-01-25 11:09:18 -08:00
} ;
2020-06-26 17:22:19 +01:00
}
catch ( e ) {
2025-02-20 16:18:19 +00:00
const ErrorClass = e instanceof util . ConfigurationError ||
( e instanceof Error && e . message . includes ( "ENOSPC" ) ) // out of disk space
? util . ConfigurationError
: Error ;
throw new ErrorClass ( ` Unable to download and extract CodeQL CLI: ${ ( 0 , util _1 . getErrorMessage ) ( e ) } ${ e instanceof Error && e . stack ? ` \n \n Details: ${ e . stack } ` : "" } ` ) ;
2020-06-26 17:22:19 +01:00
}
}
2020-08-19 15:54:23 +01:00
/**
* Use the CodeQL executable located at the given path.
*/
2021-08-18 10:15:48 +01:00
async function getCodeQL ( cmd ) {
2020-06-26 15:33:59 +01:00
if ( cachedCodeQL === undefined ) {
2021-08-18 10:15:48 +01:00
cachedCodeQL = await getCodeQLForCmd ( cmd , true ) ;
2020-06-26 15:33:59 +01:00
}
return cachedCodeQL ;
2020-06-26 17:22:19 +01:00
}
2020-08-19 15:54:23 +01:00
function resolveFunction ( partialCodeql , methodName , defaultImplementation ) {
2020-09-14 10:44:43 +01:00
if ( typeof partialCodeql [ methodName ] !== "function" ) {
2020-08-19 15:54:23 +01:00
if ( defaultImplementation !== undefined ) {
return defaultImplementation ;
}
2020-06-26 15:33:59 +01:00
const dummyMethod = ( ) => {
2020-09-14 10:44:43 +01:00
throw new Error ( ` CodeQL ${ methodName } method not correctly defined ` ) ;
2020-06-26 15:33:59 +01:00
} ;
return dummyMethod ;
}
return partialCodeql [ methodName ] ;
}
2020-07-15 17:36:49 +01:00
/**
* Set the functionality for CodeQL methods. Only for use in tests.
*
* Accepts a partial object and any undefined methods will be implemented
* to immediately throw an exception indicating which method is missing.
*/
2020-06-26 15:33:59 +01:00
function setCodeQL ( partialCodeql ) {
cachedCodeQL = {
2020-09-14 10:44:43 +01:00
getPath : resolveFunction ( partialCodeql , "getPath" , ( ) => "/tmp/dummy-path" ) ,
2024-01-30 21:53:24 +00:00
getVersion : resolveFunction ( partialCodeql , "getVersion" , async ( ) => ( {
2023-10-04 15:45:42 +01:00
version : "1.0.0" ,
2024-01-30 21:53:24 +00:00
} ) ) ,
2020-09-14 10:44:43 +01:00
printVersion : resolveFunction ( partialCodeql , "printVersion" ) ,
2024-01-30 21:53:24 +00:00
supportsFeature : resolveFunction ( partialCodeql , "supportsFeature" , async ( feature ) => ! ! partialCodeql . getVersion &&
( 0 , tools _features _1 . isSupportedToolsFeature ) ( await partialCodeql . getVersion ( ) , feature ) ) ,
2021-09-15 14:49:20 +01:00
databaseInitCluster : resolveFunction ( partialCodeql , "databaseInitCluster" ) ,
2020-09-14 10:44:43 +01:00
runAutobuild : resolveFunction ( partialCodeql , "runAutobuild" ) ,
extractScannedLanguage : resolveFunction ( partialCodeql , "extractScannedLanguage" ) ,
2024-02-02 19:13:42 +00:00
extractUsingBuildMode : resolveFunction ( partialCodeql , "extractUsingBuildMode" ) ,
2020-09-14 10:44:43 +01:00
finalizeDatabase : resolveFunction ( partialCodeql , "finalizeDatabase" ) ,
2021-05-23 16:27:46 +02:00
resolveLanguages : resolveFunction ( partialCodeql , "resolveLanguages" ) ,
2024-10-15 19:38:49 +01:00
betterResolveLanguages : resolveFunction ( partialCodeql , "betterResolveLanguages" , async ( ) => ( { aliases : { } , extractors : { } } ) ) ,
2020-09-14 10:44:43 +01:00
resolveQueries : resolveFunction ( partialCodeql , "resolveQueries" ) ,
2023-05-18 20:12:12 +01:00
resolveBuildEnvironment : resolveFunction ( partialCodeql , "resolveBuildEnvironment" ) ,
2021-06-03 09:32:44 -07:00
packDownload : resolveFunction ( partialCodeql , "packDownload" ) ,
2021-05-24 17:26:13 +01:00
databaseCleanup : resolveFunction ( partialCodeql , "databaseCleanup" ) ,
2021-06-22 13:05:12 +01:00
databaseBundle : resolveFunction ( partialCodeql , "databaseBundle" ) ,
2021-06-04 14:28:55 +01:00
databaseRunQueries : resolveFunction ( partialCodeql , "databaseRunQueries" ) ,
databaseInterpretResults : resolveFunction ( partialCodeql , "databaseInterpretResults" ) ,
2021-09-28 09:25:35 +01:00
databasePrintBaseline : resolveFunction ( partialCodeql , "databasePrintBaseline" ) ,
2023-03-20 14:09:04 -07:00
databaseExportDiagnostics : resolveFunction ( partialCodeql , "databaseExportDiagnostics" ) ,
2022-11-09 17:32:21 +00:00
diagnosticsExport : resolveFunction ( partialCodeql , "diagnosticsExport" ) ,
2023-05-16 11:18:16 +01:00
resolveExtractor : resolveFunction ( partialCodeql , "resolveExtractor" ) ,
2024-03-15 14:41:21 +01:00
mergeResults : resolveFunction ( partialCodeql , "mergeResults" ) ,
2020-06-26 15:33:59 +01:00
} ;
2020-08-19 15:54:23 +01:00
return cachedCodeQL ;
2020-06-26 15:33:59 +01:00
}
2020-08-19 15:54:23 +01:00
/**
* Get the cached CodeQL object. Should only be used from tests.
*
* TODO: Work out a good way for tests to get this from the test context
* instead of having to have this method.
*/
function getCachedCodeQL ( ) {
if ( cachedCodeQL === undefined ) {
// Should never happen as setCodeQL is called by testing-utils.setupTests
2020-09-14 10:44:43 +01:00
throw new Error ( "cachedCodeQL undefined" ) ;
2020-08-19 15:54:23 +01:00
}
return cachedCodeQL ;
}
2021-11-03 13:19:01 -07:00
/**
* Get a real, newly created CodeQL instance for testing. The instance refers to
* a non-existent placeholder codeql command, so tests that use this function
* should also stub the toolrunner.ToolRunner constructor.
*/
2022-06-27 16:01:48 +00:00
async function getCodeQLForTesting ( cmd = "codeql-for-testing" ) {
return getCodeQLForCmd ( cmd , false ) ;
2021-11-03 13:19:01 -07:00
}
2022-03-17 10:07:29 -07:00
/**
* Return a CodeQL object for CodeQL CLI access.
*
* @param cmd Path to CodeQL CLI
* @param checkVersion Whether to check that CodeQL CLI meets the minimum
* version requirement. Must be set to true outside tests.
* @returns A new CodeQL object
*/
2021-08-18 10:15:48 +01:00
async function getCodeQLForCmd ( cmd , checkVersion ) {
const codeql = {
2020-09-14 10:44:43 +01:00
getPath ( ) {
2020-08-19 15:54:23 +01:00
return cmd ;
2020-06-26 17:22:19 +01:00
} ,
2021-08-12 16:02:19 +01:00
async getVersion ( ) {
2022-03-17 10:07:29 -07:00
let result = util . getCachedCodeQlVersion ( ) ;
if ( result === undefined ) {
2024-10-10 18:54:18 +01:00
const output = await runCli ( cmd , [ "version" , "--format=json" ] , {
noStreamStdout : true ,
} ) ;
2023-10-04 15:49:25 +01:00
try {
result = JSON . parse ( output ) ;
}
2024-08-05 19:22:26 +01:00
catch {
2023-10-04 15:49:25 +01:00
throw Error ( ` Invalid JSON output from \` version --format=json \` : ${ output } ` ) ;
}
2022-03-17 10:07:29 -07:00
util . cacheCodeQlVersion ( result ) ;
}
return result ;
2021-08-12 16:02:19 +01:00
} ,
2020-09-14 10:44:43 +01:00
async printVersion ( ) {
2024-10-01 14:39:04 +01:00
await runCli ( cmd , [ "version" , "--format=json" ] ) ;
2020-06-26 17:22:19 +01:00
} ,
2024-01-30 21:53:24 +00:00
async supportsFeature ( feature ) {
return ( 0 , tools _features _1 . isSupportedToolsFeature ) ( await this . getVersion ( ) , feature ) ;
} ,
2025-03-10 13:31:46 -07:00
async databaseInitCluster ( config , sourceRoot , processName , qlconfigFile , overlayDatabaseMode , logger ) {
2022-03-01 14:33:00 +00:00
const extraArgs = config . languages . map ( ( language ) => ` --language= ${ language } ` ) ;
2024-06-26 19:38:13 +01:00
if ( await ( 0 , tracer _config _1 . shouldEnableIndirectTracing ) ( codeql , config ) ) {
2021-09-15 14:49:20 +01:00
extraArgs . push ( "--begin-tracing" ) ;
2023-07-19 17:30:23 +01:00
extraArgs . push ( ... ( await getTrapCachingExtractorConfigArgs ( config ) ) ) ;
2022-11-14 18:49:17 +00:00
extraArgs . push ( ` --trace-process-name= ${ processName } ` ) ;
2021-09-15 14:49:20 +01:00
}
2024-11-07 14:49:38 -05:00
if ( config . languages . indexOf ( languages _1 . Language . actions ) >= 0 ) {
2025-02-27 15:36:18 -05:00
// We originally added an embedded version of the Actions extractor to the CodeQL Action
// itself in order to deploy the extractor between CodeQL releases. When we did add the
// extractor to the CLI, though, its autobuild script was missing the execute bit.
// 2.20.6 is the first CLI release with the fully-functional extractor in the CLI. For older
// versions, we'll keep using the embedded extractor. We can remove the embedded extractor
// once 2.20.6 is deployed in the runner images.
if ( ! ( await util . codeQlVersionAtLeast ( codeql , "2.20.6" ) ) ) {
extraArgs . push ( "--search-path" ) ;
const extractorPath = path . resolve ( _ _dirname , "../actions-extractor" ) ;
extraArgs . push ( extractorPath ) ;
}
2024-11-07 14:49:38 -05:00
}
2024-01-04 14:39:36 +00:00
const codeScanningConfigFile = await generateCodeScanningConfig ( config , logger ) ;
const externalRepositoryToken = ( 0 , actions _util _1 . getOptionalInput ) ( "external-repository-token" ) ;
extraArgs . push ( ` --codescanning-config= ${ codeScanningConfigFile } ` ) ;
if ( externalRepositoryToken ) {
extraArgs . push ( "--external-repository-token-stdin" ) ;
2022-06-16 18:10:13 -07:00
}
2024-01-30 21:59:51 +00:00
if ( config . buildMode !== undefined &&
( await this . supportsFeature ( tools _features _1 . ToolsFeature . BuildModeOption ) ) ) {
extraArgs . push ( ` --build-mode= ${ config . buildMode } ` ) ;
}
2024-04-09 12:29:14 +01:00
if ( qlconfigFile !== undefined ) {
2023-03-06 10:46:36 +00:00
extraArgs . push ( ` --qlconfig-file= ${ qlconfigFile } ` ) ;
2023-02-07 10:40:49 -08:00
}
2024-06-11 12:31:07 -07:00
const overwriteFlag = ( 0 , tools _features _1 . isSupportedToolsFeature ) ( await this . getVersion ( ) , tools _features _1 . ToolsFeature . ForceOverwrite )
2024-06-11 12:00:21 -07:00
? "--force-overwrite"
: "--overwrite" ;
2025-03-10 13:31:46 -07:00
if ( overlayDatabaseMode === overlay _database _utils _1 . OverlayDatabaseMode . Overlay ) {
2025-03-19 11:38:45 -07:00
const overlayChangesFile = await ( 0 , overlay _database _utils _1 . writeOverlayChangesFile ) ( config , sourceRoot , logger ) ;
extraArgs . push ( ` --overlay-changes= ${ overlayChangesFile } ` ) ;
2025-03-10 13:31:46 -07:00
}
else if ( overlayDatabaseMode === overlay _database _utils _1 . OverlayDatabaseMode . OverlayBase ) {
extraArgs . push ( "--overlay-base" ) ;
}
2024-10-01 14:39:04 +01:00
await runCli ( cmd , [
2024-03-19 13:45:33 +00:00
"database" ,
"init" ,
2025-03-10 13:31:46 -07:00
... ( overlayDatabaseMode === overlay _database _utils _1 . OverlayDatabaseMode . Overlay
? [ ]
: [ overwriteFlag ] ) ,
2024-03-19 13:45:33 +00:00
"--db-cluster" ,
config . dbLocation ,
` --source-root= ${ sourceRoot } ` ,
2025-01-15 17:59:15 +00:00
"--calculate-language-specific-baseline" ,
2024-10-15 19:38:49 +01:00
"--extractor-include-aliases" ,
2025-01-15 17:59:15 +00:00
"--sublanguage-file-coverage" ,
2024-03-19 13:45:33 +00:00
... extraArgs ,
2024-04-16 18:08:46 +01:00
... getExtraOptionsFromEnv ( [ "database" , "init" ] , {
ignoringOptions : [ "--overwrite" ] ,
} ) ,
2024-03-19 13:45:33 +00:00
] , { stdin : externalRepositoryToken } ) ;
2025-03-19 11:38:45 -07:00
if ( overlayDatabaseMode === overlay _database _utils _1 . OverlayDatabaseMode . OverlayBase ) {
await ( 0 , overlay _database _utils _1 . writeBaseDatabaseOidsFile ) ( config , sourceRoot ) ;
}
2021-09-15 14:49:20 +01:00
} ,
2024-05-09 14:25:25 +01:00
async runAutobuild ( config , language ) {
2024-04-11 20:52:55 +01:00
applyAutobuildAzurePipelinesTimeoutFix ( ) ;
2023-05-16 11:18:16 +01:00
const autobuildCmd = path . join ( await this . resolveExtractor ( language ) , "tools" , process . platform === "win32" ? "autobuild.cmd" : "autobuild.sh" ) ;
2024-03-13 17:51:08 +00:00
// Bump the verbosity of the autobuild command if we're in debug mode
2024-04-11 21:05:55 +01:00
if ( config . debugMode ) {
2024-03-13 17:51:08 +00:00
process . env [ environment _1 . EnvVar . CLI _VERBOSITY ] =
process . env [ environment _1 . EnvVar . CLI _VERBOSITY ] || EXTRACTION _DEBUG _MODE _VERBOSITY ;
}
2022-07-25 14:31:52 -07:00
// On macOS, System Integrity Protection (SIP) typically interferes with
// CodeQL build tracing of protected binaries.
// The usual workaround is to prefix `$CODEQL_RUNNER` to build commands:
// `$CODEQL_RUNNER` (not to be confused with the deprecated CodeQL Runner tool)
// points to a simple wrapper binary included with the CLI, and the extra layer of
// process indirection helps the tracer bypass SIP.
// The above SIP workaround is *not* needed here.
// At the `autobuild` step in the Actions workflow, we assume the `init` step
// has successfully run, and will have exported `DYLD_INSERT_LIBRARIES`
// into the environment of subsequent steps, to activate the tracer.
// When `DYLD_INSERT_LIBRARIES` is set in the environment for a step,
// the Actions runtime introduces its own workaround for SIP
// (https://github.com/actions/runner/pull/416).
2024-10-01 14:39:04 +01:00
await runCli ( autobuildCmd ) ;
2020-07-02 14:45:14 +01:00
} ,
2022-09-13 11:19:13 +00:00
async extractScannedLanguage ( config , language ) {
2024-10-01 14:39:04 +01:00
await runCli ( cmd , [
2020-09-14 10:44:43 +01:00
"database" ,
"trace-command" ,
2023-12-01 18:58:40 +00:00
"--index-traceless-dbs" ,
2023-07-19 17:30:23 +01:00
... ( await getTrapCachingExtractorConfigArgsForLang ( config , language ) ) ,
2024-03-13 18:27:21 +00:00
... getExtractionVerbosityArguments ( config . debugMode ) ,
2020-09-14 10:44:43 +01:00
... getExtraOptionsFromEnv ( [ "database" , "trace-command" ] ) ,
2023-12-01 18:58:40 +00:00
util . getCodeQLDatabasePath ( config , language ) ,
2023-07-20 18:31:37 +01:00
] ) ;
2020-06-26 17:22:19 +01:00
} ,
2024-02-02 19:13:42 +00:00
async extractUsingBuildMode ( config , language ) {
2024-04-11 20:52:55 +01:00
if ( config . buildMode === util _1 . BuildMode . Autobuild ) {
applyAutobuildAzurePipelinesTimeoutFix ( ) ;
}
2024-04-11 20:48:05 +01:00
try {
2024-10-01 14:39:04 +01:00
await runCli ( cmd , [
2024-04-11 20:48:05 +01:00
"database" ,
"trace-command" ,
"--use-build-mode" ,
2024-06-11 16:07:54 +01:00
"--working-dir" ,
process . cwd ( ) ,
2024-04-11 20:48:05 +01:00
... ( await getTrapCachingExtractorConfigArgsForLang ( config , language ) ) ,
... getExtractionVerbosityArguments ( config . debugMode ) ,
... getExtraOptionsFromEnv ( [ "database" , "trace-command" ] ) ,
util . getCodeQLDatabasePath ( config , language ) ,
] ) ;
}
catch ( e ) {
if ( config . buildMode === util _1 . BuildMode . Autobuild ) {
const prefix = "We were unable to automatically build your code. " +
"Please change the build mode for this language to manual and specify build steps " +
2024-07-23 14:16:18 +02:00
` for your project. See ${ doc _url _1 . DocUrl . AUTOMATIC _BUILD _FAILED } for more information. ` ;
2024-09-23 22:34:32 +01:00
throw new util . ConfigurationError ( ` ${ prefix } ${ ( 0 , util _1 . getErrorMessage ) ( e ) } ` ) ;
2024-04-11 20:48:05 +01:00
}
else {
throw e ;
}
}
2024-02-02 19:13:42 +00:00
} ,
2024-03-13 18:22:37 +00:00
async finalizeDatabase ( databasePath , threadsFlag , memoryFlag , enableDebugLogging ) {
2021-08-12 16:02:19 +01:00
const args = [
2020-09-14 10:44:43 +01:00
"database" ,
"finalize" ,
2021-06-09 15:00:42 +01:00
"--finalize-dataset" ,
2020-11-03 08:25:40 -08:00
threadsFlag ,
2022-11-11 18:05:24 +00:00
memoryFlag ,
2024-03-13 18:27:21 +00:00
... getExtractionVerbosityArguments ( enableDebugLogging ) ,
2020-09-14 10:44:43 +01:00
... getExtraOptionsFromEnv ( [ "database" , "finalize" ] ) ,
databasePath ,
2021-08-12 16:02:19 +01:00
] ;
2024-10-01 14:39:04 +01:00
await runCli ( cmd , args ) ;
2020-06-26 17:22:19 +01:00
} ,
2021-05-23 16:27:46 +02:00
async resolveLanguages ( ) {
2022-01-21 13:44:52 +00:00
const codeqlArgs = [
"resolve" ,
"languages" ,
"--format=json" ,
... getExtraOptionsFromEnv ( [ "resolve" , "languages" ] ) ,
] ;
2024-10-01 14:39:04 +01:00
const output = await runCli ( cmd , codeqlArgs ) ;
2021-05-24 11:00:02 +02:00
try {
return JSON . parse ( output ) ;
}
catch ( e ) {
throw new Error ( ` Unexpected output from codeql resolve languages: ${ e } ` ) ;
}
2021-05-23 16:27:46 +02:00
} ,
2022-08-02 17:52:22 +01:00
async betterResolveLanguages ( ) {
const codeqlArgs = [
"resolve" ,
"languages" ,
"--format=betterjson" ,
"--extractor-options-verbosity=4" ,
2024-10-15 19:38:49 +01:00
"--extractor-include-aliases" ,
2022-08-02 17:52:22 +01:00
... getExtraOptionsFromEnv ( [ "resolve" , "languages" ] ) ,
] ;
2024-10-01 14:39:04 +01:00
const output = await runCli ( cmd , codeqlArgs ) ;
2022-08-02 17:52:22 +01:00
try {
return JSON . parse ( output ) ;
}
catch ( e ) {
throw new Error ( ` Unexpected output from codeql resolve languages with --format=betterjson: ${ e } ` ) ;
}
} ,
2020-09-14 10:44:43 +01:00
async resolveQueries ( queries , extraSearchPath ) {
2020-06-26 15:33:59 +01:00
const codeqlArgs = [
2020-09-14 10:44:43 +01:00
"resolve" ,
"queries" ,
2020-06-26 17:22:19 +01:00
... queries ,
2020-09-14 10:44:43 +01:00
"--format=bylanguage" ,
... getExtraOptionsFromEnv ( [ "resolve" , "queries" ] ) ,
2020-06-26 15:33:59 +01:00
] ;
if ( extraSearchPath !== undefined ) {
2021-05-20 19:03:50 +00:00
codeqlArgs . push ( "--additional-packs" , extraSearchPath ) ;
2020-06-26 15:33:59 +01:00
}
2024-10-01 14:39:04 +01:00
const output = await runCli ( cmd , codeqlArgs ) ;
2021-05-24 11:00:02 +02:00
try {
return JSON . parse ( output ) ;
}
catch ( e ) {
throw new Error ( ` Unexpected output from codeql resolve queries: ${ e } ` ) ;
}
2020-06-26 17:22:19 +01:00
} ,
2023-06-02 19:36:07 +01:00
async resolveBuildEnvironment ( workingDir , language ) {
2023-05-18 20:12:12 +01:00
const codeqlArgs = [
"resolve" ,
"build-environment" ,
` --language= ${ language } ` ,
2024-10-15 19:38:49 +01:00
"--extractor-include-aliases" ,
2023-05-18 20:12:12 +01:00
... getExtraOptionsFromEnv ( [ "resolve" , "build-environment" ] ) ,
] ;
2023-06-02 19:36:07 +01:00
if ( workingDir !== undefined ) {
codeqlArgs . push ( "--working-dir" , workingDir ) ;
}
2024-10-01 14:39:04 +01:00
const output = await runCli ( cmd , codeqlArgs ) ;
2023-05-18 20:12:12 +01:00
try {
return JSON . parse ( output ) ;
}
catch ( e ) {
2023-06-06 12:17:21 +01:00
throw new Error ( ` Unexpected output from codeql resolve build-environment: ${ e } in \n ${ output } ` ) ;
2023-05-18 20:12:12 +01:00
}
} ,
2024-02-14 17:21:01 +00:00
async databaseRunQueries ( databasePath , flags ) {
2021-06-09 13:17:25 -07:00
const codeqlArgs = [
2020-09-14 10:44:43 +01:00
"database" ,
2021-06-04 14:28:55 +01:00
"run-queries" ,
2023-02-14 11:53:52 -08:00
... flags ,
2020-07-02 14:45:14 +01:00
databasePath ,
2025-01-15 17:59:15 +00:00
"--intra-layer-parallelism" ,
2023-11-20 14:35:28 -08:00
"--min-disk-free=1024" , // Try to leave at least 1GB free
2021-05-05 18:09:10 +01:00
"-v" ,
2024-04-16 18:08:46 +01:00
... getExtraOptionsFromEnv ( [ "database" , "run-queries" ] , {
ignoringOptions : [ "--expect-discarded-cache" ] ,
} ) ,
2021-04-01 12:38:13 +01:00
] ;
2024-10-01 14:39:04 +01:00
await runCli ( cmd , codeqlArgs ) ;
2021-06-04 14:28:55 +01:00
} ,
2024-10-29 07:01:44 -07:00
async databaseInterpretResults ( databasePath , querySuitePaths , sarifFile , addSnippetsFlag , threadsFlag , verbosityFlag , sarifRunPropertyFlag , automationDetailsId , config , features ) {
2023-03-24 20:14:00 +00:00
const shouldExportDiagnostics = await features . getValue ( feature _flags _1 . Feature . ExportDiagnosticsEnabled , this ) ;
2021-06-09 13:17:25 -07:00
const codeqlArgs = [
2021-06-04 14:28:55 +01:00
"database" ,
"interpret-results" ,
threadsFlag ,
"--format=sarif-latest" ,
2022-06-28 22:51:46 +01:00
verbosityFlag ,
2024-08-05 17:48:55 +01:00
` --output= ${ sarifFile } ` ,
2021-06-04 14:28:55 +01:00
addSnippetsFlag ,
2022-11-11 18:05:24 +00:00
"--print-diagnostics-summary" ,
"--print-metrics-summary" ,
2023-11-27 12:49:28 +00:00
"--sarif-add-baseline-file-info" ,
2024-04-09 12:29:14 +01:00
` --sarif-codescanning-config= ${ getGeneratedCodeScanningConfigPath ( config ) } ` ,
2024-03-11 18:32:52 +00:00
"--sarif-group-rules-by-pack" ,
2025-01-15 17:59:15 +00:00
"--sarif-include-query-help=always" ,
"--sublanguage-file-coverage" ,
2024-09-05 14:52:43 +02:00
... ( await getJobRunUuidSarifOptions ( this ) ) ,
2021-06-04 14:28:55 +01:00
... getExtraOptionsFromEnv ( [ "database" , "interpret-results" ] ) ,
] ;
2024-10-29 07:01:44 -07:00
if ( sarifRunPropertyFlag !== undefined ) {
codeqlArgs . push ( sarifRunPropertyFlag ) ;
}
2022-11-11 18:05:24 +00:00
if ( automationDetailsId !== undefined ) {
2021-06-09 13:17:25 -07:00
codeqlArgs . push ( "--sarif-category" , automationDetailsId ) ;
2021-05-03 19:41:53 +02:00
}
2023-03-24 20:14:00 +00:00
if ( shouldExportDiagnostics ) {
2023-03-20 14:09:04 -07:00
codeqlArgs . push ( "--sarif-include-diagnostics" ) ;
}
2024-04-09 12:29:14 +01:00
else {
2023-03-29 18:52:51 +01:00
codeqlArgs . push ( "--no-sarif-include-diagnostics" ) ;
}
2025-01-15 17:59:15 +00:00
if ( ! ( 0 , tools _features _1 . isSupportedToolsFeature ) ( await this . getVersion ( ) , tools _features _1 . ToolsFeature . AnalysisSummaryV2IsDefault ) ) {
2023-07-05 18:56:55 +01:00
codeqlArgs . push ( "--new-analysis-summary" ) ;
}
2022-03-01 14:33:00 +00:00
codeqlArgs . push ( databasePath ) ;
2022-06-29 12:50:24 -07:00
if ( querySuitePaths ) {
2022-06-16 18:10:13 -07:00
codeqlArgs . push ( ... querySuitePaths ) ;
}
2023-07-28 12:04:12 +01:00
// Capture the stdout, which contains the analysis summary. Don't stream it to the Actions
// logs to avoid printing it twice.
2024-10-01 14:39:04 +01:00
return await runCli ( cmd , codeqlArgs , {
2023-07-28 12:04:12 +01:00
noStreamStdout : true ,
} ) ;
2020-09-14 10:44:43 +01:00
} ,
2021-09-28 09:25:35 +01:00
async databasePrintBaseline ( databasePath ) {
const codeqlArgs = [
"database" ,
"print-baseline" ,
... getExtraOptionsFromEnv ( [ "database" , "print-baseline" ] ) ,
databasePath ,
] ;
2024-10-01 14:39:04 +01:00
return await runCli ( cmd , codeqlArgs ) ;
2021-09-28 09:25:35 +01:00
} ,
2021-06-04 10:18:24 -07:00
/**
* Download specified packs into the package cache. If the specified
* package and version already exists (e.g., from a previous analysis run),
* then it is not downloaded again (unless the extra option `--force` is
* specified).
*
* If no version is specified, then the latest version is
* downloaded. The check to determine what the latest version is is done
* each time this package is requested.
2022-08-29 12:57:46 -07:00
*
* Optionally, a `qlconfigFile` is included. If used, then this file
* is used to determine which registry each pack is downloaded from.
2021-06-04 10:18:24 -07:00
*/
2022-08-29 12:57:46 -07:00
async packDownload ( packs , qlconfigFile ) {
const qlconfigArg = qlconfigFile
? [ ` --qlconfig-file= ${ qlconfigFile } ` ]
: [ ] ;
2021-06-09 13:17:25 -07:00
const codeqlArgs = [
2021-06-03 09:32:44 -07:00
"pack" ,
"download" ,
2022-08-29 12:57:46 -07:00
... qlconfigArg ,
2021-06-04 13:44:24 -07:00
"--format=json" ,
2022-04-29 10:54:01 -07:00
"--resolve-query-specs" ,
2021-06-03 09:32:44 -07:00
... getExtraOptionsFromEnv ( [ "pack" , "download" ] ) ,
2022-04-26 19:47:59 -07:00
... packs ,
2021-06-03 09:32:44 -07:00
] ;
2024-10-01 14:39:04 +01:00
const output = await runCli ( cmd , codeqlArgs ) ;
2021-06-03 09:32:44 -07:00
try {
2021-06-07 16:05:32 -07:00
const parsedOutput = JSON . parse ( output ) ;
if ( Array . isArray ( parsedOutput . packs ) &&
2021-06-08 10:24:08 -07:00
// TODO PackDownloadOutput will not include the version if it is not specified
// in the input. The version is always the latest version available.
// It should be added to the output, but this requires a CLI change
parsedOutput . packs . every ( ( p ) => p . name /* && p.version */ ) ) {
2021-06-07 16:05:32 -07:00
return parsedOutput ;
}
else {
throw new Error ( "Unexpected output from pack download" ) ;
}
2021-06-03 09:32:44 -07:00
}
catch ( e ) {
2021-06-07 16:05:32 -07:00
throw new Error ( ` Attempted to download specified packs but got an error: \n ${ output } \n ${ e } ` ) ;
2021-06-03 09:32:44 -07:00
}
2020-09-14 10:44:43 +01:00
} ,
2021-05-24 17:26:13 +01:00
async databaseCleanup ( databasePath , cleanupLevel ) {
2024-09-02 08:32:47 +02:00
const cacheCleanupFlag = ( await util . codeQlVersionAtLeast ( this , CODEQL _VERSION _CACHE _CLEANUP ) )
? "--cache-cleanup"
: "--mode" ;
2021-06-09 13:17:25 -07:00
const codeqlArgs = [
2021-05-24 17:26:13 +01:00
"database" ,
"cleanup" ,
databasePath ,
2024-09-02 08:32:47 +02:00
` ${ cacheCleanupFlag } = ${ cleanupLevel } ` ,
2022-01-21 13:44:52 +00:00
... getExtraOptionsFromEnv ( [ "database" , "cleanup" ] ) ,
2021-05-24 17:26:13 +01:00
] ;
2024-10-01 14:39:04 +01:00
await runCli ( cmd , codeqlArgs ) ;
2021-05-24 17:26:13 +01:00
} ,
2022-01-07 13:11:51 +00:00
async databaseBundle ( databasePath , outputFilePath , databaseName ) {
2021-06-22 13:05:12 +01:00
const args = [
"database" ,
"bundle" ,
databasePath ,
` --output= ${ outputFilePath } ` ,
2022-01-07 13:11:51 +00:00
` --name= ${ databaseName } ` ,
2022-01-21 13:44:52 +00:00
... getExtraOptionsFromEnv ( [ "database" , "bundle" ] ) ,
2021-06-22 13:05:12 +01:00
] ;
await new toolrunner . ToolRunner ( cmd , args ) . exec ( ) ;
} ,
2024-08-05 17:48:55 +01:00
async databaseExportDiagnostics ( databasePath , sarifFile , automationDetailsId ) {
2023-03-20 14:09:04 -07:00
const args = [
"database" ,
"export-diagnostics" ,
` ${ databasePath } ` ,
2023-11-20 14:35:28 -08:00
"--db-cluster" , // Database is always a cluster for CodeQL versions that support diagnostics.
2023-03-20 14:09:04 -07:00
"--format=sarif-latest" ,
2024-08-05 17:48:55 +01:00
` --output= ${ sarifFile } ` ,
2023-11-20 14:35:28 -08:00
"--sarif-include-diagnostics" , // ExportDiagnosticsEnabled is always true if this command is run.
2023-03-20 14:09:04 -07:00
"-vvv" ,
... getExtraOptionsFromEnv ( [ "diagnostics" , "export" ] ) ,
] ;
if ( automationDetailsId !== undefined ) {
args . push ( "--sarif-category" , automationDetailsId ) ;
}
await new toolrunner . ToolRunner ( cmd , args ) . exec ( ) ;
} ,
2023-07-05 16:26:20 +01:00
async diagnosticsExport ( sarifFile , automationDetailsId , config ) {
2022-11-09 17:32:21 +00:00
const args = [
"diagnostics" ,
"export" ,
"--format=sarif-latest" ,
` --output= ${ sarifFile } ` ,
2024-04-09 12:29:14 +01:00
` --sarif-codescanning-config= ${ getGeneratedCodeScanningConfigPath ( config ) } ` ,
2022-11-09 17:32:21 +00:00
... getExtraOptionsFromEnv ( [ "diagnostics" , "export" ] ) ,
] ;
if ( automationDetailsId !== undefined ) {
args . push ( "--sarif-category" , automationDetailsId ) ;
}
await new toolrunner . ToolRunner ( cmd , args ) . exec ( ) ;
} ,
2023-05-16 11:18:16 +01:00
async resolveExtractor ( language ) {
// Request it using `format=json` so we don't need to strip the trailing new line generated by
// the CLI.
let extractorPath = "" ;
await new toolrunner . ToolRunner ( cmd , [
"resolve" ,
"extractor" ,
"--format=json" ,
` --language= ${ language } ` ,
2024-10-15 19:38:49 +01:00
"--extractor-include-aliases" ,
2023-05-16 11:18:16 +01:00
... getExtraOptionsFromEnv ( [ "resolve" , "extractor" ] ) ,
] , {
silent : true ,
listeners : {
stdout : ( data ) => {
extractorPath += data . toString ( ) ;
} ,
stderr : ( data ) => {
process . stderr . write ( data ) ;
} ,
} ,
} ) . exec ( ) ;
return JSON . parse ( extractorPath ) ;
} ,
2024-03-25 10:01:54 +01:00
async mergeResults ( sarifFiles , outputFile , { mergeRunsFromEqualCategory = false , } ) {
2024-03-15 14:41:21 +01:00
const args = [
"github" ,
"merge-results" ,
"--output" ,
outputFile ,
... getExtraOptionsFromEnv ( [ "github" , "merge-results" ] ) ,
] ;
for ( const sarifFile of sarifFiles ) {
args . push ( "--sarif" , sarifFile ) ;
}
if ( mergeRunsFromEqualCategory ) {
args . push ( "--sarif-merge-runs-from-equal-category" ) ;
}
2024-10-01 14:39:04 +01:00
await runCli ( cmd , args ) ;
2024-03-15 14:41:21 +01:00
} ,
2020-06-26 17:22:19 +01:00
} ;
2022-11-11 18:09:53 +00:00
// To ensure that status reports include the CodeQL CLI version wherever
// possible, we want to call getVersion(), which populates the version value
2022-03-17 10:07:29 -07:00
// used by status reporting, at the earliest opportunity. But invoking
// getVersion() directly here breaks tests that only pretend to create a
// CodeQL object. So instead we rely on the assumption that all non-test
// callers would set checkVersion to true, and util.codeQlVersionAbove()
// would call getVersion(), so the CLI version would be cached as soon as the
// CodeQL object is created.
2021-08-18 10:15:48 +01:00
if ( checkVersion &&
2024-04-25 15:20:13 -07:00
! ( await util . codeQlVersionAtLeast ( codeql , CODEQL _MINIMUM _VERSION ) ) ) {
2024-02-08 09:20:03 -08:00
throw new util . ConfigurationError ( ` Expected a CodeQL CLI with version at least ${ CODEQL _MINIMUM _VERSION } but got version ${ ( await codeql . getVersion ( ) ) . version } ` ) ;
2021-08-18 10:15:48 +01:00
}
2023-07-06 11:56:49 +01:00
else if ( checkVersion &&
2023-07-06 12:28:03 +01:00
process . env [ environment _1 . EnvVar . SUPPRESS _DEPRECATED _SOON _WARNING ] !== "true" &&
2024-04-25 15:20:13 -07:00
! ( await util . codeQlVersionAtLeast ( codeql , CODEQL _NEXT _MINIMUM _VERSION ) ) ) {
2023-10-04 11:28:28 +01:00
const result = await codeql . getVersion ( ) ;
core . warning ( ` CodeQL CLI version ${ result . version } was discontinued on ` +
2023-09-14 16:34:07 +01:00
` ${ GHES _MOST _RECENT _DEPRECATION _DATE } alongside GitHub Enterprise Server ` +
` ${ GHES _VERSION _MOST _RECENTLY _DEPRECATED } and will not be supported by the next minor ` +
` release of the CodeQL Action. Please update to CodeQL CLI version ` +
` ${ CODEQL _NEXT _MINIMUM _VERSION } or later. For instance, if you have specified a custom ` +
"version of the CLI using the 'tools' input to the 'init' Action, you can remove this " +
"input to use the default version.\n\n" +
2023-07-06 11:56:49 +01:00
"Alternatively, if you want to continue using CodeQL CLI version " +
2024-04-03 15:50:23 +01:00
` ${ result . version } , you can replace 'github/codeql-action/*@v ${ ( 0 , actions _util _1 . getActionVersion ) ( ) . split ( "." ) [ 0 ] } ' by 'github/codeql-action/*@v ${ ( 0 , actions _util _1 . getActionVersion ) ( ) } ' in your code scanning workflow to ` +
2023-09-14 16:34:07 +01:00
"continue using this version of the CodeQL Action." ) ;
2023-07-06 12:28:03 +01:00
core . exportVariable ( environment _1 . EnvVar . SUPPRESS _DEPRECATED _SOON _WARNING , "true" ) ;
2023-07-06 11:56:49 +01:00
}
2021-08-18 10:15:48 +01:00
return codeql ;
2020-06-26 17:22:19 +01:00
}
2020-08-10 09:25:14 +02:00
/**
* Gets the options for `path` of `options` as an array of extra option strings.
2024-04-16 18:08:46 +01:00
*
* @param ignoringOptions Options that should be ignored, for example because they have already
* been passed and it is an error to pass them more than once.
2020-08-10 09:25:14 +02:00
*/
2024-04-16 18:08:46 +01:00
function getExtraOptionsFromEnv ( paths , { ignoringOptions } = { } ) {
2020-09-14 10:44:43 +01:00
const options = util . getExtraOptionsEnvParam ( ) ;
2024-04-16 18:08:46 +01:00
return getExtraOptions ( options , paths , [ ] ) . filter ( ( option ) => ! ignoringOptions ? . includes ( option ) ) ;
2020-11-19 23:03:45 +01:00
}
/**
* Gets `options` as an array of extra option strings.
*
* - throws an exception mentioning `pathInfo` if this conversion is impossible.
*/
function asExtraOptions ( options , pathInfo ) {
if ( options === undefined ) {
return [ ] ;
}
if ( ! Array . isArray ( options ) ) {
const msg = ` The extra options for ' ${ pathInfo . join ( "." ) } ' (' ${ JSON . stringify ( options ) } ') are not in an array. ` ;
throw new Error ( msg ) ;
}
return options . map ( ( o ) => {
const t = typeof o ;
if ( t !== "string" && t !== "number" && t !== "boolean" ) {
const msg = ` The extra option for ' ${ pathInfo . join ( "." ) } ' (' ${ JSON . stringify ( o ) } ') is not a primitive value. ` ;
throw new Error ( msg ) ;
}
return ` ${ o } ` ;
} ) ;
2020-08-10 09:25:14 +02:00
}
/**
* Gets the options for `path` of `options` as an array of extra option strings.
*
* - the special terminal step name '*' in `options` matches all path steps
* - throws an exception if this conversion is impossible.
2020-09-23 20:25:45 +08:00
*
* Exported for testing.
2020-08-10 09:25:14 +02:00
*/
2020-11-19 23:03:45 +01:00
function getExtraOptions ( options , paths , pathInfo ) {
2023-01-18 20:00:33 +00:00
const all = asExtraOptions ( options ? . [ "*" ] , pathInfo . concat ( "*" ) ) ;
2020-11-19 23:03:45 +01:00
const specific = paths . length === 0
2020-09-14 10:44:43 +01:00
? asExtraOptions ( options , pathInfo )
2023-01-18 20:00:33 +00:00
: getExtraOptions ( options ? . [ paths [ 0 ] ] , paths ? . slice ( 1 ) , pathInfo . concat ( paths [ 0 ] ) ) ;
2020-08-10 09:25:14 +02:00
return all . concat ( specific ) ;
}
2024-10-01 14:39:04 +01:00
async function runCli ( cmd , args = [ ] , opts = { } ) {
try {
return await ( 0 , actions _util _1 . runTool ) ( cmd , args , opts ) ;
}
catch ( e ) {
if ( e instanceof actions _util _1 . CommandInvocationError ) {
throw ( 0 , cli _errors _1 . wrapCliConfigurationError ) ( new cli _errors _1 . CliError ( e ) ) ;
}
throw e ;
2023-07-20 18:31:37 +01:00
}
2021-06-09 13:17:25 -07:00
}
2022-06-19 16:44:24 -07:00
/**
2024-01-04 14:39:36 +00:00
* Generates a code scanning configuration that is to be used for a scan.
2022-06-19 16:44:24 -07:00
*
* @param codeql The CodeQL object to use.
* @param config The configuration to use.
* @returns the path to the generated user configuration file.
*/
2024-01-04 14:39:36 +00:00
async function generateCodeScanningConfig ( config , logger ) {
2023-07-19 17:37:43 +01:00
const codeScanningConfigFile = getGeneratedCodeScanningConfigPath ( config ) ;
2022-06-19 16:44:24 -07:00
// make a copy so we can modify it
2024-07-31 17:56:06 -07:00
const augmentedConfig = ( 0 , util _1 . cloneObject ) ( config . originalUserInput ) ;
2022-06-19 16:44:24 -07:00
// Inject the queries from the input
if ( config . augmentationProperties . queriesInput ) {
if ( config . augmentationProperties . queriesInputCombines ) {
augmentedConfig . queries = ( augmentedConfig . queries || [ ] ) . concat ( config . augmentationProperties . queriesInput ) ;
}
else {
augmentedConfig . queries = config . augmentationProperties . queriesInput ;
}
}
2023-01-18 20:00:33 +00:00
if ( augmentedConfig . queries ? . length === 0 ) {
2022-06-19 16:44:24 -07:00
delete augmentedConfig . queries ;
}
// Inject the packs from the input
if ( config . augmentationProperties . packsInput ) {
if ( config . augmentationProperties . packsInputCombines ) {
// At this point, we already know that this is a single-language analysis
if ( Array . isArray ( augmentedConfig . packs ) ) {
augmentedConfig . packs = ( augmentedConfig . packs || [ ] ) . concat ( config . augmentationProperties . packsInput ) ;
}
else if ( ! augmentedConfig . packs ) {
augmentedConfig . packs = config . augmentationProperties . packsInput ;
}
else {
// At this point, we know there is only one language.
// If there were more than one language, an error would already have been thrown.
const language = Object . keys ( augmentedConfig . packs ) [ 0 ] ;
augmentedConfig . packs [ language ] = augmentedConfig . packs [ language ] . concat ( config . augmentationProperties . packsInput ) ;
}
}
else {
augmentedConfig . packs = config . augmentationProperties . packsInput ;
}
}
if ( Array . isArray ( augmentedConfig . packs ) && ! augmentedConfig . packs . length ) {
delete augmentedConfig . packs ;
}
2025-03-28 12:30:40 -07:00
augmentedConfig [ "query-filters" ] = [
... ( config . augmentationProperties . defaultQueryFilters || [ ] ) ,
... ( augmentedConfig [ "query-filters" ] || [ ] ) ,
] ;
if ( augmentedConfig [ "query-filters" ] ? . length === 0 ) {
delete augmentedConfig [ "query-filters" ] ;
}
2023-02-09 11:19:27 -08:00
logger . info ( ` Writing augmented user configuration file to ${ codeScanningConfigFile } ` ) ;
2023-01-17 20:59:36 -08:00
logger . startGroup ( "Augmented user configuration file contents" ) ;
logger . info ( yaml . dump ( augmentedConfig ) ) ;
logger . endGroup ( ) ;
2023-02-09 11:19:27 -08:00
fs . writeFileSync ( codeScanningConfigFile , yaml . dump ( augmentedConfig ) ) ;
return codeScanningConfigFile ;
2022-06-19 16:44:24 -07:00
}
2023-07-19 17:30:23 +01:00
// This constant sets the size of each TRAP cache in megabytes.
const TRAP _CACHE _SIZE _MB = 1024 ;
async function getTrapCachingExtractorConfigArgs ( config ) {
const result = [ ] ;
for ( const language of config . languages )
result . push ( await getTrapCachingExtractorConfigArgsForLang ( config , language ) ) ;
return result . flat ( ) ;
}
async function getTrapCachingExtractorConfigArgsForLang ( config , language ) {
const cacheDir = config . trapCaches [ language ] ;
if ( cacheDir === undefined )
return [ ] ;
2024-12-09 14:44:56 -08:00
const write = await ( 0 , git _utils _1 . isAnalyzingDefaultBranch ) ( ) ;
2023-07-19 17:30:23 +01:00
return [
` -O= ${ language } .trap.cache.dir= ${ cacheDir } ` ,
` -O= ${ language } .trap.cache.bound= ${ TRAP _CACHE _SIZE _MB } ` ,
` -O= ${ language } .trap.cache.write= ${ write } ` ,
] ;
}
2023-07-19 17:37:43 +01:00
/**
* Get the path to the code scanning configuration generated by the CLI.
*
* This will not exist if the configuration is being parsed in the Action.
*/
function getGeneratedCodeScanningConfigPath ( config ) {
return path . resolve ( config . tempDir , "user-config.yaml" ) ;
}
2024-03-13 18:27:21 +00:00
function getExtractionVerbosityArguments ( enableDebugLogging ) {
return enableDebugLogging
? [ ` --verbosity= ${ EXTRACTION _DEBUG _MODE _VERBOSITY } ` ]
: [ ] ;
}
2024-04-11 20:52:55 +01:00
/**
* Updates the `JAVA_TOOL_OPTIONS` environment variable to resolve an issue with Azure Pipelines
* timing out connections after 4 minutes and Maven not properly handling closed connections.
*
* Without the fix, long build processes will timeout when pulling down Java packages
* https://developercommunity.visualstudio.com/content/problem/292284/maven-hosted-agent-connection-timeout.html
*/
function applyAutobuildAzurePipelinesTimeoutFix ( ) {
const javaToolOptions = process . env [ "JAVA_TOOL_OPTIONS" ] || "" ;
process . env [ "JAVA_TOOL_OPTIONS" ] = [
... javaToolOptions . split ( /\s+/ ) ,
"-Dhttp.keepAlive=false" ,
"-Dmaven.wagon.http.pool=false" ,
] . join ( " " ) ;
}
2024-09-05 14:52:43 +02:00
async function getJobRunUuidSarifOptions ( codeql ) {
const jobRunUuid = process . env [ environment _1 . EnvVar . JOB _RUN _UUID ] ;
return jobRunUuid &&
( await codeql . supportsFeature ( tools _features _1 . ToolsFeature . DatabaseInterpretResultsSupportsSarifRunProperty ) )
? [ ` --sarif-run-property=jobRunUuid= ${ jobRunUuid } ` ]
: [ ] ;
}
2020-06-26 17:22:19 +01:00
//# sourceMappingURL=codeql.js.map