2020-05-15 17:22:59 +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 ;
} ;
} ) ( ) ;
2021-01-04 13:12:30 +00:00
var _ _importDefault = ( this && this . _ _importDefault ) || function ( mod ) {
return ( mod && mod . _ _esModule ) ? mod : { "default" : mod } ;
} ;
2020-05-15 17:22:59 +01:00
Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
2021-01-04 13:12:30 +00:00
const fs = _ _importStar ( require ( "fs" ) ) ;
const path = _ _importStar ( require ( "path" ) ) ;
2020-05-15 17:22:59 +01:00
const ava _1 = _ _importDefault ( require ( "ava" ) ) ;
2020-08-11 12:43:27 +01:00
const logging _1 = require ( "./logging" ) ;
2020-06-22 12:12:14 +01:00
const testing _utils _1 = require ( "./testing-utils" ) ;
2020-05-15 17:22:59 +01:00
const uploadLib = _ _importStar ( require ( "./upload-lib" ) ) ;
2021-01-04 13:12:30 +00:00
const util _1 = require ( "./util" ) ;
2021-09-10 13:53:13 -07:00
( 0 , testing _utils _1 . setupTests ) ( ava _1 . default ) ;
2021-05-20 15:20:32 -07:00
ava _1 . default . beforeEach ( ( ) => {
2022-11-14 16:37:48 +00:00
( 0 , util _1 . initializeEnvironment ) ( "1.2.3" ) ;
2021-05-20 15:20:32 -07:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "validateSarifFileSchema - valid" , ( t ) => {
2020-09-14 10:44:43 +01:00
const inputFile = ` ${ _ _dirname } /../src/testdata/valid-sarif.sarif ` ;
2025-05-14 15:11:16 +01:00
t . notThrows ( ( ) => uploadLib . validateSarifFileSchema ( uploadLib . readSarifFile ( inputFile ) , inputFile , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ) ;
2020-05-15 17:22:59 +01:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "validateSarifFileSchema - invalid" , ( t ) => {
2020-09-14 10:44:43 +01:00
const inputFile = ` ${ _ _dirname } /../src/testdata/invalid-sarif.sarif ` ;
2025-05-14 15:11:16 +01:00
t . throws ( ( ) => uploadLib . validateSarifFileSchema ( uploadLib . readSarifFile ( inputFile ) , inputFile , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ) ;
2020-05-15 17:22:59 +01:00
} ) ;
2022-11-23 13:57:07 +00:00
( 0 , ava _1 . default ) ( "validate correct payload used for push, PR merge commit, and PR head" , async ( t ) => {
2020-11-30 18:35:55 +00:00
process . env [ "GITHUB_EVENT_NAME" ] = "push" ;
2024-04-17 10:20:46 +02:00
const pushPayload = uploadLib . buildPayload ( "commit" , "refs/heads/master" , "key" , undefined , "" , 1234 , 1 , "/opt/src" , undefined , [ "CodeQL" , "eslint" ] , "mergeBaseCommit" ) ;
2022-11-23 13:57:07 +00:00
// Not triggered by a pull request
t . falsy ( pushPayload . base _ref ) ;
t . falsy ( pushPayload . base _sha ) ;
2020-11-30 16:33:38 +00:00
process . env [ "GITHUB_EVENT_NAME" ] = "pull_request" ;
2022-02-01 15:23:02 +00:00
process . env [ "GITHUB_SHA" ] = "commit" ;
process . env [ "GITHUB_BASE_REF" ] = "master" ;
2024-12-03 18:39:38 +00:00
process . env [ "GITHUB_EVENT_PATH" ] =
` ${ _ _dirname } /../src/testdata/pull_request.json ` ;
2024-04-17 10:20:46 +02:00
const prMergePayload = uploadLib . buildPayload ( "commit" , "refs/pull/123/merge" , "key" , undefined , "" , 1234 , 1 , "/opt/src" , undefined , [ "CodeQL" , "eslint" ] , "mergeBaseCommit" ) ;
2022-11-23 13:57:07 +00:00
// Uploads for a merge commit use the merge base
t . deepEqual ( prMergePayload . base _ref , "refs/heads/master" ) ;
t . deepEqual ( prMergePayload . base _sha , "mergeBaseCommit" ) ;
2024-04-17 10:20:46 +02:00
const prHeadPayload = uploadLib . buildPayload ( "headCommit" , "refs/pull/123/head" , "key" , undefined , "" , 1234 , 1 , "/opt/src" , undefined , [ "CodeQL" , "eslint" ] , "mergeBaseCommit" ) ;
2022-11-23 13:57:07 +00:00
// Uploads for the head use the PR base
t . deepEqual ( prHeadPayload . base _ref , "refs/heads/master" ) ;
t . deepEqual ( prHeadPayload . base _sha , "f95f852bd8fca8fcc58a9a2d6c842781e32a215e" ) ;
2020-11-30 16:33:38 +00:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "finding SARIF files" , async ( t ) => {
await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2021-01-04 13:12:30 +00:00
// include a couple of sarif files
fs . writeFileSync ( path . join ( tmpDir , "a.sarif" ) , "" ) ;
fs . writeFileSync ( path . join ( tmpDir , "b.sarif" ) , "" ) ;
// other random files shouldn't be returned
fs . writeFileSync ( path . join ( tmpDir , "c.foo" ) , "" ) ;
// we should recursively look in subdirectories
fs . mkdirSync ( path . join ( tmpDir , "dir1" ) ) ;
fs . writeFileSync ( path . join ( tmpDir , "dir1" , "d.sarif" ) , "" ) ;
fs . mkdirSync ( path . join ( tmpDir , "dir1" , "dir2" ) ) ;
fs . writeFileSync ( path . join ( tmpDir , "dir1" , "dir2" , "e.sarif" ) , "" ) ;
// we should ignore symlinks
fs . mkdirSync ( path . join ( tmpDir , "dir3" ) ) ;
fs . symlinkSync ( tmpDir , path . join ( tmpDir , "dir3" , "symlink1" ) , "dir" ) ;
fs . symlinkSync ( path . join ( tmpDir , "a.sarif" ) , path . join ( tmpDir , "dir3" , "symlink2.sarif" ) , "file" ) ;
const sarifFiles = uploadLib . findSarifFilesInDir ( tmpDir ) ;
t . deepEqual ( sarifFiles , [
path . join ( tmpDir , "a.sarif" ) ,
path . join ( tmpDir , "b.sarif" ) ,
path . join ( tmpDir , "dir1" , "d.sarif" ) ,
path . join ( tmpDir , "dir1" , "dir2" , "e.sarif" ) ,
] ) ;
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "populateRunAutomationDetails" , ( t ) => {
2022-01-12 15:26:34 -08:00
let sarif = {
runs : [ { } ] ,
} ;
2021-04-15 16:20:49 +02:00
const analysisKey = ".github/workflows/codeql-analysis.yml:analyze" ;
2022-01-12 15:26:34 -08:00
let expectedSarif = {
runs : [ { automationDetails : { id : "language:javascript/os:linux/" } } ] ,
} ;
2021-04-28 14:32:16 +02:00
// Category has priority over analysis_key/environment
let modifiedSarif = uploadLib . populateRunAutomationDetails ( sarif , "language:javascript/os:linux" , analysisKey , '{"language": "other", "os": "other"}' ) ;
t . deepEqual ( modifiedSarif , expectedSarif ) ;
// It doesn't matter if the category has a slash at the end or not
modifiedSarif = uploadLib . populateRunAutomationDetails ( sarif , "language:javascript/os:linux/" , analysisKey , "" ) ;
t . deepEqual ( modifiedSarif , expectedSarif ) ;
2021-04-20 12:53:16 +02:00
// check that the automation details doesn't get overwritten
2022-01-12 15:26:34 -08:00
sarif = { runs : [ { automationDetails : { id : "my_id" } } ] } ;
expectedSarif = { runs : [ { automationDetails : { id : "my_id" } } ] } ;
2021-04-28 14:32:16 +02:00
modifiedSarif = uploadLib . populateRunAutomationDetails ( sarif , undefined , analysisKey , '{"os": "linux", "language": "javascript"}' ) ;
2021-04-19 09:04:58 +02:00
t . deepEqual ( modifiedSarif , expectedSarif ) ;
2022-01-12 15:26:34 -08:00
// check multiple runs
sarif = { runs : [ { automationDetails : { id : "my_id" } } , { } ] } ;
expectedSarif = {
runs : [
{ automationDetails : { id : "my_id" } } ,
{
automationDetails : {
id : ".github/workflows/codeql-analysis.yml:analyze/language:javascript/os:linux/" ,
} ,
} ,
] ,
} ;
modifiedSarif = uploadLib . populateRunAutomationDetails ( sarif , undefined , analysisKey , '{"os": "linux", "language": "javascript"}' ) ;
t . deepEqual ( modifiedSarif , expectedSarif ) ;
} ) ;
( 0 , ava _1 . default ) ( "validateUniqueCategory when empty" , ( t ) => {
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( ) ) ) ;
2021-04-15 16:20:49 +02:00
} ) ;
2022-01-12 15:26:34 -08:00
( 0 , ava _1 . default ) ( "validateUniqueCategory for automation details id" , ( t ) => {
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "AbC" ) ) ) ;
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "def" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "def" ) ) ) ;
2021-10-29 11:31:30 -07:00
// Our category sanitization is not perfect. Here are some examples
// of where we see false clashes
2022-01-12 15:26:34 -08:00
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc/def" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc@def" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc_def" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc def" ) ) ) ;
2021-10-29 11:31:30 -07:00
// this one is fine
2022-01-12 15:26:34 -08:00
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc_ def" ) ) ) ;
} ) ;
( 0 , ava _1 . default ) ( "validateUniqueCategory for tool name" , ( t ) => {
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( undefined , "abc" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( undefined , "abc" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( undefined , "AbC" ) ) ) ;
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( undefined , "def" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( undefined , "def" ) ) ) ;
// Our category sanitization is not perfect. Here are some examples
// of where we see false clashes
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( undefined , "abc/def" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( undefined , "abc@def" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( undefined , "abc_def" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( undefined , "abc def" ) ) ) ;
// this one is fine
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc_ def" ) ) ) ;
} ) ;
( 0 , ava _1 . default ) ( "validateUniqueCategory for automation details id and tool name" , ( t ) => {
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc" , "abc" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc" , "abc" ) ) ) ;
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc_" , "def" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc_" , "def" ) ) ) ;
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "ghi" , "_jkl" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "ghi" , "_jkl" ) ) ) ;
// Our category sanitization is not perfect. Here are some examples
// of where we see false clashes
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc" , "_" ) ) ) ;
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc" , "def__" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "abc_def" ) ) ) ;
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "mno_" , "pqr" ) ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( createMockSarif ( "mno" , "_pqr" ) ) ) ;
} ) ;
( 0 , ava _1 . default ) ( "validateUniqueCategory for multiple runs" , ( t ) => {
const sarif1 = createMockSarif ( "abc" , "def" ) ;
const sarif2 = createMockSarif ( "ghi" , "jkl" ) ;
2022-01-12 16:32:09 -08:00
// duplicate categories are allowed within the same sarif file
const multiSarif = { runs : [ sarif1 . runs [ 0 ] , sarif1 . runs [ 0 ] , sarif2 . runs [ 0 ] ] } ;
2022-01-12 15:26:34 -08:00
t . notThrows ( ( ) => uploadLib . validateUniqueCategory ( multiSarif ) ) ;
2022-01-12 16:32:09 -08:00
// should throw if there are duplicate categories in separate validations
2022-01-12 15:26:34 -08:00
t . throws ( ( ) => uploadLib . validateUniqueCategory ( sarif1 ) ) ;
t . throws ( ( ) => uploadLib . validateUniqueCategory ( sarif2 ) ) ;
2021-10-29 11:31:30 -07:00
} ) ;
2023-05-25 10:17:52 -07:00
( 0 , ava _1 . default ) ( "accept results with invalid artifactLocation.uri value" , ( t ) => {
const loggedMessages = [ ] ;
const mockLogger = {
info : ( message ) => {
loggedMessages . push ( message ) ;
} ,
} ;
const sarifFile = ` ${ _ _dirname } /../src/testdata/with-invalid-uri.sarif ` ;
2025-05-14 15:11:16 +01:00
uploadLib . validateSarifFileSchema ( uploadLib . readSarifFile ( sarifFile ) , sarifFile , mockLogger ) ;
2024-09-16 13:54:05 -07:00
t . deepEqual ( loggedMessages . length , 3 ) ;
t . deepEqual ( loggedMessages [ 1 ] , "Warning: 'not a valid URI' is not a valid URI in 'instance.runs[0].tool.driver.rules[0].helpUri'." , "Warning: 'not a valid URI' is not a valid URI in 'instance.runs[0].results[0].locations[0].physicalLocation.artifactLocation.uri'." ) ;
2023-05-25 10:17:52 -07:00
} ) ;
2024-05-14 11:00:12 +02:00
( 0 , ava _1 . default ) ( "shouldShowCombineSarifFilesDeprecationWarning when on dotcom" , async ( t ) => {
t . true ( await uploadLib . shouldShowCombineSarifFilesDeprecationWarning ( [ createMockSarif ( "abc" , "def" ) , createMockSarif ( "abc" , "def" ) ] , {
2024-05-02 10:20:11 +02:00
type : util _1 . GitHubVariant . DOTCOM ,
} ) ) ;
} ) ;
( 0 , ava _1 . default ) ( "shouldShowCombineSarifFilesDeprecationWarning when on GHES 3.13" , async ( t ) => {
2024-05-14 11:00:12 +02:00
t . false ( await uploadLib . shouldShowCombineSarifFilesDeprecationWarning ( [ createMockSarif ( "abc" , "def" ) , createMockSarif ( "abc" , "def" ) ] , {
2024-05-02 10:20:11 +02:00
type : util _1 . GitHubVariant . GHES ,
version : "3.13.2" ,
} ) ) ;
} ) ;
( 0 , ava _1 . default ) ( "shouldShowCombineSarifFilesDeprecationWarning when on GHES 3.14" , async ( t ) => {
2024-05-14 11:00:12 +02:00
t . true ( await uploadLib . shouldShowCombineSarifFilesDeprecationWarning ( [ createMockSarif ( "abc" , "def" ) , createMockSarif ( "abc" , "def" ) ] , {
2024-05-02 10:20:11 +02:00
type : util _1 . GitHubVariant . GHES ,
version : "3.14.0" ,
} ) ) ;
} ) ;
( 0 , ava _1 . default ) ( "shouldShowCombineSarifFilesDeprecationWarning with only 1 run" , async ( t ) => {
2024-05-14 11:00:12 +02:00
t . false ( await uploadLib . shouldShowCombineSarifFilesDeprecationWarning ( [ createMockSarif ( "abc" , "def" ) ] , {
2024-05-02 10:20:11 +02:00
type : util _1 . GitHubVariant . DOTCOM ,
} ) ) ;
} ) ;
( 0 , ava _1 . default ) ( "shouldShowCombineSarifFilesDeprecationWarning with distinct categories" , async ( t ) => {
2024-05-14 11:00:12 +02:00
t . false ( await uploadLib . shouldShowCombineSarifFilesDeprecationWarning ( [ createMockSarif ( "abc" , "def" ) , createMockSarif ( "def" , "def" ) ] , {
2024-05-02 10:20:11 +02:00
type : util _1 . GitHubVariant . DOTCOM ,
} ) ) ;
} ) ;
( 0 , ava _1 . default ) ( "shouldShowCombineSarifFilesDeprecationWarning with distinct tools" , async ( t ) => {
2024-05-14 11:00:12 +02:00
t . false ( await uploadLib . shouldShowCombineSarifFilesDeprecationWarning ( [ createMockSarif ( "abc" , "abc" ) , createMockSarif ( "abc" , "def" ) ] , {
2024-05-02 10:20:11 +02:00
type : util _1 . GitHubVariant . DOTCOM ,
} ) ) ;
} ) ;
( 0 , ava _1 . default ) ( "shouldShowCombineSarifFilesDeprecationWarning when environment variable is already set" , async ( t ) => {
process . env [ "CODEQL_MERGE_SARIF_DEPRECATION_WARNING" ] = "true" ;
2024-05-14 11:00:12 +02:00
t . false ( await uploadLib . shouldShowCombineSarifFilesDeprecationWarning ( [ createMockSarif ( "abc" , "def" ) , createMockSarif ( "abc" , "def" ) ] , {
2024-05-02 10:20:11 +02:00
type : util _1 . GitHubVariant . DOTCOM ,
} ) ) ;
} ) ;
2025-03-31 12:17:23 +01:00
( 0 , ava _1 . default ) ( "shouldConsiderConfigurationError correctly detects configuration errors" , ( t ) => {
const error1 = [
"CodeQL analyses from advanced configurations cannot be processed when the default setup is enabled" ,
] ;
t . true ( uploadLib . shouldConsiderConfigurationError ( error1 ) ) ;
const error2 = [
"rejecting delivery as the repository has too many logical alerts" ,
] ;
t . true ( uploadLib . shouldConsiderConfigurationError ( error2 ) ) ;
// We fail cases where we get > 1 error messages back
const error3 = [
"rejecting delivery as the repository has too many alerts" ,
"extra error message" ,
] ;
t . false ( uploadLib . shouldConsiderConfigurationError ( error3 ) ) ;
} ) ;
( 0 , ava _1 . default ) ( "shouldConsiderInvalidRequest returns correct recognises processing errors" , ( t ) => {
const error1 = [
"rejecting SARIF" ,
"an invalid URI was provided as a SARIF location" ,
] ;
t . true ( uploadLib . shouldConsiderInvalidRequest ( error1 ) ) ;
const error2 = [
"locationFromSarifResult: expected artifact location" ,
2025-04-01 15:10:16 +01:00
"an invalid URI was provided as a SARIF location" ,
2025-03-31 12:17:23 +01:00
] ;
t . true ( uploadLib . shouldConsiderInvalidRequest ( error2 ) ) ;
// We expect ALL errors to be of processing errors, for the outcome to be classified as
// an invalid SARIF upload error.
const error3 = [
"could not convert rules: invalid security severity value, is not a number" ,
"an unknown error occurred" ,
] ;
t . false ( uploadLib . shouldConsiderInvalidRequest ( error3 ) ) ;
} ) ;
2022-01-12 15:26:34 -08:00
function createMockSarif ( id , tool ) {
return {
runs : [
{
automationDetails : {
id ,
} ,
tool : {
driver : {
name : tool ,
} ,
} ,
} ,
] ,
} ;
}
2020-05-15 17:22:59 +01:00
//# sourceMappingURL=upload-lib.test.js.map