Treat status reports as non-critical

Change `sendStatusReport` to `void`
This commit is contained in:
Josh Soref 2024-01-31 12:23:50 -05:00
parent 43a8916cbe
commit 5a6da1d85d
28 changed files with 146 additions and 138 deletions

View file

@ -30,7 +30,7 @@ test("analyze action with RAM & threads from environment variables", async (t) =
sinon
.stub(statusReport, "createStatusReportBase")
.resolves({} as statusReport.StatusReportBase);
sinon.stub(statusReport, "sendStatusReport").resolves(true);
sinon.stub(statusReport, "sendStatusReport").resolves();
sinon.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
const gitHubVersion: util.GitHubVersion = {

View file

@ -30,7 +30,7 @@ test("analyze action with RAM & threads from action inputs", async (t) => {
sinon
.stub(statusReport, "createStatusReportBase")
.resolves({} as statusReport.StatusReportBase);
sinon.stub(statusReport, "sendStatusReport").resolves(true);
sinon.stub(statusReport, "sendStatusReport").resolves();
const gitHubVersion: util.GitHubVersion = {
type: util.GitHubVariant.DOTCOM,
};

View file

@ -187,18 +187,15 @@ async function run() {
const logger = getActionsLogger();
try {
if (
!(await statusReport.sendStatusReport(
await createStatusReportBase(
"finish",
"starting",
startedAt,
await util.checkDiskUsage(logger),
),
))
) {
return;
}
await statusReport.sendStatusReport(
await createStatusReportBase(
"finish",
"starting",
startedAt,
await util.checkDiskUsage(logger),
),
);
config = await getConfig(actionsUtil.getTemporaryDirectory(), logger);
if (config === undefined) {
throw new Error(

View file

@ -65,18 +65,14 @@ async function run() {
let currentLanguage: Language | undefined = undefined;
let languages: Language[] | undefined = undefined;
try {
if (
!(await sendStatusReport(
await createStatusReportBase(
"autobuild",
"starting",
startedAt,
await checkDiskUsage(logger),
),
))
) {
return;
}
await sendStatusReport(
await createStatusReportBase(
"autobuild",
"starting",
startedAt,
await checkDiskUsage(logger),
),
);
const gitHubVersion = await getGitHubVersion();
checkGitHubVersionInRange(gitHubVersion, logger);

View file

@ -229,18 +229,14 @@ async function run() {
core.exportVariable(EnvVar.JOB_RUN_UUID, uuidV4());
try {
if (
!(await sendStatusReport(
await createStatusReportBase(
"init",
"starting",
startedAt,
await checkDiskUsage(logger),
),
))
) {
return;
}
await sendStatusReport(
await createStatusReportBase(
"init",
"starting",
startedAt,
await checkDiskUsage(logger),
),
);
const codeQLDefaultVersionInfo = await features.getDefaultCliVersion(
gitHubVersion.type,

View file

@ -32,18 +32,14 @@ async function run() {
const logger = getActionsLogger();
try {
if (
!(await sendStatusReport(
await createStatusReportBase(
ACTION_NAME,
"starting",
startedAt,
await checkDiskUsage(logger),
),
))
) {
return;
}
await sendStatusReport(
await createStatusReportBase(
ACTION_NAME,
"starting",
startedAt,
await checkDiskUsage(logger),
),
);
const gitHubVersion = await getGitHubVersion();
checkGitHubVersionInRange(gitHubVersion, logger);

View file

@ -282,10 +282,6 @@ export async function createStatusReportBase(
return statusReport;
}
const GENERIC_403_MSG =
"The repo on which this action is running is not opted-in to CodeQL code scanning.";
const GENERIC_404_MSG =
"Not authorized to use the CodeQL code scanning feature on this repo.";
const OUT_OF_DATE_MSG =
"CodeQL Action is out-of-date. Please upgrade to the latest version of codeql-action.";
const INCOMPATIBLE_MSG =
@ -298,11 +294,14 @@ const INCOMPATIBLE_MSG =
* as failed if the status report failed. This is only expected to be used
* when sending a 'starting' report.
*
* Returns whether sending the status report was successful of not.
* The `/code-scanning/analysis/status` endpoint is internal and it is not critical that it succeeds:
* https://github.com/github/codeql/issues/15462#issuecomment-1919186317
*
* Failures while calling this endpoint are logged as warings.
*/
export async function sendStatusReport<S extends StatusReportBase>(
statusReport: S,
): Promise<boolean> {
): Promise<void> {
setJobStatusIfUnsuccessful(statusReport.status);
const statusReportJSON = JSON.stringify(statusReport);
@ -310,7 +309,7 @@ export async function sendStatusReport<S extends StatusReportBase>(
// If in test mode we don't want to upload the results
if (isInTestMode()) {
core.debug("In test mode. Status reports are not uploaded.");
return true;
return;
}
const nwo = getRequiredEnvParam("GITHUB_REPOSITORY");
@ -326,8 +325,6 @@ export async function sendStatusReport<S extends StatusReportBase>(
data: statusReportJSON,
},
);
return true;
} catch (e) {
console.log(e);
if (isHTTPError(e)) {
@ -337,19 +334,19 @@ export async function sendStatusReport<S extends StatusReportBase>(
getWorkflowEventName() === "push" &&
process.env["GITHUB_ACTOR"] === "dependabot[bot]"
) {
core.setFailed(
core.warning(
'Workflows triggered by Dependabot on the "push" event run with read-only access. ' +
"Uploading Code Scanning results requires write access. " +
'To use Code Scanning with Dependabot, please ensure you are using the "pull_request" event for this workflow and avoid triggering on the "push" event for Dependabot branches. ' +
"See https://docs.github.com/en/code-security/secure-coding/configuring-code-scanning#scanning-on-push for more information on how to configure these events.",
);
} else {
core.setFailed(e.message || GENERIC_403_MSG);
core.warning(e.message);
}
return false;
return;
case 404:
core.setFailed(GENERIC_404_MSG);
return false;
core.warning(e.message);
return;
case 422:
// schema incompatibility when reporting status
// this means that this action version is no longer compatible with the API
@ -359,15 +356,14 @@ export async function sendStatusReport<S extends StatusReportBase>(
} else {
core.debug(OUT_OF_DATE_MSG);
}
return true;
return;
}
}
// something else has gone wrong and the request/response will be logged by octokit
// it's possible this is a transient error and we should continue scanning
core.error(
core.warning(
"An unexpected error occurred when sending code scanning status report.",
);
return true;
}
}

View file

@ -16,6 +16,11 @@ import { parseRepositoryNwo, RepositoryNwo } from "./repository";
import * as util from "./util";
import { SarifFile, ConfigurationError, wrapError } from "./util";
const GENERIC_403_MSG =
"The repo on which this action is running has not opted-in to CodeQL code scanning.";
const GENERIC_404_MSG =
"The CodeQL code scanning feature is forbidden on this repository.";
// Takes a list of paths to sarif files and combines them together,
// returning the contents of the combined sarif file.
function combineSarifFiles(sarifFiles: string[]): SarifFile {
@ -107,19 +112,35 @@ async function uploadPayload(
const client = api.getApiClient();
const response = await client.request(
"PUT /repos/:owner/:repo/code-scanning/analysis",
{
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
data: payload,
},
);
try {
const response = await client.request(
"PUT /repos/:owner/:repo/code-scanning/analysis",
{
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
data: payload,
},
);
logger.debug(`response status: ${response.status}`);
logger.info("Successfully uploaded results");
return response.data.id;
logger.debug(`response status: ${response.status}`);
logger.info("Successfully uploaded results");
return response.data.id;
} catch (e) {
if (util.isHTTPError(e)) {
switch (e.status) {
case 403:
core.warning(e.message || GENERIC_403_MSG);
break;
case 404:
core.warning(e.message || GENERIC_404_MSG);
break;
default:
core.warning(e.message);
break;
}
}
throw e;
}
}
export interface UploadStatusReport {

View file

@ -50,18 +50,14 @@ async function run() {
const gitHubVersion = await getGitHubVersion();
checkActionVersion(getActionVersion(), gitHubVersion);
if (
!(await sendStatusReport(
await createStatusReportBase(
"upload-sarif",
"starting",
startedAt,
await checkDiskUsage(),
),
))
) {
return;
}
await sendStatusReport(
await createStatusReportBase(
"upload-sarif",
"starting",
startedAt,
await checkDiskUsage(),
),
);
try {
const uploadResult = await upload_lib.uploadFromActions(