mirror of
https://github.com/github/codeql-action.git
synced 2025-12-17 21:09:40 +08:00
Compare commits
5 Commits
copilot/up
...
mbg/upload
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
483613152e | ||
|
|
dca95cdb78 | ||
|
|
55b6208ff8 | ||
|
|
e84e781d34 | ||
|
|
f4bf13aa48 |
4
lib/analyze-action.js
generated
4
lib/analyze-action.js
generated
@@ -229,10 +229,10 @@ async function run() {
|
||||
core.setOutput("sarif-output", path_1.default.resolve(outputDir));
|
||||
const uploadInput = actionsUtil.getOptionalInput("upload");
|
||||
if (runStats && actionsUtil.getUploadValue(uploadInput) === "always") {
|
||||
uploadResult = await uploadLib.uploadFiles(outputDir, actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getOptionalInput("category"), features, logger, uploadLib.CodeScanningTarget);
|
||||
uploadResult = await uploadLib.uploadFiles(codeql, outputDir, actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getOptionalInput("category"), features, logger, uploadLib.CodeScanningTarget);
|
||||
core.setOutput("sarif-id", uploadResult.sarifID);
|
||||
if (config.augmentationProperties.qualityQueriesInput !== undefined) {
|
||||
const qualityUploadResult = await uploadLib.uploadFiles(outputDir, actionsUtil.getRequiredInput("checkout_path"), actionsUtil.fixCodeQualityCategory(logger, actionsUtil.getOptionalInput("category")), features, logger, uploadLib.CodeQualityTarget);
|
||||
const qualityUploadResult = await uploadLib.uploadFiles(codeql, outputDir, actionsUtil.getRequiredInput("checkout_path"), actionsUtil.fixCodeQualityCategory(logger, actionsUtil.getOptionalInput("category")), features, logger, uploadLib.CodeQualityTarget);
|
||||
core.setOutput("quality-sarif-id", qualityUploadResult.sarifID);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
2
lib/init-action-post-helper.js
generated
2
lib/init-action-post-helper.js
generated
@@ -87,7 +87,7 @@ async function maybeUploadFailedSarif(config, repositoryNwo, features, logger) {
|
||||
await codeql.databaseExportDiagnostics(databasePath, sarifFile, category);
|
||||
}
|
||||
logger.info(`Uploading failed SARIF file ${sarifFile}`);
|
||||
const uploadResult = await uploadLib.uploadFiles(sarifFile, checkoutPath, category, features, logger, uploadLib.CodeScanningTarget);
|
||||
const uploadResult = await uploadLib.uploadFiles(codeql, sarifFile, checkoutPath, category, features, logger, uploadLib.CodeScanningTarget);
|
||||
await uploadLib.waitForProcessing(repositoryNwo, uploadResult.sarifID, logger, { isUnsuccessfulExecution: true });
|
||||
return uploadResult
|
||||
? { ...uploadResult.statusReport, sarifID: uploadResult.sarifID }
|
||||
|
||||
File diff suppressed because one or more lines are too long
2
lib/init-action-post-helper.test.js
generated
2
lib/init-action-post-helper.test.js
generated
@@ -348,7 +348,7 @@ async function testFailedSarifUpload(t, actionsWorkflow, { category, databaseExi
|
||||
else {
|
||||
t.true(diagnosticsExportStub.calledOnceWith(sinon.match.string, category, config), `Actual args were: ${JSON.stringify(diagnosticsExportStub.args)}`);
|
||||
}
|
||||
t.true(uploadFiles.calledOnceWith(sinon.match.string, sinon.match.string, category, sinon.match.any, sinon.match.any), `Actual args were: ${JSON.stringify(uploadFiles.args)}`);
|
||||
t.true(uploadFiles.calledOnceWith(sinon.match.any, sinon.match.string, sinon.match.string, category, sinon.match.any, sinon.match.any), `Actual args were: ${JSON.stringify(uploadFiles.args)}`);
|
||||
t.true(waitForProcessing.calledOnceWith(sinon.match.any, "42", sinon.match.any, {
|
||||
isUnsuccessfulExecution: true,
|
||||
}));
|
||||
|
||||
File diff suppressed because one or more lines are too long
57
lib/upload-lib.js
generated
57
lib/upload-lib.js
generated
@@ -39,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.InvalidSarifUploadError = exports.CodeQualityTarget = exports.CodeScanningTarget = exports.SARIF_UPLOAD_ENDPOINT = void 0;
|
||||
exports.shouldShowCombineSarifFilesDeprecationWarning = shouldShowCombineSarifFilesDeprecationWarning;
|
||||
exports.throwIfCombineSarifFilesDisabled = throwIfCombineSarifFilesDisabled;
|
||||
exports.initCodeQLForUpload = initCodeQLForUpload;
|
||||
exports.populateRunAutomationDetails = populateRunAutomationDetails;
|
||||
exports.findSarifFilesInDir = findSarifFilesInDir;
|
||||
exports.getSarifFilePaths = getSarifFilePaths;
|
||||
@@ -60,8 +61,6 @@ const jsonschema = __importStar(require("jsonschema"));
|
||||
const actionsUtil = __importStar(require("./actions-util"));
|
||||
const api = __importStar(require("./api-client"));
|
||||
const api_client_1 = require("./api-client");
|
||||
const codeql_1 = require("./codeql");
|
||||
const config_utils_1 = require("./config-utils");
|
||||
const diff_informed_analysis_utils_1 = require("./diff-informed-analysis-utils");
|
||||
const environment_1 = require("./environment");
|
||||
const fingerprints = __importStar(require("./fingerprints"));
|
||||
@@ -168,11 +167,28 @@ async function shouldDisableCombineSarifFiles(sarifObjects, githubVersion) {
|
||||
// error if multiple runs with the same category are uploaded.
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Minimally initialises CodeQL if needed to combine SARIF files and CodeQL
|
||||
* wasn't already initialised before.
|
||||
*/
|
||||
async function initCodeQLForUpload(gitHubVersion, features, logger) {
|
||||
logger.info("Initializing CodeQL since the 'init' Action was not called before this step.");
|
||||
const apiDetails = {
|
||||
auth: actionsUtil.getRequiredInput("token"),
|
||||
externalRepoAuth: actionsUtil.getOptionalInput("external-repository-token"),
|
||||
url: (0, util_1.getRequiredEnvParam)("GITHUB_SERVER_URL"),
|
||||
apiURL: (0, util_1.getRequiredEnvParam)("GITHUB_API_URL"),
|
||||
};
|
||||
const codeQLDefaultVersionInfo = await features.getDefaultCliVersion(gitHubVersion.type);
|
||||
const initCodeQLResult = await (0, init_1.initCodeQL)(undefined, // There is no tools input on the upload action
|
||||
apiDetails, actionsUtil.getTemporaryDirectory(), gitHubVersion.type, codeQLDefaultVersionInfo, features, logger);
|
||||
return initCodeQLResult.codeql;
|
||||
}
|
||||
// Takes a list of paths to sarif files and combines them together using the
|
||||
// CLI `github merge-results` command when all SARIF files are produced by
|
||||
// CodeQL. Otherwise, it will fall back to combining the files in the action.
|
||||
// Returns the contents of the combined sarif file.
|
||||
async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, logger) {
|
||||
async function combineSarifFilesUsingCLI(codeQL, sarifFiles, gitHubVersion, logger) {
|
||||
logger.info("Combining SARIF files using the CodeQL CLI");
|
||||
const sarifObjects = sarifFiles.map((sarifFile) => {
|
||||
return JSON.parse(fs.readFileSync(sarifFile, "utf8"));
|
||||
@@ -191,28 +207,6 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo
|
||||
// If not, use the naive method of combining the files.
|
||||
return combineSarifFiles(sarifFiles, logger);
|
||||
}
|
||||
// Initialize CodeQL, either by using the config file from the 'init' step,
|
||||
// or by initializing it here.
|
||||
let codeQL;
|
||||
let tempDir = actionsUtil.getTemporaryDirectory();
|
||||
const config = await (0, config_utils_1.getConfig)(tempDir, logger);
|
||||
if (config !== undefined) {
|
||||
codeQL = await (0, codeql_1.getCodeQL)(config.codeQLCmd);
|
||||
tempDir = config.tempDir;
|
||||
}
|
||||
else {
|
||||
logger.info("Initializing CodeQL since the 'init' Action was not called before this step.");
|
||||
const apiDetails = {
|
||||
auth: actionsUtil.getRequiredInput("token"),
|
||||
externalRepoAuth: actionsUtil.getOptionalInput("external-repository-token"),
|
||||
url: (0, util_1.getRequiredEnvParam)("GITHUB_SERVER_URL"),
|
||||
apiURL: (0, util_1.getRequiredEnvParam)("GITHUB_API_URL"),
|
||||
};
|
||||
const codeQLDefaultVersionInfo = await features.getDefaultCliVersion(gitHubVersion.type);
|
||||
const initCodeQLResult = await (0, init_1.initCodeQL)(undefined, // There is no tools input on the upload action
|
||||
apiDetails, tempDir, gitHubVersion.type, codeQLDefaultVersionInfo, features, logger);
|
||||
codeQL = initCodeQLResult.codeql;
|
||||
}
|
||||
if (!(await codeQL.supportsFeature(tools_features_1.ToolsFeature.SarifMergeRunsFromEqualCategory))) {
|
||||
await throwIfCombineSarifFilesDisabled(sarifObjects, gitHubVersion);
|
||||
logger.warning("The CodeQL CLI does not support merging SARIF files. Merging files in the action.");
|
||||
@@ -222,6 +216,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo
|
||||
}
|
||||
return combineSarifFiles(sarifFiles, logger);
|
||||
}
|
||||
const tempDir = actionsUtil.getTemporaryDirectory();
|
||||
const baseTempDir = path.resolve(tempDir, "combined-sarif");
|
||||
fs.mkdirSync(baseTempDir, { recursive: true });
|
||||
const outputDirectory = fs.mkdtempSync(path.resolve(baseTempDir, "output-"));
|
||||
@@ -456,14 +451,14 @@ exports.CodeQualityTarget = {
|
||||
* Uploads a single SARIF file or a directory of SARIF files depending on what `inputSarifPath` refers
|
||||
* to.
|
||||
*/
|
||||
async function uploadFiles(inputSarifPath, checkoutPath, category, features, logger, uploadTarget) {
|
||||
async function uploadFiles(codeQL, inputSarifPath, checkoutPath, category, features, logger, uploadTarget) {
|
||||
const sarifPaths = getSarifFilePaths(inputSarifPath, uploadTarget.sarifPredicate);
|
||||
return uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget);
|
||||
return uploadSpecifiedFiles(codeQL, sarifPaths, checkoutPath, category, features, logger, uploadTarget);
|
||||
}
|
||||
/**
|
||||
* Uploads the given array of SARIF files.
|
||||
*/
|
||||
async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = exports.CodeScanningTarget) {
|
||||
async function uploadSpecifiedFiles(codeQL, sarifPaths, checkoutPath, category, _features, logger, uploadTarget = exports.CodeScanningTarget) {
|
||||
logger.startGroup(`Uploading ${uploadTarget.name} results`);
|
||||
logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`);
|
||||
const gitHubVersion = await (0, api_client_1.getGitHubVersion)();
|
||||
@@ -474,7 +469,11 @@ async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features
|
||||
const parsedSarif = readSarifFile(sarifPath);
|
||||
validateSarifFileSchema(parsedSarif, sarifPath, logger);
|
||||
}
|
||||
sarif = await combineSarifFilesUsingCLI(sarifPaths, gitHubVersion, features, logger);
|
||||
// CodeQL should always be initialised at this point if we have multiple sarif files.
|
||||
if (codeQL === undefined) {
|
||||
throw new Error(`Unexpectedly, CodeQL has not been initialised for the upload of multiple files.`);
|
||||
}
|
||||
sarif = await combineSarifFilesUsingCLI(codeQL, sarifPaths, gitHubVersion, logger);
|
||||
}
|
||||
else {
|
||||
const sarifPath = sarifPaths[0];
|
||||
|
||||
File diff suppressed because one or more lines are too long
29
lib/upload-sarif-action.js
generated
29
lib/upload-sarif-action.js
generated
@@ -54,6 +54,18 @@ async function sendSuccessStatusReport(startedAt, uploadStats, logger) {
|
||||
await (0, status_report_1.sendStatusReport)(statusReport);
|
||||
}
|
||||
}
|
||||
async function findSecuritySarifFiles(sarifPath) {
|
||||
if (fs.lstatSync(sarifPath).isDirectory()) {
|
||||
return upload_lib.findSarifFilesInDir(sarifPath, upload_lib.CodeScanningTarget.sarifPredicate);
|
||||
}
|
||||
return [sarifPath];
|
||||
}
|
||||
async function findQualitySarifFiles(sarifPath) {
|
||||
if (fs.lstatSync(sarifPath).isDirectory()) {
|
||||
return upload_lib.findSarifFilesInDir(sarifPath, upload_lib.CodeQualityTarget.sarifPredicate);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
async function run() {
|
||||
const startedAt = new Date();
|
||||
const logger = (0, logging_1.getActionsLogger)();
|
||||
@@ -72,16 +84,21 @@ async function run() {
|
||||
const sarifPath = actionsUtil.getRequiredInput("sarif_file");
|
||||
const checkoutPath = actionsUtil.getRequiredInput("checkout_path");
|
||||
const category = actionsUtil.getOptionalInput("category");
|
||||
const uploadResult = await upload_lib.uploadFiles(sarifPath, checkoutPath, category, features, logger, upload_lib.CodeScanningTarget);
|
||||
const securitySarifFiles = await findSecuritySarifFiles(sarifPath);
|
||||
const qualitySarifFiles = await findQualitySarifFiles(sarifPath);
|
||||
// If we have more than one SARIF file for a given service, then we need to combine
|
||||
// them using the CLI. To avoid initialising the CLI twice in one run, we do it here.
|
||||
let codeql;
|
||||
if (securitySarifFiles.length > 1 || qualitySarifFiles.length > 1) {
|
||||
codeql = await upload_lib.initCodeQLForUpload(gitHubVersion, features, logger);
|
||||
}
|
||||
const uploadResult = await upload_lib.uploadSpecifiedFiles(codeql, securitySarifFiles, checkoutPath, category, features, logger, upload_lib.CodeScanningTarget);
|
||||
core.setOutput("sarif-id", uploadResult.sarifID);
|
||||
// If there are `.quality.sarif` files in `sarifPath`, then upload those to the code quality service.
|
||||
// Code quality can currently only be enabled on top of security, so we'd currently always expect to
|
||||
// have a directory for the results here.
|
||||
if (fs.lstatSync(sarifPath).isDirectory()) {
|
||||
const qualitySarifFiles = upload_lib.findSarifFilesInDir(sarifPath, upload_lib.CodeQualityTarget.sarifPredicate);
|
||||
if (qualitySarifFiles.length !== 0) {
|
||||
await upload_lib.uploadSpecifiedFiles(qualitySarifFiles, checkoutPath, actionsUtil.fixCodeQualityCategory(logger, category), features, logger, upload_lib.CodeQualityTarget);
|
||||
}
|
||||
if (qualitySarifFiles.length !== 0) {
|
||||
await upload_lib.uploadSpecifiedFiles(codeql, qualitySarifFiles, checkoutPath, actionsUtil.fixCodeQualityCategory(logger, category), features, logger, upload_lib.CodeQualityTarget);
|
||||
}
|
||||
// We don't upload results in test mode, so don't wait for processing
|
||||
if ((0, util_1.isInTestMode)()) {
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"upload-sarif-action.js","sourceRoot":"","sources":["../src/upload-sarif-action.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"upload-sarif-action.js","sourceRoot":"","sources":["../src/upload-sarif-action.ts"],"names":[],"mappings":"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"}
|
||||
@@ -344,6 +344,7 @@ async function run() {
|
||||
const uploadInput = actionsUtil.getOptionalInput("upload");
|
||||
if (runStats && actionsUtil.getUploadValue(uploadInput) === "always") {
|
||||
uploadResult = await uploadLib.uploadFiles(
|
||||
codeql,
|
||||
outputDir,
|
||||
actionsUtil.getRequiredInput("checkout_path"),
|
||||
actionsUtil.getOptionalInput("category"),
|
||||
@@ -355,6 +356,7 @@ async function run() {
|
||||
|
||||
if (config.augmentationProperties.qualityQueriesInput !== undefined) {
|
||||
const qualityUploadResult = await uploadLib.uploadFiles(
|
||||
codeql,
|
||||
outputDir,
|
||||
actionsUtil.getRequiredInput("checkout_path"),
|
||||
actionsUtil.fixCodeQualityCategory(
|
||||
|
||||
@@ -407,6 +407,7 @@ async function testFailedSarifUpload(
|
||||
}
|
||||
t.true(
|
||||
uploadFiles.calledOnceWith(
|
||||
sinon.match.any,
|
||||
sinon.match.string,
|
||||
sinon.match.string,
|
||||
category,
|
||||
|
||||
@@ -99,6 +99,7 @@ async function maybeUploadFailedSarif(
|
||||
|
||||
logger.info(`Uploading failed SARIF file ${sarifFile}`);
|
||||
const uploadResult = await uploadLib.uploadFiles(
|
||||
codeql,
|
||||
sarifFile,
|
||||
checkoutPath,
|
||||
category,
|
||||
|
||||
@@ -10,8 +10,7 @@ import * as jsonschema from "jsonschema";
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import * as api from "./api-client";
|
||||
import { getGitHubVersion, wrapApiConfigurationError } from "./api-client";
|
||||
import { CodeQL, getCodeQL } from "./codeql";
|
||||
import { getConfig } from "./config-utils";
|
||||
import { CodeQL } from "./codeql";
|
||||
import { readDiffRangesJsonFile } from "./diff-informed-analysis-utils";
|
||||
import { EnvVar } from "./environment";
|
||||
import { FeatureEnablement } from "./feature-flags";
|
||||
@@ -182,14 +181,51 @@ async function shouldDisableCombineSarifFiles(
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimally initialises CodeQL if needed to combine SARIF files and CodeQL
|
||||
* wasn't already initialised before.
|
||||
*/
|
||||
export async function initCodeQLForUpload(
|
||||
gitHubVersion: GitHubVersion,
|
||||
features: FeatureEnablement,
|
||||
logger: Logger,
|
||||
): Promise<CodeQL> {
|
||||
logger.info(
|
||||
"Initializing CodeQL since the 'init' Action was not called before this step.",
|
||||
);
|
||||
|
||||
const apiDetails = {
|
||||
auth: actionsUtil.getRequiredInput("token"),
|
||||
externalRepoAuth: actionsUtil.getOptionalInput("external-repository-token"),
|
||||
url: getRequiredEnvParam("GITHUB_SERVER_URL"),
|
||||
apiURL: getRequiredEnvParam("GITHUB_API_URL"),
|
||||
};
|
||||
|
||||
const codeQLDefaultVersionInfo = await features.getDefaultCliVersion(
|
||||
gitHubVersion.type,
|
||||
);
|
||||
|
||||
const initCodeQLResult = await initCodeQL(
|
||||
undefined, // There is no tools input on the upload action
|
||||
apiDetails,
|
||||
actionsUtil.getTemporaryDirectory(),
|
||||
gitHubVersion.type,
|
||||
codeQLDefaultVersionInfo,
|
||||
features,
|
||||
logger,
|
||||
);
|
||||
|
||||
return initCodeQLResult.codeql;
|
||||
}
|
||||
|
||||
// Takes a list of paths to sarif files and combines them together using the
|
||||
// CLI `github merge-results` command when all SARIF files are produced by
|
||||
// CodeQL. Otherwise, it will fall back to combining the files in the action.
|
||||
// Returns the contents of the combined sarif file.
|
||||
async function combineSarifFilesUsingCLI(
|
||||
codeQL: CodeQL,
|
||||
sarifFiles: string[],
|
||||
gitHubVersion: GitHubVersion,
|
||||
features: FeatureEnablement,
|
||||
logger: Logger,
|
||||
): Promise<SarifFile> {
|
||||
logger.info("Combining SARIF files using the CodeQL CLI");
|
||||
@@ -228,46 +264,6 @@ async function combineSarifFilesUsingCLI(
|
||||
return combineSarifFiles(sarifFiles, logger);
|
||||
}
|
||||
|
||||
// Initialize CodeQL, either by using the config file from the 'init' step,
|
||||
// or by initializing it here.
|
||||
let codeQL: CodeQL;
|
||||
let tempDir: string = actionsUtil.getTemporaryDirectory();
|
||||
|
||||
const config = await getConfig(tempDir, logger);
|
||||
if (config !== undefined) {
|
||||
codeQL = await getCodeQL(config.codeQLCmd);
|
||||
tempDir = config.tempDir;
|
||||
} else {
|
||||
logger.info(
|
||||
"Initializing CodeQL since the 'init' Action was not called before this step.",
|
||||
);
|
||||
|
||||
const apiDetails = {
|
||||
auth: actionsUtil.getRequiredInput("token"),
|
||||
externalRepoAuth: actionsUtil.getOptionalInput(
|
||||
"external-repository-token",
|
||||
),
|
||||
url: getRequiredEnvParam("GITHUB_SERVER_URL"),
|
||||
apiURL: getRequiredEnvParam("GITHUB_API_URL"),
|
||||
};
|
||||
|
||||
const codeQLDefaultVersionInfo = await features.getDefaultCliVersion(
|
||||
gitHubVersion.type,
|
||||
);
|
||||
|
||||
const initCodeQLResult = await initCodeQL(
|
||||
undefined, // There is no tools input on the upload action
|
||||
apiDetails,
|
||||
tempDir,
|
||||
gitHubVersion.type,
|
||||
codeQLDefaultVersionInfo,
|
||||
features,
|
||||
logger,
|
||||
);
|
||||
|
||||
codeQL = initCodeQLResult.codeql;
|
||||
}
|
||||
|
||||
if (
|
||||
!(await codeQL.supportsFeature(
|
||||
ToolsFeature.SarifMergeRunsFromEqualCategory,
|
||||
@@ -294,6 +290,7 @@ async function combineSarifFilesUsingCLI(
|
||||
return combineSarifFiles(sarifFiles, logger);
|
||||
}
|
||||
|
||||
const tempDir = actionsUtil.getTemporaryDirectory();
|
||||
const baseTempDir = path.resolve(tempDir, "combined-sarif");
|
||||
fs.mkdirSync(baseTempDir, { recursive: true });
|
||||
const outputDirectory = fs.mkdtempSync(path.resolve(baseTempDir, "output-"));
|
||||
@@ -647,6 +644,7 @@ export const CodeQualityTarget: UploadTarget = {
|
||||
* to.
|
||||
*/
|
||||
export async function uploadFiles(
|
||||
codeQL: CodeQL,
|
||||
inputSarifPath: string,
|
||||
checkoutPath: string,
|
||||
category: string | undefined,
|
||||
@@ -660,6 +658,7 @@ export async function uploadFiles(
|
||||
);
|
||||
|
||||
return uploadSpecifiedFiles(
|
||||
codeQL,
|
||||
sarifPaths,
|
||||
checkoutPath,
|
||||
category,
|
||||
@@ -673,10 +672,11 @@ export async function uploadFiles(
|
||||
* Uploads the given array of SARIF files.
|
||||
*/
|
||||
export async function uploadSpecifiedFiles(
|
||||
codeQL: CodeQL | undefined,
|
||||
sarifPaths: string[],
|
||||
checkoutPath: string,
|
||||
category: string | undefined,
|
||||
features: FeatureEnablement,
|
||||
_features: FeatureEnablement,
|
||||
logger: Logger,
|
||||
uploadTarget: UploadTarget = CodeScanningTarget,
|
||||
): Promise<UploadResult> {
|
||||
@@ -694,10 +694,17 @@ export async function uploadSpecifiedFiles(
|
||||
validateSarifFileSchema(parsedSarif, sarifPath, logger);
|
||||
}
|
||||
|
||||
// CodeQL should always be initialised at this point if we have multiple sarif files.
|
||||
if (codeQL === undefined) {
|
||||
throw new Error(
|
||||
`Unexpectedly, CodeQL has not been initialised for the upload of multiple files.`,
|
||||
);
|
||||
}
|
||||
|
||||
sarif = await combineSarifFilesUsingCLI(
|
||||
codeQL,
|
||||
sarifPaths,
|
||||
gitHubVersion,
|
||||
features,
|
||||
logger,
|
||||
);
|
||||
} else {
|
||||
|
||||
@@ -5,6 +5,7 @@ import * as core from "@actions/core";
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import { getActionVersion, getTemporaryDirectory } from "./actions-util";
|
||||
import { getGitHubVersion } from "./api-client";
|
||||
import { CodeQL } from "./codeql";
|
||||
import { Features } from "./feature-flags";
|
||||
import { Logger, getActionsLogger } from "./logging";
|
||||
import { getRepositoryNwo } from "./repository";
|
||||
@@ -53,6 +54,28 @@ async function sendSuccessStatusReport(
|
||||
}
|
||||
}
|
||||
|
||||
async function findSecuritySarifFiles(sarifPath: string): Promise<string[]> {
|
||||
if (fs.lstatSync(sarifPath).isDirectory()) {
|
||||
return upload_lib.findSarifFilesInDir(
|
||||
sarifPath,
|
||||
upload_lib.CodeScanningTarget.sarifPredicate,
|
||||
);
|
||||
}
|
||||
|
||||
return [sarifPath];
|
||||
}
|
||||
|
||||
async function findQualitySarifFiles(sarifPath: string): Promise<string[]> {
|
||||
if (fs.lstatSync(sarifPath).isDirectory()) {
|
||||
return upload_lib.findSarifFilesInDir(
|
||||
sarifPath,
|
||||
upload_lib.CodeQualityTarget.sarifPredicate,
|
||||
);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
async function run() {
|
||||
const startedAt = new Date();
|
||||
const logger = getActionsLogger();
|
||||
@@ -89,8 +112,23 @@ async function run() {
|
||||
const checkoutPath = actionsUtil.getRequiredInput("checkout_path");
|
||||
const category = actionsUtil.getOptionalInput("category");
|
||||
|
||||
const uploadResult = await upload_lib.uploadFiles(
|
||||
sarifPath,
|
||||
const securitySarifFiles = await findSecuritySarifFiles(sarifPath);
|
||||
const qualitySarifFiles = await findQualitySarifFiles(sarifPath);
|
||||
|
||||
// If we have more than one SARIF file for a given service, then we need to combine
|
||||
// them using the CLI. To avoid initialising the CLI twice in one run, we do it here.
|
||||
let codeql: CodeQL | undefined;
|
||||
if (securitySarifFiles.length > 1 || qualitySarifFiles.length > 1) {
|
||||
codeql = await upload_lib.initCodeQLForUpload(
|
||||
gitHubVersion,
|
||||
features,
|
||||
logger,
|
||||
);
|
||||
}
|
||||
|
||||
const uploadResult = await upload_lib.uploadSpecifiedFiles(
|
||||
codeql,
|
||||
securitySarifFiles,
|
||||
checkoutPath,
|
||||
category,
|
||||
features,
|
||||
@@ -102,22 +140,16 @@ async function run() {
|
||||
// If there are `.quality.sarif` files in `sarifPath`, then upload those to the code quality service.
|
||||
// Code quality can currently only be enabled on top of security, so we'd currently always expect to
|
||||
// have a directory for the results here.
|
||||
if (fs.lstatSync(sarifPath).isDirectory()) {
|
||||
const qualitySarifFiles = upload_lib.findSarifFilesInDir(
|
||||
sarifPath,
|
||||
upload_lib.CodeQualityTarget.sarifPredicate,
|
||||
if (qualitySarifFiles.length !== 0) {
|
||||
await upload_lib.uploadSpecifiedFiles(
|
||||
codeql,
|
||||
qualitySarifFiles,
|
||||
checkoutPath,
|
||||
actionsUtil.fixCodeQualityCategory(logger, category),
|
||||
features,
|
||||
logger,
|
||||
upload_lib.CodeQualityTarget,
|
||||
);
|
||||
|
||||
if (qualitySarifFiles.length !== 0) {
|
||||
await upload_lib.uploadSpecifiedFiles(
|
||||
qualitySarifFiles,
|
||||
checkoutPath,
|
||||
actionsUtil.fixCodeQualityCategory(logger, category),
|
||||
features,
|
||||
logger,
|
||||
upload_lib.CodeQualityTarget,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// We don't upload results in test mode, so don't wait for processing
|
||||
|
||||
Reference in New Issue
Block a user