2022-08-02 12:27:52 +02:00
"use strict" ;
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 ) ;
2022-08-02 12:27:52 +02: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 ;
} ;
} ) ( ) ;
2022-08-02 12:27:52 +02:00
var _ _importDefault = ( this && this . _ _importDefault ) || function ( mod ) {
return ( mod && mod . _ _esModule ) ? mod : { "default" : mod } ;
} ;
Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
2024-09-16 23:05:17 +02:00
exports . sanitizeArtifactName = sanitizeArtifactName ;
2024-09-12 12:55:49 -07:00
exports . uploadCombinedSarifArtifacts = uploadCombinedSarifArtifacts ;
2024-09-16 23:05:17 +02:00
exports . tryUploadAllAvailableDebugArtifacts = tryUploadAllAvailableDebugArtifacts ;
2024-06-25 09:21:42 +00:00
exports . uploadDebugArtifacts = uploadDebugArtifacts ;
2024-10-01 09:59:05 -07:00
exports . getArtifactUploaderClient = getArtifactUploaderClient ;
2022-08-02 12:27:52 +02:00
const fs = _ _importStar ( require ( "fs" ) ) ;
const path = _ _importStar ( require ( "path" ) ) ;
const artifact = _ _importStar ( require ( "@actions/artifact" ) ) ;
2024-10-01 09:59:05 -07:00
const artifactLegacy = _ _importStar ( require ( "@actions/artifact-legacy" ) ) ;
2022-08-02 12:27:52 +02:00
const core = _ _importStar ( require ( "@actions/core" ) ) ;
2025-04-04 14:40:53 +01:00
const archiver _1 = _ _importDefault ( require ( "archiver" ) ) ;
2022-08-02 12:27:52 +02:00
const del _1 = _ _importDefault ( require ( "del" ) ) ;
const actions _util _1 = require ( "./actions-util" ) ;
const analyze _1 = require ( "./analyze" ) ;
const codeql _1 = require ( "./codeql" ) ;
2024-09-11 15:13:10 -07:00
const environment _1 = require ( "./environment" ) ;
2024-09-17 11:08:27 +02:00
const logging _1 = require ( "./logging" ) ;
2025-01-26 13:34:30 -08:00
const tools _features _1 = require ( "./tools-features" ) ;
2022-08-02 12:27:52 +02:00
const util _1 = require ( "./util" ) ;
2024-09-16 23:05:17 +02:00
function sanitizeArtifactName ( name ) {
2022-08-02 12:27:52 +02:00
return name . replace ( /[^a-zA-Z0-9_\\-]+/g , "" ) ;
}
2024-09-12 12:55:49 -07:00
/**
* Upload Actions SARIF artifacts for debugging when CODEQL_ACTION_DEBUG_COMBINED_SARIF
* environment variable is set
*/
2025-01-26 13:34:30 -08:00
async function uploadCombinedSarifArtifacts ( logger , gitHubVariant , codeQlVersion ) {
2024-09-12 12:55:49 -07:00
const tempDir = ( 0 , actions _util _1 . getTemporaryDirectory ) ( ) ;
// Upload Actions SARIF artifacts for debugging when environment variable is set
if ( process . env [ "CODEQL_ACTION_DEBUG_COMBINED_SARIF" ] === "true" ) {
2025-02-12 16:27:40 +00:00
await ( 0 , logging _1 . withGroup ) ( "Uploading combined SARIF debug artifact" , async ( ) => {
logger . info ( "Uploading available combined SARIF files as Actions debugging artifact..." ) ;
const baseTempDir = path . resolve ( tempDir , "combined-sarif" ) ;
const toUpload = [ ] ;
if ( fs . existsSync ( baseTempDir ) ) {
const outputDirs = fs . readdirSync ( baseTempDir ) ;
for ( const outputDir of outputDirs ) {
const sarifFiles = fs
. readdirSync ( path . resolve ( baseTempDir , outputDir ) )
. filter ( ( f ) => f . endsWith ( ".sarif" ) ) ;
for ( const sarifFile of sarifFiles ) {
toUpload . push ( path . resolve ( baseTempDir , outputDir , sarifFile ) ) ;
}
2024-09-12 12:55:49 -07:00
}
}
2025-02-12 16:27:40 +00:00
try {
await uploadDebugArtifacts ( logger , toUpload , baseTempDir , "combined-sarif-artifacts" , gitHubVariant , codeQlVersion ) ;
}
catch ( e ) {
logger . warning ( ` Failed to upload combined SARIF files as Actions debugging artifact. Reason: ${ ( 0 , util _1 . getErrorMessage ) ( e ) } ` ) ;
}
} ) ;
2024-09-12 12:55:49 -07:00
}
}
2024-09-16 23:05:17 +02:00
/**
2024-09-17 10:58:00 +02:00
* Try to prepare a SARIF result debug artifact for the given language.
2024-09-16 23:05:17 +02:00
*
2024-09-17 10:58:00 +02:00
* @return The path to that debug artifact, or undefined if an error occurs.
2024-09-16 23:05:17 +02:00
*/
2024-09-17 10:58:00 +02:00
function tryPrepareSarifDebugArtifact ( config , language , logger ) {
2024-09-16 18:39:39 +02:00
try {
const analyzeActionOutputDir = process . env [ environment _1 . EnvVar . SARIF _RESULTS _OUTPUT _DIR ] ;
2024-09-11 15:13:10 -07:00
if ( analyzeActionOutputDir !== undefined &&
fs . existsSync ( analyzeActionOutputDir ) &&
fs . lstatSync ( analyzeActionOutputDir ) . isDirectory ( ) ) {
2024-09-16 18:39:39 +02:00
const sarifFile = path . resolve ( analyzeActionOutputDir , ` ${ language } .sarif ` ) ;
2024-09-11 15:13:10 -07:00
// Move SARIF to DB location so that they can be uploaded with the same root directory as the other artifacts.
if ( fs . existsSync ( sarifFile ) ) {
2024-09-16 18:39:39 +02:00
const sarifInDbLocation = path . resolve ( config . dbLocation , ` ${ language } .sarif ` ) ;
2024-09-12 12:58:13 -07:00
fs . copyFileSync ( sarifFile , sarifInDbLocation ) ;
2024-09-17 10:58:00 +02:00
return sarifInDbLocation ;
2024-09-11 15:13:10 -07:00
}
}
2024-09-16 18:39:39 +02:00
}
catch ( e ) {
2024-09-16 22:38:35 +02:00
logger . warning ( ` Failed to find SARIF results path for ${ language } . Reason: ${ ( 0 , util _1 . getErrorMessage ) ( e ) } ` ) ;
2024-09-16 18:39:39 +02:00
}
2024-09-17 10:58:00 +02:00
return undefined ;
2024-09-16 18:39:39 +02:00
}
2024-09-16 23:05:17 +02:00
/**
2024-09-17 10:58:00 +02:00
* Try to bundle the database for the given language.
2024-09-16 23:05:17 +02:00
*
2024-09-17 10:58:00 +02:00
* @return The path to the database bundle, or undefined if an error occurs.
2024-09-16 23:05:17 +02:00
*/
2024-09-16 18:39:39 +02:00
async function tryBundleDatabase ( config , language , logger ) {
try {
2024-09-16 22:29:11 +02:00
if ( ( 0 , analyze _1 . dbIsFinalized ) ( config , language , logger ) ) {
try {
2024-09-17 10:58:00 +02:00
return await createDatabaseBundleCli ( config , language ) ;
2024-09-16 22:29:11 +02:00
}
catch ( e ) {
logger . warning ( ` Failed to bundle database for ${ language } using the CLI. ` +
2024-09-16 22:38:35 +02:00
` Falling back to a partial bundle. Reason: ${ ( 0 , util _1 . getErrorMessage ) ( e ) } ` ) ;
2024-09-16 22:29:11 +02:00
}
2024-09-16 18:39:39 +02:00
}
2024-09-17 10:58:00 +02:00
return await createPartialDatabaseBundle ( config , language ) ;
2024-09-16 18:39:39 +02:00
}
catch ( e ) {
2024-09-16 22:38:35 +02:00
logger . warning ( ` Failed to bundle database for ${ language } . Reason: ${ ( 0 , util _1 . getErrorMessage ) ( e ) } ` ) ;
2024-09-17 10:58:00 +02:00
return undefined ;
2024-09-16 18:39:39 +02:00
}
}
2024-09-16 23:05:17 +02:00
/**
* Attempt to upload all available debug artifacts.
*
* Logs and suppresses any errors that occur.
*/
2025-01-26 13:34:30 -08:00
async function tryUploadAllAvailableDebugArtifacts ( config , logger , codeQlVersion ) {
2024-09-17 11:15:08 +02:00
const filesToUpload = [ ] ;
2024-09-16 22:20:22 +02:00
try {
for ( const language of config . languages ) {
2024-09-17 11:08:27 +02:00
await ( 0 , logging _1 . withGroup ) ( ` Uploading debug artifacts for ${ language } ` , async ( ) => {
logger . info ( "Preparing SARIF result debug artifact..." ) ;
const sarifResultDebugArtifact = tryPrepareSarifDebugArtifact ( config , language , logger ) ;
if ( sarifResultDebugArtifact ) {
filesToUpload . push ( sarifResultDebugArtifact ) ;
logger . info ( "SARIF result debug artifact ready for upload." ) ;
}
logger . info ( "Preparing database logs debug artifact..." ) ;
const databaseDirectory = ( 0 , util _1 . getCodeQLDatabasePath ) ( config , language ) ;
const logsDirectory = path . resolve ( databaseDirectory , "log" ) ;
if ( ( 0 , util _1 . doesDirectoryExist ) ( logsDirectory ) ) {
filesToUpload . push ( ... ( 0 , util _1 . listFolder ) ( logsDirectory ) ) ;
logger . info ( "Database logs debug artifact ready for upload." ) ;
}
// Multilanguage tracing: there are additional logs in the root of the cluster
logger . info ( "Preparing database cluster logs debug artifact..." ) ;
const multiLanguageTracingLogsDirectory = path . resolve ( config . dbLocation , "log" ) ;
if ( ( 0 , util _1 . doesDirectoryExist ) ( multiLanguageTracingLogsDirectory ) ) {
filesToUpload . push ( ... ( 0 , util _1 . listFolder ) ( multiLanguageTracingLogsDirectory ) ) ;
logger . info ( "Database cluster logs debug artifact ready for upload." ) ;
}
// Add database bundle
logger . info ( "Preparing database bundle debug artifact..." ) ;
const databaseBundle = await tryBundleDatabase ( config , language , logger ) ;
if ( databaseBundle ) {
filesToUpload . push ( databaseBundle ) ;
logger . info ( "Database bundle debug artifact ready for upload." ) ;
}
} ) ;
2024-09-11 15:13:10 -07:00
}
2024-09-17 11:15:08 +02:00
}
catch ( e ) {
logger . warning ( ` Failed to prepare debug artifacts. Reason: ${ ( 0 , util _1 . getErrorMessage ) ( e ) } ` ) ;
return ;
}
try {
2025-01-26 13:34:30 -08:00
await ( 0 , logging _1 . withGroup ) ( "Uploading debug artifacts" , async ( ) => uploadDebugArtifacts ( logger , filesToUpload , config . dbLocation , config . debugArtifactName , config . gitHubVersion . type , codeQlVersion ) ) ;
2024-09-16 22:20:22 +02:00
}
catch ( e ) {
2024-09-16 22:38:35 +02:00
logger . warning ( ` Failed to upload debug artifacts. Reason: ${ ( 0 , util _1 . getErrorMessage ) ( e ) } ` ) ;
2024-09-11 15:13:10 -07:00
}
}
2025-01-26 13:34:30 -08:00
async function uploadDebugArtifacts ( logger , toUpload , rootDir , artifactName , ghVariant , codeQlVersion ) {
2022-08-02 12:27:52 +02:00
if ( toUpload . length === 0 ) {
2025-01-25 15:31:35 -08:00
return "no-artifacts-to-upload" ;
}
2025-01-26 13:34:30 -08:00
const uploadSupported = ( 0 , tools _features _1 . isSafeArtifactUpload ) ( codeQlVersion ) ;
2025-01-25 15:31:35 -08:00
if ( ! uploadSupported ) {
2025-01-26 13:34:30 -08:00
core . info ( ` Skipping debug artifact upload because the current CLI does not support safe upload. Please upgrade to CLI v ${ tools _features _1 . SafeArtifactUploadVersion } or later. ` ) ;
2025-01-25 15:31:35 -08:00
return "upload-not-supported" ;
2022-08-02 12:27:52 +02:00
}
let suffix = "" ;
2025-01-25 15:31:35 -08:00
const matrix = ( 0 , actions _util _1 . getOptionalInput ) ( "matrix" ) ;
2022-08-02 12:27:52 +02:00
if ( matrix ) {
try {
for ( const [ , matrixVal ] of Object . entries ( JSON . parse ( matrix ) ) . sort ( ) )
suffix += ` - ${ matrixVal } ` ;
}
2024-08-05 19:22:26 +01:00
catch {
2022-08-02 12:27:52 +02:00
core . info ( "Could not parse user-specified `matrix` input into JSON. The debug artifact will not be named with the user's `matrix` input." ) ;
}
}
2024-12-04 12:05:11 -08:00
const artifactUploader = await getArtifactUploaderClient ( logger , ghVariant ) ;
2024-10-01 09:59:05 -07:00
try {
await artifactUploader . uploadArtifact ( sanitizeArtifactName ( ` ${ artifactName } ${ suffix } ` ) , toUpload . map ( ( file ) => path . normalize ( file ) ) , path . normalize ( rootDir ) , {
// ensure we don't keep the debug artifacts around for too long since they can be large.
retentionDays : 7 ,
} ) ;
2025-01-25 15:31:35 -08:00
return "upload-successful" ;
2024-10-01 09:59:05 -07:00
}
catch ( e ) {
// A failure to upload debug artifacts should not fail the entire action.
core . warning ( ` Failed to upload debug artifacts: ${ e } ` ) ;
2025-01-25 15:31:35 -08:00
return "upload-failed" ;
2024-10-01 09:59:05 -07:00
}
}
// `@actions/artifact@v2` is not yet supported on GHES so the legacy version of the client will be used on GHES
// until it is supported. We also use the legacy version of the client if the feature flag is disabled.
// The feature flag is named `ArtifactV4Upgrade` to reduce customer confusion; customers are primarily affected by
// `actions/download-artifact`, whose upgrade to v4 must be accompanied by the `@actions/artifact@v2` upgrade.
2024-12-04 12:05:11 -08:00
async function getArtifactUploaderClient ( logger , ghVariant ) {
2024-10-01 09:59:05 -07:00
if ( ghVariant === util _1 . GitHubVariant . GHES ) {
logger . info ( "Debug artifacts can be consumed with `actions/download-artifact@v3` because the `v4` version is not yet compatible on GHES." ) ;
return artifactLegacy . create ( ) ;
}
else {
logger . info ( "Debug artifacts can be consumed with `actions/download-artifact@v4`." ) ;
return new artifact . DefaultArtifactClient ( ) ;
}
2022-08-02 12:27:52 +02:00
}
/**
* If a database has not been finalized, we cannot run the `codeql database bundle`
* command in the CLI because it will return an error. Instead we directly zip
2022-08-11 13:45:26 +02:00
* all files in the database folder and return the path.
2022-08-02 12:27:52 +02:00
*/
2022-08-11 13:45:26 +02:00
async function createPartialDatabaseBundle ( config , language ) {
2022-08-02 12:27:52 +02:00
const databasePath = ( 0 , util _1 . getCodeQLDatabasePath ) ( config , language ) ;
const databaseBundlePath = path . resolve ( config . dbLocation , ` ${ config . debugDatabaseName } - ${ language } -partial.zip ` ) ;
core . info ( ` ${ config . debugDatabaseName } - ${ language } is not finalized. Uploading partial database bundle at ${ databaseBundlePath } ... ` ) ;
// See `bundleDb` for explanation behind deleting existing db bundle.
if ( fs . existsSync ( databaseBundlePath ) ) {
await ( 0 , del _1 . default ) ( databaseBundlePath , { force : true } ) ;
}
2025-04-04 14:40:53 +01:00
const output = fs . createWriteStream ( databaseBundlePath ) ;
const zip = ( 0 , archiver _1 . default ) ( "zip" ) ;
zip . on ( "error" , ( err ) => {
throw err ;
} ) ;
zip . on ( "warning" , ( err ) => {
2025-04-04 13:42:00 -07:00
// Ignore ENOENT warnings. There's nothing anyone can do about it.
if ( err . code !== "ENOENT" ) {
throw err ;
}
2025-04-04 14:40:53 +01:00
} ) ;
zip . pipe ( output ) ;
zip . directory ( databasePath , false ) ;
await zip . finalize ( ) ;
2022-08-11 13:45:26 +02:00
return databaseBundlePath ;
}
/**
* Runs `codeql database bundle` command and returns the path.
*/
async function createDatabaseBundleCli ( config , language ) {
const databaseBundlePath = await ( 0 , util _1 . bundleDb ) ( config , language , await ( 0 , codeql _1 . getCodeQL ) ( config . codeQLCmd ) , ` ${ config . debugDatabaseName } - ${ language } ` ) ;
return databaseBundlePath ;
2022-08-02 12:27:52 +02:00
}
//# sourceMappingURL=debug-artifacts.js.map