Add environment variable override

This commit is contained in:
Henry Mercer
2026-03-10 15:41:40 +00:00
parent bef08edf32
commit 55a0f2b2aa
11 changed files with 1928 additions and 1647 deletions

View File

@@ -6,7 +6,12 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th
- Upcoming change: Starting April 2026, the CodeQL Action will skip collecting file coverage information on pull requests to improve analysis performance. File coverage information will still be computed on non-PR analyses. Pull request analyses will log a warning about this upcoming change.
Repositories owned by an organization can opt out of this change by creating a custom repository property with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then setting this property to `true` in the repository's settings. For more information, see [Managing custom properties for repositories in your organization](https://docs.github.com/en/organizations/managing-organization-settings/managing-custom-properties-for-repositories-in-your-organization). [#3562](https://github.com/github/codeql-action/pull/3562)
To opt out of this change:
- **Repositories owned by an organization:** Create a custom repository property with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to `true` in the repository's settings. For more information, see [Managing custom properties for repositories in your organization](https://docs.github.com/en/organizations/managing-organization-settings/managing-custom-properties-for-repositories-in-your-organization). Alternatively, if you are using an advanced setup workflow, you can set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true` in your workflow.
- **User-owned repositories using default setup:** Switch to an advanced setup workflow and set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true` in your workflow.
- **User-owned repositories using advanced setup:** Set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true` in your workflow.
[#3562](https://github.com/github/codeql-action/pull/3562)
- Fixed [a bug](https://github.com/github/codeql-action/issues/3555) which caused the CodeQL Action to fail loading repository properties if a "Multi select" repository property was configured for the repository. [#3557](https://github.com/github/codeql-action/pull/3557)
- The CodeQL Action now loads [custom repository properties](https://docs.github.com/en/organizations/managing-organization-settings/managing-custom-properties-for-repositories-in-your-organization) on GitHub Enterprise Server, enabling the customization of features such as `github-codeql-disable-overlay` that was previously only available on GitHub.com. [#3559](https://github.com/github/codeql-action/pull/3559)

480
lib/analyze-action.js generated

File diff suppressed because it is too large Load Diff

820
lib/init-action-post.js generated

File diff suppressed because it is too large Load Diff

585
lib/init-action.js generated

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

460
lib/upload-lib.js generated

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -50,6 +50,12 @@ export enum EnvVar {
/** Whether the deprecation warning for file coverage on PRs has been logged. */
DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION = "CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION",
/**
* Set to `true` to opt out of the upcoming change that skips file coverage
* information on pull requests.
*/
FILE_COVERAGE_ON_PRS = "CODEQL_ACTION_FILE_COVERAGE_ON_PRS",
/** Whether the error for a deprecated version of the CodeQL Action was logged. */
LOG_VERSION_DEPRECATION = "CODEQL_ACTION_DID_LOG_VERSION_DEPRECATION",

View File

@@ -48,6 +48,7 @@ import {
checkPacksForOverlayCompatibility,
cleanupDatabaseClusterDirectory,
getFileCoverageInformationEnabled,
logFileCoverageOnPrsDeprecationWarning,
initCodeQL,
initConfig,
runDatabaseInitCluster,
@@ -409,21 +410,8 @@ async function run(startedAt: Date) {
);
}
if (
fileCoverageResult.showDeprecationWarning &&
!process.env[EnvVar.DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION]
) {
logger.warning(
"Starting April 2026, the CodeQL Action will skip collecting file coverage information on pull requests " +
"to improve analysis performance. File coverage information will still be computed on non-PR analyses. " +
"Repositories owned by an organization can opt out of this change by creating a custom repository property " +
'with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then setting this property to ' +
"`true` in the repository's settings.",
);
core.exportVariable(
EnvVar.DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION,
"true",
);
if (fileCoverageResult.showDeprecationWarning) {
logFileCoverageOnPrsDeprecationWarning(logger);
}
await checkInstallPython311(config.languages, codeql);

View File

@@ -1,6 +1,8 @@
import * as fs from "fs";
import path from "path";
import * as core from "@actions/core";
import * as github from "@actions/github";
import test, { ExecutionContext } from "ava";
import * as sinon from "sinon";
@@ -11,6 +13,7 @@ import {
checkPacksForOverlayCompatibility,
cleanupDatabaseClusterDirectory,
getFileCoverageInformationEnabled,
logFileCoverageOnPrsDeprecationWarning,
} from "./init";
import { KnownLanguage } from "./languages";
import {
@@ -516,6 +519,24 @@ test.serial(
},
);
test.serial(
"file coverage information enabled when env var opt-out is set",
async (t) => {
sinon.stub(actionsUtil, "isAnalyzingPullRequest").returns(true);
process.env["CODEQL_ACTION_FILE_COVERAGE_ON_PRS"] = "true";
const result = await getFileCoverageInformationEnabled(
false, // debugMode
createStubCodeQL({}),
createFeatures([Feature.SkipFileCoverageOnPrs]),
{},
);
t.true(result.enabled);
t.false(result.enabledByRepositoryProperty);
t.false(result.showDeprecationWarning);
},
);
test.serial(
"file coverage information disabled when all conditions for skipping are met",
async (t) => {
@@ -532,3 +553,163 @@ test.serial(
t.false(result.showDeprecationWarning);
},
);
test.serial(
"file coverage deprecation warning for org-owned repo with default setup recommends repo property",
(t) => {
const exportVariableStub = sinon.stub(core, "exportVariable");
sinon.stub(actionsUtil, "isDefaultSetup").returns(true);
github.context.payload = {
repository: {
name: "test-repo",
owner: { login: "test-org", type: "Organization" },
},
};
const messages: LoggedMessage[] = [];
logFileCoverageOnPrsDeprecationWarning(getRecordingLogger(messages));
t.is(messages.length, 1);
t.is(messages[0].type, "warning");
t.is(
messages[0].message,
"Starting April 2026, the CodeQL Action will skip computing file coverage information on pull requests " +
"to improve analysis performance. File coverage information will still be computed on non-PR analyses.\n\n" +
"To opt out of this change, create a custom repository property " +
'with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to ' +
"`true` in the repository's settings.",
);
t.true(exportVariableStub.calledOnce);
},
);
test.serial(
"file coverage deprecation warning for org-owned repo with advanced setup recommends env var and repo property",
(t) => {
const exportVariableStub = sinon.stub(core, "exportVariable");
sinon.stub(actionsUtil, "isDefaultSetup").returns(false);
github.context.payload = {
repository: {
name: "test-repo",
owner: { login: "test-org", type: "Organization" },
},
};
const messages: LoggedMessage[] = [];
logFileCoverageOnPrsDeprecationWarning(getRecordingLogger(messages));
t.is(messages.length, 1);
t.is(messages[0].type, "warning");
t.is(
messages[0].message,
"Starting April 2026, the CodeQL Action will skip computing file coverage information on pull requests " +
"to improve analysis performance. File coverage information will still be computed on non-PR analyses.\n\n" +
"To opt out of this change, set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`. " +
"Alternatively, create a custom repository property " +
'with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to ' +
"`true` in the repository's settings.",
);
t.true(exportVariableStub.calledOnce);
},
);
test.serial(
"file coverage deprecation warning for user-owned repo with default setup recommends advanced setup",
(t) => {
const exportVariableStub = sinon.stub(core, "exportVariable");
sinon.stub(actionsUtil, "isDefaultSetup").returns(true);
github.context.payload = {
repository: {
name: "test-repo",
owner: { login: "test-user", type: "User" },
},
};
const messages: LoggedMessage[] = [];
logFileCoverageOnPrsDeprecationWarning(getRecordingLogger(messages));
t.is(messages.length, 1);
t.is(messages[0].type, "warning");
t.is(
messages[0].message,
"Starting April 2026, the CodeQL Action will skip computing file coverage information on pull requests " +
"to improve analysis performance. File coverage information will still be computed on non-PR analyses.\n\n" +
"To opt out of this change, switch to an advanced setup workflow and " +
"set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.",
);
t.true(exportVariableStub.calledOnce);
},
);
test.serial(
"file coverage deprecation warning for user-owned repo with advanced setup recommends env var",
(t) => {
const exportVariableStub = sinon.stub(core, "exportVariable");
sinon.stub(actionsUtil, "isDefaultSetup").returns(false);
github.context.payload = {
repository: {
name: "test-repo",
owner: { login: "test-user", type: "User" },
},
};
const messages: LoggedMessage[] = [];
logFileCoverageOnPrsDeprecationWarning(getRecordingLogger(messages));
t.is(messages.length, 1);
t.is(messages[0].type, "warning");
t.is(
messages[0].message,
"Starting April 2026, the CodeQL Action will skip computing file coverage information on pull requests " +
"to improve analysis performance. File coverage information will still be computed on non-PR analyses.\n\n" +
"To opt out of this change, set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.",
);
t.true(exportVariableStub.calledOnce);
},
);
test.serial(
"file coverage deprecation warning for unknown owner type with default setup recommends advanced setup",
(t) => {
const exportVariableStub = sinon.stub(core, "exportVariable");
sinon.stub(actionsUtil, "isDefaultSetup").returns(true);
github.context.payload = { repository: undefined };
const messages: LoggedMessage[] = [];
logFileCoverageOnPrsDeprecationWarning(getRecordingLogger(messages));
t.is(messages.length, 1);
t.is(messages[0].type, "warning");
t.is(
messages[0].message,
"Starting April 2026, the CodeQL Action will skip computing file coverage information on pull requests " +
"to improve analysis performance. File coverage information will still be computed on non-PR analyses.\n\n" +
"To opt out of this change, switch to an advanced setup workflow and " +
"set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.",
);
t.true(exportVariableStub.calledOnce);
},
);
test.serial(
"file coverage deprecation warning for unknown owner type with advanced setup recommends env var",
(t) => {
const exportVariableStub = sinon.stub(core, "exportVariable");
sinon.stub(actionsUtil, "isDefaultSetup").returns(false);
github.context.payload = { repository: undefined };
const messages: LoggedMessage[] = [];
logFileCoverageOnPrsDeprecationWarning(getRecordingLogger(messages));
t.is(messages.length, 1);
t.is(messages[0].type, "warning");
t.is(
messages[0].message,
"Starting April 2026, the CodeQL Action will skip computing file coverage information on pull requests " +
"to improve analysis performance. File coverage information will still be computed on non-PR analyses.\n\n" +
"To opt out of this change, set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.",
);
t.true(exportVariableStub.calledOnce);
},
);
test.serial(
"logFileCoverageOnPrsDeprecationWarning does not log if already logged",
(t) => {
process.env["CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION"] =
"true";
const exportVariableStub = sinon.stub(core, "exportVariable");
const messages: LoggedMessage[] = [];
logFileCoverageOnPrsDeprecationWarning(getRecordingLogger(messages));
t.is(messages.length, 0);
t.true(exportVariableStub.notCalled);
},
);

View File

@@ -1,18 +1,22 @@
import * as fs from "fs";
import * as path from "path";
import * as core from "@actions/core";
import * as toolrunner from "@actions/exec/lib/toolrunner";
import * as github from "@actions/github";
import * as io from "@actions/io";
import * as yaml from "js-yaml";
import {
getOptionalInput,
isAnalyzingPullRequest,
isDefaultSetup,
isSelfHostedRunner,
} from "./actions-util";
import { GitHubApiDetails } from "./api-client";
import { CodeQL, setupCodeQL } from "./codeql";
import * as configUtils from "./config-utils";
import { EnvVar } from "./environment";
import {
CodeQLDefaultVersionInfo,
Feature,
@@ -329,6 +333,18 @@ export async function getFileCoverageInformationEnabled(
showDeprecationWarning: false,
};
}
// If the user has explicitly opted out via an environment variable, don't
// show the deprecation warning.
if (
(process.env[EnvVar.FILE_COVERAGE_ON_PRS] || "").toLocaleLowerCase() ===
"true"
) {
return {
enabled: true,
enabledByRepositoryProperty: false,
showDeprecationWarning: false,
};
}
// Allow repositories to opt in to file coverage information on PRs
// using a repository property. In this case, don't show the deprecation
// warning since the repository has explicitly opted in.
@@ -358,3 +374,45 @@ export async function getFileCoverageInformationEnabled(
showDeprecationWarning: false,
};
}
/**
* Log a warning about the deprecation of file coverage information on PRs, including how to opt
* back in via an environment variable or repository property.
*/
export function logFileCoverageOnPrsDeprecationWarning(logger: Logger): void {
if (process.env[EnvVar.DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION]) {
return;
}
const repositoryOwnerType: string | undefined =
github.context.payload.repository?.owner.type;
let message =
"Starting April 2026, the CodeQL Action will skip computing file coverage information on pull requests " +
"to improve analysis performance. File coverage information will still be computed on non-PR analyses.";
const envVarOptOut =
"set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.";
const repoPropertyOptOut =
"create a custom repository property with the name " +
'`github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to ' +
"`true` in the repository's settings.";
if (repositoryOwnerType === "Organization") {
// Org-owned repo: can use the repository property
if (isDefaultSetup()) {
message += `\n\nTo opt out of this change, ${repoPropertyOptOut}`;
} else {
message += `\n\nTo opt out of this change, ${envVarOptOut} Alternatively, ${repoPropertyOptOut}`;
}
} else if (isDefaultSetup()) {
// User-owned repo on default setup: no repo property available and
// no way to set env vars, so need to switch to advanced setup.
message += `\n\nTo opt out of this change, switch to an advanced setup workflow and ${envVarOptOut}`;
} else {
// User-owned repo on advanced setup: can set the env var
message += `\n\nTo opt out of this change, ${envVarOptOut}`;
}
logger.warning(message);
core.exportVariable(EnvVar.DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION, "true");
}