Move core upload-sarif logic to upload-sarif module

Note that this also fixes the format of the `sarif-ids` outputs to match what is documented
This commit is contained in:
Michael B. Gale
2025-09-29 08:57:52 +01:00
parent 5fc9e66105
commit 9f452fad0f
5 changed files with 119 additions and 79 deletions
+11 -40
View File
@@ -1,5 +1,3 @@
import * as fs from "fs";
import * as core from "@actions/core";
import * as actionsUtil from "./actions-util";
@@ -18,7 +16,7 @@ import {
isThirdPartyAnalysis,
} from "./status-report";
import * as upload_lib from "./upload-lib";
import { findAndUpload } from "./upload-sarif";
import { uploadSarif } from "./upload-sarif";
import {
ConfigurationError,
checkActionVersion,
@@ -91,56 +89,29 @@ async function run() {
const sarifPath = actionsUtil.getRequiredInput("sarif_file");
const checkoutPath = actionsUtil.getRequiredInput("checkout_path");
const category = actionsUtil.getOptionalInput("category");
const pathStats = fs.lstatSync(sarifPath, { throwIfNoEntry: false });
if (pathStats === undefined) {
throw new ConfigurationError(`Path does not exist: ${sarifPath}.`);
}
const sarifIds: Array<{ analysis: string; id: string }> = [];
const uploadResult = await findAndUpload(
const uploadResults = await uploadSarif(
logger,
features,
sarifPath,
pathStats,
checkoutPath,
analyses.CodeScanning,
sarifPath,
category,
);
if (uploadResult !== undefined) {
core.setOutput("sarif-id", uploadResult.sarifID);
sarifIds.push({
analysis: analyses.AnalysisKind.CodeScanning,
id: uploadResult.sarifID,
});
const codeScanningResult =
uploadResults[analyses.AnalysisKind.CodeScanning];
if (codeScanningResult !== undefined) {
core.setOutput("sarif-id", codeScanningResult.sarifID);
}
// If there are `.quality.sarif` files in `sarifPath`, then upload those to the code quality service.
const qualityUploadResult = await findAndUpload(
logger,
features,
sarifPath,
pathStats,
checkoutPath,
analyses.CodeQuality,
actionsUtil.fixCodeQualityCategory(logger, category),
);
if (qualityUploadResult !== undefined) {
sarifIds.push({
analysis: analyses.AnalysisKind.CodeQuality,
id: qualityUploadResult.sarifID,
});
}
core.setOutput("sarif-ids", JSON.stringify(sarifIds));
core.setOutput("sarif-ids", JSON.stringify(uploadResults));
// We don't upload results in test mode, so don't wait for processing
if (isInTestMode()) {
core.debug("In test mode. Waiting for processing is disabled.");
} else if (actionsUtil.getRequiredInput("wait-for-processing") === "true") {
if (uploadResult !== undefined) {
if (codeScanningResult !== undefined) {
await upload_lib.waitForProcessing(
getRepositoryNwo(),
uploadResult.sarifID,
codeScanningResult.sarifID,
logger,
);
}
@@ -149,7 +120,7 @@ async function run() {
}
await sendSuccessStatusReport(
startedAt,
uploadResult?.statusReport || {},
codeScanningResult?.statusReport || {},
logger,
);
} catch (unwrappedError) {
+64 -2
View File
@@ -1,9 +1,11 @@
import * as fs from "fs";
import * as actionsUtil from "./actions-util";
import * as analyses from "./analyses";
import { Features } from "./feature-flags";
import { FeatureEnablement } from "./feature-flags";
import { Logger } from "./logging";
import * as upload_lib from "./upload-lib";
import { ConfigurationError } from "./util";
/**
* Searches for SARIF files for the given `analysis` in the given `sarifPath`.
@@ -20,7 +22,7 @@ import * as upload_lib from "./upload-lib";
*/
export async function findAndUpload(
logger: Logger,
features: Features,
features: FeatureEnablement,
sarifPath: string,
pathStats: fs.Stats,
checkoutPath: string,
@@ -58,3 +60,63 @@ export async function findAndUpload(
return undefined;
}
// Maps analysis kinds to SARIF IDs.
type UploadSarifResults = Partial<
Record<analyses.AnalysisKind, upload_lib.UploadResult>
>;
/**
* Finds SARIF files in `sarifPath` and uploads them to the appropriate services.
*
* @param logger The logger to use.
* @param features Information about enabled features.
* @param checkoutPath The path where the repository was checked out at.
* @param sarifPath The path to the file or directory to upload.
* @param category The analysis category.
*
* @returns A partial mapping from analysis kinds to the upload results.
*/
export async function uploadSarif(
logger: Logger,
features: FeatureEnablement,
checkoutPath: string,
sarifPath: string,
category?: string,
): Promise<UploadSarifResults> {
const pathStats = fs.lstatSync(sarifPath, { throwIfNoEntry: false });
if (pathStats === undefined) {
throw new ConfigurationError(`Path does not exist: ${sarifPath}.`);
}
const uploadResults: UploadSarifResults = {};
const uploadResult = await findAndUpload(
logger,
features,
sarifPath,
pathStats,
checkoutPath,
analyses.CodeScanning,
category,
);
if (uploadResult !== undefined) {
uploadResults[analyses.AnalysisKind.CodeScanning] = uploadResult;
}
// If there are `.quality.sarif` files in `sarifPath`, then upload those to the code quality service.
const qualityUploadResult = await findAndUpload(
logger,
features,
sarifPath,
pathStats,
checkoutPath,
analyses.CodeQuality,
actionsUtil.fixCodeQualityCategory(logger, category),
);
if (qualityUploadResult !== undefined) {
uploadResults[analyses.AnalysisKind.CodeQuality] = qualityUploadResult;
}
return uploadResults;
}