Change category uniqueness test
Turboscan only allows a single combination of tool name and automation details id for testing category uniqueness. Previously, the check in the action was not entirely correct since it only looked at the _category_ and not the combination of the category and the tool name. It's even more precise now since it is looking at the actual, computed value of the automation details id, rather than an inputted value of the category. This change also includes a refactoring where the action is now avoiding multiple parsing/stringifying of the sarif files. Instead, sarif is parsed once at the start of the process and stringified once, after sarif processing is completely finished.
This commit is contained in:
parent
cbabe47a0b
commit
8454e21c9c
18 changed files with 416 additions and 162 deletions
64
lib/upload-lib.js
generated
64
lib/upload-lib.js
generated
|
|
@ -54,25 +54,24 @@ function combineSarifFiles(sarifFiles) {
|
|||
}
|
||||
combinedSarif.runs.push(...sarifObject.runs);
|
||||
}
|
||||
return JSON.stringify(combinedSarif);
|
||||
return combinedSarif;
|
||||
}
|
||||
exports.combineSarifFiles = combineSarifFiles;
|
||||
// Populates the run.automationDetails.id field using the analysis_key and environment
|
||||
// and return an updated sarif file contents.
|
||||
function populateRunAutomationDetails(sarifContents, category, analysis_key, environment) {
|
||||
if (analysis_key === undefined) {
|
||||
return sarifContents;
|
||||
}
|
||||
function populateRunAutomationDetails(sarif, category, analysis_key, environment) {
|
||||
const automationID = getAutomationID(category, analysis_key, environment);
|
||||
const sarif = JSON.parse(sarifContents);
|
||||
for (const run of sarif.runs || []) {
|
||||
if (run.automationDetails === undefined) {
|
||||
run.automationDetails = {
|
||||
id: automationID,
|
||||
};
|
||||
if (automationID !== undefined) {
|
||||
for (const run of sarif.runs || []) {
|
||||
if (run.automationDetails === undefined) {
|
||||
run.automationDetails = {
|
||||
id: automationID,
|
||||
};
|
||||
}
|
||||
}
|
||||
return sarif;
|
||||
}
|
||||
return JSON.stringify(sarif);
|
||||
return sarif;
|
||||
}
|
||||
exports.populateRunAutomationDetails = populateRunAutomationDetails;
|
||||
function getAutomationID(category, analysis_key, environment) {
|
||||
|
|
@ -83,7 +82,11 @@ function getAutomationID(category, analysis_key, environment) {
|
|||
}
|
||||
return automationID;
|
||||
}
|
||||
return actionsUtil.computeAutomationID(analysis_key, environment);
|
||||
// analysis_key is undefined for the runner.
|
||||
if (analysis_key !== undefined) {
|
||||
return actionsUtil.computeAutomationID(analysis_key, environment);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
// Upload the given payload.
|
||||
// If the request fails then this will retry a small number of times.
|
||||
|
|
@ -244,17 +247,18 @@ exports.buildPayload = buildPayload;
|
|||
async function uploadFiles(sarifFiles, repositoryNwo, commitOid, ref, analysisKey, category, analysisName, workflowRunID, sourceRoot, environment, gitHubVersion, apiDetails, logger) {
|
||||
logger.startGroup("Uploading results");
|
||||
logger.info(`Processing sarif files: ${JSON.stringify(sarifFiles)}`);
|
||||
validateUniqueCategory(category);
|
||||
// Validate that the files we were asked to upload are all valid SARIF files
|
||||
for (const file of sarifFiles) {
|
||||
validateSarifFileSchema(file, logger);
|
||||
}
|
||||
let sarifPayload = combineSarifFiles(sarifFiles);
|
||||
sarifPayload = await fingerprints.addFingerprints(sarifPayload, sourceRoot, logger);
|
||||
sarifPayload = populateRunAutomationDetails(sarifPayload, category, analysisKey, environment);
|
||||
let sarif = combineSarifFiles(sarifFiles);
|
||||
sarif = await fingerprints.addFingerprints(sarif, sourceRoot, logger);
|
||||
sarif = populateRunAutomationDetails(sarif, category, analysisKey, environment);
|
||||
const toolNames = util.getToolNames(sarif);
|
||||
validateUniqueCategory(sarif);
|
||||
const sarifPayload = JSON.stringify(sarif);
|
||||
const zippedSarif = zlib_1.default.gzipSync(sarifPayload).toString("base64");
|
||||
const checkoutURI = (0, file_url_1.default)(sourceRoot);
|
||||
const toolNames = util.getToolNames(sarifPayload);
|
||||
const payload = buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, workflowRunID, checkoutURI, environment, toolNames, gitHubVersion);
|
||||
// Log some useful debug info about the info
|
||||
const rawUploadSizeBytes = sarifPayload.length;
|
||||
|
|
@ -325,16 +329,22 @@ async function waitForProcessing(repositoryNwo, sarifID, apiDetails, logger) {
|
|||
logger.endGroup();
|
||||
}
|
||||
exports.waitForProcessing = waitForProcessing;
|
||||
function validateUniqueCategory(category) {
|
||||
function validateUniqueCategory(sarif) {
|
||||
var _a, _b, _c;
|
||||
// This check only works on actions as env vars don't persist between calls to the runner
|
||||
if (util.isActions()) {
|
||||
// This check only works on actions as env vars don't persist between calls to the runner
|
||||
const sentinelEnvVar = `CODEQL_UPLOAD_SARIF${category ? `_${sanitize(category)}` : ""}`;
|
||||
if (process.env[sentinelEnvVar]) {
|
||||
throw new Error("Aborting upload: only one run of the codeql/analyze or codeql/upload-sarif actions is allowed per job per category. " +
|
||||
"Please specify a unique `category` to call this action multiple times. " +
|
||||
`Category: ${category ? category : "(none)"}`);
|
||||
for (const run of sarif.runs) {
|
||||
const id = (_a = run === null || run === void 0 ? void 0 : run.automationDetails) === null || _a === void 0 ? void 0 : _a.id;
|
||||
const tool = (_c = (_b = run.tool) === null || _b === void 0 ? void 0 : _b.driver) === null || _c === void 0 ? void 0 : _c.name;
|
||||
const category = `${sanitize(id)}_${sanitize(tool)}`;
|
||||
const sentinelEnvVar = `CODEQL_UPLOAD_SARIF_${category}`;
|
||||
if (process.env[sentinelEnvVar]) {
|
||||
throw new Error("Aborting upload: only one run of the codeql/analyze or codeql/upload-sarif actions is allowed per job per tool/category. " +
|
||||
"The easiest fix is to specify a unique value for the `category` input. " +
|
||||
`Category: (${id ? id : "none"}) Tool: (${tool ? tool : "none"})`);
|
||||
}
|
||||
core.exportVariable(sentinelEnvVar, sentinelEnvVar);
|
||||
}
|
||||
core.exportVariable(sentinelEnvVar, sentinelEnvVar);
|
||||
}
|
||||
}
|
||||
exports.validateUniqueCategory = validateUniqueCategory;
|
||||
|
|
@ -348,6 +358,6 @@ exports.validateUniqueCategory = validateUniqueCategory;
|
|||
* @param str the initial value to sanitize
|
||||
*/
|
||||
function sanitize(str) {
|
||||
return str.replace(/[^a-zA-Z0-9_]/g, "_");
|
||||
return (str !== null && str !== void 0 ? str : "_").replace(/[^a-zA-Z0-9_]/g, "_").toLocaleUpperCase();
|
||||
}
|
||||
//# sourceMappingURL=upload-lib.js.map
|
||||
Loading…
Add table
Add a link
Reference in a new issue