diff --git a/init/action.yml b/init/action.yml index 57d5a99402..6c36f79bc4 100644 --- a/init/action.yml +++ b/init/action.yml @@ -159,6 +159,11 @@ inputs: description: >- Explicitly enable or disable caching of project build dependencies. required: false + check-run-id: + description: >- + [Internal] The ID of the check run, as provided by the Actions runtime environment. Do not set this value manually. + default: ${{ job.check_run_id }} + required: false outputs: codeql-path: description: The path of the CodeQL binary used for analysis diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 67322ea200..cd49ab720a 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -166091,6 +166091,18 @@ function getStatusFilePath(languages) { STATUS_FILE_NAME ); } +function createOverlayStatus(attributes, checkRunId) { + const job = { + workflowRunId: getWorkflowRunID(), + workflowRunAttempt: getWorkflowRunAttempt(), + name: getRequiredEnvParam("GITHUB_JOB"), + checkRunId + }; + return { + ...attributes, + job + }; +} async function saveOverlayStatus(codeql, languages, diskUsage, status, logger) { const cacheKey = await getCacheKey(codeql, languages, diskUsage); const statusFile = getStatusFilePath(languages); @@ -170355,10 +170367,15 @@ async function recordOverlayStatus(codeql, config, features, logger) { if (config.overlayDatabaseMode !== "overlay-base" /* OverlayBase */ || process.env["CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */] === "true" || !await features.getValue("overlay_analysis_status_save" /* OverlayAnalysisStatusSave */)) { return; } - const overlayStatus = { - attemptedToBuildOverlayBaseDatabase: true, - builtOverlayBaseDatabase: false - }; + const checkRunIdInput = getOptionalInput("check-run-id"); + const checkRunId = checkRunIdInput !== void 0 ? parseInt(checkRunIdInput, 10) : void 0; + const overlayStatus = createOverlayStatus( + { + attemptedToBuildOverlayBaseDatabase: true, + builtOverlayBaseDatabase: false + }, + checkRunId !== void 0 && checkRunId >= 0 ? checkRunId : void 0 + ); const diskUsage = await checkDiskUsage(logger); if (diskUsage === void 0) { logger.warning( diff --git a/src/init-action-post-helper.test.ts b/src/init-action-post-helper.test.ts index 1ddb702872..5bdb674a14 100644 --- a/src/init-action-post-helper.test.ts +++ b/src/init-action-post-helper.test.ts @@ -316,6 +316,9 @@ test("not uploading failed SARIF when `code-scanning` is not an enabled analysis test("saves overlay status when overlay-base analysis did not complete successfully", async (t) => { return await util.withTmpDir(async (tmpDir) => { process.env["GITHUB_REPOSITORY"] = "github/codeql-action-fake-repository"; + process.env["GITHUB_RUN_ID"] = "12345"; + process.env["GITHUB_RUN_ATTEMPT"] = "1"; + process.env["GITHUB_JOB"] = "analyze"; process.env["RUNNER_TEMP"] = tmpDir; // Ensure analyze did not complete successfully. delete process.env[EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY]; @@ -370,8 +373,14 @@ test("saves overlay status when overlay-base analysis did not complete successfu { attemptedToBuildOverlayBaseDatabase: true, builtOverlayBaseDatabase: false, + job: { + checkRunId: undefined, + workflowRunId: 12345, + workflowRunAttempt: 1, + name: "analyze", + }, }, - "fourth arg should be the overlay status recording an unsuccessful build attempt", + "fourth arg should be the overlay status recording an unsuccessful build attempt with job details", ); }); }); diff --git a/src/init-action-post-helper.ts b/src/init-action-post-helper.ts index 90a4626654..a8f7a8731d 100644 --- a/src/init-action-post-helper.ts +++ b/src/init-action-post-helper.ts @@ -12,7 +12,11 @@ import { EnvVar } from "./environment"; import { Feature, FeatureEnablement } from "./feature-flags"; import { Logger } from "./logging"; import { OverlayDatabaseMode } from "./overlay"; -import { OverlayStatus, saveOverlayStatus } from "./overlay/status"; +import { + createOverlayStatus, + OverlayStatus, + saveOverlayStatus, +} from "./overlay/status"; import { RepositoryNwo, getRepositoryNwo } from "./repository"; import { JobStatus } from "./status-report"; import * as uploadLib from "./upload-lib"; @@ -270,10 +274,17 @@ async function recordOverlayStatus( return; } - const overlayStatus: OverlayStatus = { - attemptedToBuildOverlayBaseDatabase: true, - builtOverlayBaseDatabase: false, - }; + const checkRunIdInput = actionsUtil.getOptionalInput("check-run-id"); + const checkRunId = + checkRunIdInput !== undefined ? parseInt(checkRunIdInput, 10) : undefined; + + const overlayStatus: OverlayStatus = createOverlayStatus( + { + attemptedToBuildOverlayBaseDatabase: true, + builtOverlayBaseDatabase: false, + }, + checkRunId !== undefined && checkRunId >= 0 ? checkRunId : undefined, + ); const diskUsage = await checkDiskUsage(logger); if (diskUsage === undefined) { diff --git a/src/overlay/status.ts b/src/overlay/status.ts index ac3d6e7476..a57835ed1b 100644 --- a/src/overlay/status.ts +++ b/src/overlay/status.ts @@ -13,12 +13,17 @@ import * as path from "path"; import * as actionsCache from "@actions/cache"; -import { getTemporaryDirectory } from "../actions-util"; +import { + getTemporaryDirectory, + getWorkflowRunAttempt, + getWorkflowRunID, +} from "../actions-util"; import { type CodeQL } from "../codeql"; import { Logger } from "../logging"; import { DiskUsage, getErrorMessage, + getRequiredEnvParam, waitForResultWithTimeLimit, } from "../util"; @@ -38,12 +43,43 @@ function getStatusFilePath(languages: string[]): string { ); } +/** Details of the job that recorded an overlay status. */ +interface JobInfo { + /** The check run ID. This is optional since it is not always available. */ + checkRunId?: number; + /** The workflow run ID. */ + workflowRunId: number; + /** The workflow run attempt number. */ + workflowRunAttempt: number; + /** The name of the job (from GITHUB_JOB). */ + name: string; +} + /** Status of an overlay analysis for a group of languages. */ export interface OverlayStatus { /** Whether the job attempted to build an overlay base database. */ attemptedToBuildOverlayBaseDatabase: boolean; /** Whether the job successfully built an overlay base database. */ builtOverlayBaseDatabase: boolean; + /** Details of the job that recorded this status. */ + job?: JobInfo; +} + +/** Creates an `OverlayStatus` populated with the details of the current job. */ +export function createOverlayStatus( + attributes: Omit, + checkRunId?: number, +): OverlayStatus { + const job: JobInfo = { + workflowRunId: getWorkflowRunID(), + workflowRunAttempt: getWorkflowRunAttempt(), + name: getRequiredEnvParam("GITHUB_JOB"), + checkRunId, + }; + return { + ...attributes, + job, + }; } /**