2022-08-02 13:27:52 +03:00
"use strict" ;
var _ _createBinding = ( this && this . _ _createBinding ) || ( Object . create ? ( function ( o , m , k , k2 ) {
if ( k2 === undefined ) k2 = k ;
2023-01-18 23:00:33 +03: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 13:27:52 +03: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 ;
} ) ;
var _ _importStar = ( this && this . _ _importStar ) || function ( mod ) {
if ( mod && mod . _ _esModule ) return mod ;
var result = { } ;
if ( mod != null ) for ( var k in mod ) if ( k !== "default" && Object . prototype . hasOwnProperty . call ( mod , k ) ) _ _createBinding ( result , mod , k ) ;
_ _setModuleDefault ( result , mod ) ;
return result ;
} ;
var _ _importDefault = ( this && this . _ _importDefault ) || function ( mod ) {
return ( mod && mod . _ _esModule ) ? mod : { "default" : mod } ;
} ;
Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
2024-09-17 00:05:17 +03:00
exports . sanitizeArtifactName = sanitizeArtifactName ;
2024-09-12 22:55:49 +03:00
exports . uploadCombinedSarifArtifacts = uploadCombinedSarifArtifacts ;
2024-09-17 00:05:17 +03:00
exports . tryUploadAllAvailableDebugArtifacts = tryUploadAllAvailableDebugArtifacts ;
2024-06-25 12:21:42 +03:00
exports . uploadDebugArtifacts = uploadDebugArtifacts ;
2024-10-01 19:59:05 +03:00
exports . getArtifactUploaderClient = getArtifactUploaderClient ;
2022-08-02 13:27:52 +03:00
const fs = _ _importStar ( require ( "fs" ) ) ;
const path = _ _importStar ( require ( "path" ) ) ;
const artifact = _ _importStar ( require ( "@actions/artifact" ) ) ;
2024-10-01 19:59:05 +03:00
const artifactLegacy = _ _importStar ( require ( "@actions/artifact-legacy" ) ) ;
2022-08-02 13:27:52 +03:00
const core = _ _importStar ( require ( "@actions/core" ) ) ;
const adm _zip _1 = _ _importDefault ( require ( "adm-zip" ) ) ;
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-12 01:13:10 +03:00
const environment _1 = require ( "./environment" ) ;
2024-10-01 19:59:05 +03:00
const feature _flags _1 = require ( "./feature-flags" ) ;
2024-09-17 12:08:27 +03:00
const logging _1 = require ( "./logging" ) ;
2022-08-02 13:27:52 +03:00
const util _1 = require ( "./util" ) ;
2024-09-17 00:05:17 +03:00
function sanitizeArtifactName ( name ) {
2022-08-02 13:27:52 +03:00
return name . replace ( /[^a-zA-Z0-9_\\-]+/g , "" ) ;
}
2024-09-12 22:55:49 +03:00
/ * *
* Upload Actions SARIF artifacts for debugging when CODEQL _ACTION _DEBUG _COMBINED _SARIF
* environment variable is set
* /
2024-10-01 19:59:05 +03:00
async function uploadCombinedSarifArtifacts ( logger , gitHubVariant , features ) {
2024-09-12 22:55:49 +03: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" ) {
2024-09-17 12:15:08 +03:00
logger . info ( "Uploading available combined SARIF files as Actions debugging artifact..." ) ;
2024-09-12 22:55:49 +03:00
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-17 12:15:08 +03:00
try {
2024-10-01 19:59:05 +03:00
await uploadDebugArtifacts ( logger , toUpload , baseTempDir , "combined-sarif-artifacts" , gitHubVariant , features ) ;
2024-09-12 22:55:49 +03:00
}
2024-09-17 12:15:08 +03:00
catch ( e ) {
logger . warning ( ` Failed to upload combined SARIF files as Actions debugging artifact. Reason: ${ ( 0 , util _1 . getErrorMessage ) ( e ) } ` ) ;
}
2024-09-12 22:55:49 +03:00
}
}
2024-09-17 00:05:17 +03:00
/ * *
2024-09-17 11:58:00 +03:00
* Try to prepare a SARIF result debug artifact for the given language .
2024-09-17 00:05:17 +03:00
*
2024-09-17 11:58:00 +03:00
* @ return The path to that debug artifact , or undefined if an error occurs .
2024-09-17 00:05:17 +03:00
* /
2024-09-17 11:58:00 +03:00
function tryPrepareSarifDebugArtifact ( config , language , logger ) {
2024-09-16 19:39:39 +03:00
try {
const analyzeActionOutputDir = process . env [ environment _1 . EnvVar . SARIF _RESULTS _OUTPUT _DIR ] ;
2024-09-12 01:13:10 +03:00
if ( analyzeActionOutputDir !== undefined &&
fs . existsSync ( analyzeActionOutputDir ) &&
fs . lstatSync ( analyzeActionOutputDir ) . isDirectory ( ) ) {
2024-09-16 19:39:39 +03:00
const sarifFile = path . resolve ( analyzeActionOutputDir , ` ${ language } .sarif ` ) ;
2024-09-12 01:13:10 +03: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 19:39:39 +03:00
const sarifInDbLocation = path . resolve ( config . dbLocation , ` ${ language } .sarif ` ) ;
2024-09-12 22:58:13 +03:00
fs . copyFileSync ( sarifFile , sarifInDbLocation ) ;
2024-09-17 11:58:00 +03:00
return sarifInDbLocation ;
2024-09-12 01:13:10 +03:00
}
}
2024-09-16 19:39:39 +03:00
}
catch ( e ) {
2024-09-16 23:38:35 +03:00
logger . warning ( ` Failed to find SARIF results path for ${ language } . Reason: ${ ( 0 , util _1 . getErrorMessage ) ( e ) } ` ) ;
2024-09-16 19:39:39 +03:00
}
2024-09-17 11:58:00 +03:00
return undefined ;
2024-09-16 19:39:39 +03:00
}
2024-09-17 00:05:17 +03:00
/ * *
2024-09-17 11:58:00 +03:00
* Try to bundle the database for the given language .
2024-09-17 00:05:17 +03:00
*
2024-09-17 11:58:00 +03:00
* @ return The path to the database bundle , or undefined if an error occurs .
2024-09-17 00:05:17 +03:00
* /
2024-09-16 19:39:39 +03:00
async function tryBundleDatabase ( config , language , logger ) {
try {
2024-09-16 23:29:11 +03:00
if ( ( 0 , analyze _1 . dbIsFinalized ) ( config , language , logger ) ) {
try {
2024-09-17 11:58:00 +03:00
return await createDatabaseBundleCli ( config , language ) ;
2024-09-16 23:29:11 +03:00
}
catch ( e ) {
logger . warning ( ` Failed to bundle database for ${ language } using the CLI. ` +
2024-09-16 23:38:35 +03:00
` Falling back to a partial bundle. Reason: ${ ( 0 , util _1 . getErrorMessage ) ( e ) } ` ) ;
2024-09-16 23:29:11 +03:00
}
2024-09-16 19:39:39 +03:00
}
2024-09-17 11:58:00 +03:00
return await createPartialDatabaseBundle ( config , language ) ;
2024-09-16 19:39:39 +03:00
}
catch ( e ) {
2024-09-16 23:38:35 +03:00
logger . warning ( ` Failed to bundle database for ${ language } . Reason: ${ ( 0 , util _1 . getErrorMessage ) ( e ) } ` ) ;
2024-09-17 11:58:00 +03:00
return undefined ;
2024-09-16 19:39:39 +03:00
}
}
2024-09-17 00:05:17 +03:00
/ * *
* Attempt to upload all available debug artifacts .
*
* Logs and suppresses any errors that occur .
* /
2024-10-01 19:59:05 +03:00
async function tryUploadAllAvailableDebugArtifacts ( config , logger , features ) {
2024-09-17 12:15:08 +03:00
const filesToUpload = [ ] ;
2024-09-16 23:20:22 +03:00
try {
for ( const language of config . languages ) {
2024-09-17 12:08:27 +03: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-12 01:13:10 +03:00
}
2024-09-17 12:15:08 +03:00
}
catch ( e ) {
logger . warning ( ` Failed to prepare debug artifacts. Reason: ${ ( 0 , util _1 . getErrorMessage ) ( e ) } ` ) ;
return ;
}
try {
2024-10-01 19:59:05 +03:00
await ( 0 , logging _1 . withGroup ) ( "Uploading debug artifacts" , async ( ) => uploadDebugArtifacts ( logger , filesToUpload , config . dbLocation , config . debugArtifactName , config . gitHubVersion . type , features ) ) ;
2024-09-16 23:20:22 +03:00
}
catch ( e ) {
2024-09-16 23:38:35 +03:00
logger . warning ( ` Failed to upload debug artifacts. Reason: ${ ( 0 , util _1 . getErrorMessage ) ( e ) } ` ) ;
2024-09-12 01:13:10 +03:00
}
}
2024-10-01 19:59:05 +03:00
async function uploadDebugArtifacts ( logger , toUpload , rootDir , artifactName , ghVariant , features ) {
2022-08-02 13:27:52 +03:00
if ( toUpload . length === 0 ) {
return ;
}
let suffix = "" ;
const matrix = ( 0 , actions _util _1 . getRequiredInput ) ( "matrix" ) ;
if ( matrix ) {
try {
for ( const [ , matrixVal ] of Object . entries ( JSON . parse ( matrix ) ) . sort ( ) )
suffix += ` - ${ matrixVal } ` ;
}
2024-08-05 21:22:26 +03:00
catch {
2022-08-02 13:27:52 +03: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-10-01 19:59:05 +03:00
const artifactUploader = await getArtifactUploaderClient ( logger , ghVariant , features ) ;
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 ,
} ) ;
}
catch ( e ) {
// A failure to upload debug artifacts should not fail the entire action.
core . warning ( ` Failed to upload debug artifacts: ${ e } ` ) ;
}
}
// `@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.
async function getArtifactUploaderClient ( logger , ghVariant , features ) {
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 if ( ! ( await features . getValue ( feature _flags _1 . Feature . ArtifactV4Upgrade ) ) ) {
logger . info ( "Debug artifacts can be consumed with `actions/download-artifact@v3`. To use the `actions/download-artifact@v4`, set the `CODEQL_ACTION_ARTIFACT_V4_UPGRADE` environment variable to true." ) ;
return artifactLegacy . create ( ) ;
}
else {
logger . info ( "Debug artifacts can be consumed with `actions/download-artifact@v4`." ) ;
return new artifact . DefaultArtifactClient ( ) ;
}
2022-08-02 13:27:52 +03: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 14:45:26 +03:00
* all files in the database folder and return the path .
2022-08-02 13:27:52 +03:00
* /
2022-08-11 14:45:26 +03:00
async function createPartialDatabaseBundle ( config , language ) {
2022-08-02 13:27:52 +03: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 } ) ;
}
const zip = new adm _zip _1 . default ( ) ;
zip . addLocalFolder ( databasePath ) ;
zip . writeZip ( databaseBundlePath ) ;
2022-08-11 14:45:26 +03: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 13:27:52 +03:00
}
//# sourceMappingURL=debug-artifacts.js.map