mirror of
https://github.com/github/codeql-action.git
synced 2026-10-20 17:51:32 +00:00
Compare commits
22 Commits
mbg/use-gi
...
mbg/refact
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eaaa622046 | ||
|
|
75aa44b152 | ||
|
|
c252c71195 | ||
|
|
a234b846e2 | ||
|
|
dc2ed81cc7 | ||
|
|
02283e9542 | ||
|
|
86bc4448d3 | ||
|
|
9c72af5b2b | ||
|
|
929f5c0db4 | ||
|
|
a76419a632 | ||
|
|
071544a67a | ||
|
|
8bdea824e2 | ||
|
|
83e1837c6d | ||
|
|
5ecf3b32e9 | ||
|
|
e461913b38 | ||
|
|
6992155901 | ||
|
|
f3c93e3106 | ||
|
|
2441e6e56e | ||
|
|
0d2baf6822 | ||
|
|
ae098fa9fe | ||
|
|
4ebc48bf25 | ||
|
|
1ec6b03cf4 |
17
.github/copilot-instructions.md
vendored
17
.github/copilot-instructions.md
vendored
@@ -11,9 +11,12 @@ The CodeQL Action is used in GitHub Actions workflows to run CodeQL scans using
|
||||
|
||||
## Review instructions
|
||||
|
||||
- When wording review comments, be helpful and friendly. Assume that the PR author has written the code with the best of intentions. Word your comments constructively as suggestions for improvements. Do not word suggestions as commands.
|
||||
- Prioritise identifying critical issues, such as logic bugs, over comments on documentation or typos.
|
||||
- When wording review comments, be helpful and friendly. Assume that the PR author has written the code with the best of intentions. Never word suggestions as commands or using the imperative. Examples of what you should never write: "Preserve that non-fatal behaviour here" or "Please preserve that non-fatal behaviour here".
|
||||
- When writing feedback, assume that the PR author is competent and is able to understand whether the point you are making is valid or not, why you are raising it, and how to best address it. While you can suggest how to address a point you are making, don't phrase it as a requirement or assume that it is the only solution.
|
||||
- Always word your comments constructively as suggestions for improvements, for example: "It would make sense to ..." or "Could you add ...?" or "Would it make sense to ...?"
|
||||
- If you want to comment on a change that you believe will fail a CI check, do not present the CI failure you expect as a fact. Instead, write that you think a change "may" lead to a failure in CI. Suggest that, if such a failure manifests, the changes you are commenting on may be the place responsible for the failure and are worth looking at.
|
||||
- If a suggestion you make is suitable for a follow-up, such as a refactoring that doesn't change the behaviour or fixing a typo in a comment, mention that it can be addressed in a later PR rather than blocking this one.
|
||||
- If a suggestion you make is suitable for a follow-up, such as a refactoring that doesn't change the behaviour or fixing a typo in a comment, mention that it can be addressed in a later PR rather than blocking this one or prefix your comment with "Minor: ".
|
||||
- If a change is a net improvement, for example because it improves on an existing limitation of existing code, do not complain about pre-existing problems that remain. You may comment on them, but you should make it clear that the thing you are commenting on is not new by writing e.g. "Not new in this PR, but [..]" followed by your description of the issue and a suggestion that it could be improved at the same time with e.g. "Consider whether this is worth addressing as part of this PR as well."
|
||||
|
||||
## Generated code
|
||||
@@ -22,6 +25,16 @@ The main codebase of the CodeQL Action is written in TypeScript and compiled to
|
||||
|
||||
GitHub Actions workflows in the `.github/workflows` directory whose filenames start with two underscores (e.g. `__all-platform-bundle.yml`) are automatically generated using the `pr-checks/sync.sh` script from template files in the `pr-checks/checks` directory. Therefore, you do not need to review files in the `.github/workflows` directory that start with two underscores. However, you should review changes to the `pr-checks` directory as well as workflows in the `.github/workflows` directory that do not start with underscores.
|
||||
|
||||
## Feature flags
|
||||
|
||||
Some functionality in the code may be gated behind feature flags, which are controlled server-side. If the functionality that is gated behind them is user-facing, then this should be documented in a change note at the time that the gated functionality is added. See `CHANGELOG.md` for existing notes that mention "experimental" for examples. These typically include information about when users may expect to see the feature rolled out.
|
||||
|
||||
When a feature flag that gates some functionality is removed, this does not need to be documented in a change note since the feature is already rolled out and the notes for the release which introduced the feature already describe it. The only exception is functionality which will start having an effect on GHES as a result of the feature flag removal:
|
||||
|
||||
- Most functionality gated behind feature flags does not affect GHES.
|
||||
- We can make functionality available on GHES by setting `defaultValue` to `true` first and waiting for this to have had an effect on GHES. No change note is needed if a feature flag is removed where `defaultValue` was `true`.
|
||||
- When removing a feature flag where `defaultValue` was `false` and the functionality starts to affect GHES, a change note may be appropriate.
|
||||
|
||||
## Release process
|
||||
|
||||
Changes that are merged to the `main` branch are not used in production straight away. Instead, changes from `main` must first be released using the release process, which has to be manually triggered by a staff member. Therefore, it is possible for further changes to be made to the code after some changes have been merged to `main` but before they are released. Once the release process automation is started, a series of PRs are automatically generated:
|
||||
|
||||
1
.github/workflows/__multi-language-autodetect.yml
generated
vendored
1
.github/workflows/__multi-language-autodetect.yml
generated
vendored
@@ -192,6 +192,5 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
env:
|
||||
CODEQL_ACTION_CLEANUP_TOOLCACHE_BUNDLES: true
|
||||
CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI: true
|
||||
CODEQL_ACTION_TEST_MODE: true
|
||||
|
||||
294
lib/entry-points.js
generated
294
lib/entry-points.js
generated
@@ -34719,7 +34719,7 @@ var require_cacheUtils = __commonJS({
|
||||
var crypto3 = __importStar2(require("crypto"));
|
||||
var fs32 = __importStar2(require("fs"));
|
||||
var path30 = __importStar2(require("path"));
|
||||
var semver11 = __importStar2(require_semver3());
|
||||
var semver12 = __importStar2(require_semver3());
|
||||
var util4 = __importStar2(require("util"));
|
||||
var constants_1 = require_constants7();
|
||||
var versionSalt = "1.0";
|
||||
@@ -34812,7 +34812,7 @@ var require_cacheUtils = __commonJS({
|
||||
function getCompressionMethod() {
|
||||
return __awaiter2(this, void 0, void 0, function* () {
|
||||
const versionOutput = yield getVersion("zstd", ["--quiet"]);
|
||||
const version = semver11.clean(versionOutput);
|
||||
const version = semver12.clean(versionOutput);
|
||||
core29.debug(`zstd version: ${version}`);
|
||||
if (versionOutput === "") {
|
||||
return constants_1.CompressionMethod.Gzip;
|
||||
@@ -42967,11 +42967,11 @@ var require_tracingPolicy = __commonJS({
|
||||
var import_log = require_log3();
|
||||
var import_core_util = require_commonjs4();
|
||||
var import_restError = require_restError3();
|
||||
var import_util59 = require_internal3();
|
||||
var import_util58 = require_internal3();
|
||||
var tracingPolicyName2 = "tracingPolicy";
|
||||
function tracingPolicy2(options = {}) {
|
||||
const userAgentPromise = (0, import_userAgent.getUserAgentValue)(options.userAgentPrefix);
|
||||
const sanitizer = new import_util59.Sanitizer({
|
||||
const sanitizer = new import_util58.Sanitizer({
|
||||
additionalAllowedQueryParameters: options.additionalAllowedQueryParameters
|
||||
});
|
||||
const tracingClient = tryCreateTracingClient();
|
||||
@@ -46597,11 +46597,11 @@ var require_response2 = __commonJS({
|
||||
});
|
||||
module2.exports = __toCommonJS2(response_exports);
|
||||
var import_core_rest_pipeline = require_commonjs6();
|
||||
var import_util59 = require_util9();
|
||||
var import_util58 = require_util9();
|
||||
var originalResponse = /* @__PURE__ */ Symbol("Original FullOperationResponse");
|
||||
function toCompatResponse2(response, options) {
|
||||
let request3 = (0, import_util59.toWebResourceLike)(response.request);
|
||||
let headers = (0, import_util59.toHttpHeadersLike)(response.headers);
|
||||
let request3 = (0, import_util58.toWebResourceLike)(response.request);
|
||||
let headers = (0, import_util58.toHttpHeadersLike)(response.headers);
|
||||
if (options?.createProxy) {
|
||||
return new Proxy(response, {
|
||||
get(target, prop, receiver) {
|
||||
@@ -46642,7 +46642,7 @@ var require_response2 = __commonJS({
|
||||
return {
|
||||
...compatResponse,
|
||||
headers,
|
||||
request: (0, import_util59.toPipelineRequest)(compatResponse.request)
|
||||
request: (0, import_util58.toPipelineRequest)(compatResponse.request)
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -46749,7 +46749,7 @@ var require_requestPolicyFactoryPolicy = __commonJS({
|
||||
requestPolicyFactoryPolicyName: () => requestPolicyFactoryPolicyName2
|
||||
});
|
||||
module2.exports = __toCommonJS2(requestPolicyFactoryPolicy_exports);
|
||||
var import_util59 = require_util9();
|
||||
var import_util58 = require_util9();
|
||||
var import_response = require_response2();
|
||||
var HttpPipelineLogLevel2 = /* @__PURE__ */ ((HttpPipelineLogLevel22) => {
|
||||
HttpPipelineLogLevel22[HttpPipelineLogLevel22["ERROR"] = 1] = "ERROR";
|
||||
@@ -46773,14 +46773,14 @@ var require_requestPolicyFactoryPolicy = __commonJS({
|
||||
async sendRequest(request3, next) {
|
||||
let httpPipeline = {
|
||||
async sendRequest(httpRequest) {
|
||||
const response2 = await next((0, import_util59.toPipelineRequest)(httpRequest));
|
||||
const response2 = await next((0, import_util58.toPipelineRequest)(httpRequest));
|
||||
return (0, import_response.toCompatResponse)(response2, { createProxy: true });
|
||||
}
|
||||
};
|
||||
for (const factory of orderedFactories) {
|
||||
httpPipeline = factory.create(httpPipeline, mockRequestPolicyOptions);
|
||||
}
|
||||
const webResourceLike = (0, import_util59.toWebResourceLike)(request3, { createProxy: true });
|
||||
const webResourceLike = (0, import_util58.toWebResourceLike)(request3, { createProxy: true });
|
||||
const response = await httpPipeline.sendRequest(webResourceLike);
|
||||
return (0, import_response.toPipelineResponse)(response);
|
||||
}
|
||||
@@ -46815,12 +46815,12 @@ var require_httpClientAdapter = __commonJS({
|
||||
});
|
||||
module2.exports = __toCommonJS2(httpClientAdapter_exports);
|
||||
var import_response = require_response2();
|
||||
var import_util59 = require_util9();
|
||||
var import_util58 = require_util9();
|
||||
function convertHttpClient2(requestPolicyClient) {
|
||||
return {
|
||||
sendRequest: async (request3) => {
|
||||
const response = await requestPolicyClient.sendRequest(
|
||||
(0, import_util59.toWebResourceLike)(request3, { createProxy: true })
|
||||
(0, import_util58.toWebResourceLike)(request3, { createProxy: true })
|
||||
);
|
||||
return (0, import_response.toPipelineResponse)(response);
|
||||
}
|
||||
@@ -46858,7 +46858,7 @@ var require_commonjs9 = __commonJS({
|
||||
disableKeepAlivePolicyName: () => import_disableKeepAlivePolicy.disableKeepAlivePolicyName,
|
||||
requestPolicyFactoryPolicyName: () => import_requestPolicyFactoryPolicy.requestPolicyFactoryPolicyName,
|
||||
toCompatResponse: () => import_response.toCompatResponse,
|
||||
toHttpHeadersLike: () => import_util59.toHttpHeadersLike
|
||||
toHttpHeadersLike: () => import_util58.toHttpHeadersLike
|
||||
});
|
||||
module2.exports = __toCommonJS2(src_exports);
|
||||
var import_extendedClient = require_extendedClient();
|
||||
@@ -46866,7 +46866,7 @@ var require_commonjs9 = __commonJS({
|
||||
var import_requestPolicyFactoryPolicy = require_requestPolicyFactoryPolicy();
|
||||
var import_disableKeepAlivePolicy = require_disableKeepAlivePolicy();
|
||||
var import_httpClientAdapter = require_httpClientAdapter();
|
||||
var import_util59 = require_util9();
|
||||
var import_util58 = require_util9();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -106361,7 +106361,7 @@ var require_manifest = __commonJS({
|
||||
exports2._findMatch = _findMatch;
|
||||
exports2._getOsVersion = _getOsVersion;
|
||||
exports2._readLinuxVersionFile = _readLinuxVersionFile;
|
||||
var semver11 = __importStar2(require_semver2());
|
||||
var semver12 = __importStar2(require_semver2());
|
||||
var core_1 = require_core();
|
||||
var os7 = require("os");
|
||||
var cp = require("child_process");
|
||||
@@ -106375,7 +106375,7 @@ var require_manifest = __commonJS({
|
||||
for (const candidate of candidates) {
|
||||
const version = candidate.version;
|
||||
(0, core_1.debug)(`check ${version} satisfies ${versionSpec}`);
|
||||
if (semver11.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) {
|
||||
if (semver12.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) {
|
||||
file = candidate.files.find((item) => {
|
||||
(0, core_1.debug)(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`);
|
||||
let chk = item.arch === archFilter && item.platform === platFilter;
|
||||
@@ -106384,7 +106384,7 @@ var require_manifest = __commonJS({
|
||||
if (osVersion === item.platform_version) {
|
||||
chk = true;
|
||||
} else {
|
||||
chk = semver11.satisfies(osVersion, item.platform_version);
|
||||
chk = semver12.satisfies(osVersion, item.platform_version);
|
||||
}
|
||||
}
|
||||
return chk;
|
||||
@@ -106644,7 +106644,7 @@ var require_tool_cache = __commonJS({
|
||||
var os7 = __importStar2(require("os"));
|
||||
var path30 = __importStar2(require("path"));
|
||||
var httpm = __importStar2(require_lib());
|
||||
var semver11 = __importStar2(require_semver2());
|
||||
var semver12 = __importStar2(require_semver2());
|
||||
var stream2 = __importStar2(require("stream"));
|
||||
var util4 = __importStar2(require("util"));
|
||||
var assert_1 = require("assert");
|
||||
@@ -106917,7 +106917,7 @@ var require_tool_cache = __commonJS({
|
||||
}
|
||||
function cacheDir2(sourceDir, tool, version, arch2) {
|
||||
return __awaiter2(this, void 0, void 0, function* () {
|
||||
version = semver11.clean(version) || version;
|
||||
version = semver12.clean(version) || version;
|
||||
arch2 = arch2 || os7.arch();
|
||||
core29.debug(`Caching tool ${tool} ${version} ${arch2}`);
|
||||
core29.debug(`source dir: ${sourceDir}`);
|
||||
@@ -106935,7 +106935,7 @@ var require_tool_cache = __commonJS({
|
||||
}
|
||||
function cacheFile(sourceFile, targetFile, tool, version, arch2) {
|
||||
return __awaiter2(this, void 0, void 0, function* () {
|
||||
version = semver11.clean(version) || version;
|
||||
version = semver12.clean(version) || version;
|
||||
arch2 = arch2 || os7.arch();
|
||||
core29.debug(`Caching tool ${tool} ${version} ${arch2}`);
|
||||
core29.debug(`source file: ${sourceFile}`);
|
||||
@@ -106965,7 +106965,7 @@ var require_tool_cache = __commonJS({
|
||||
}
|
||||
let toolPath = "";
|
||||
if (versionSpec) {
|
||||
versionSpec = semver11.clean(versionSpec) || "";
|
||||
versionSpec = semver12.clean(versionSpec) || "";
|
||||
const cachePath = path30.join(_getCacheDirectory(), toolName, versionSpec, arch2);
|
||||
core29.debug(`checking cache: ${cachePath}`);
|
||||
if (fs32.existsSync(cachePath) && fs32.existsSync(`${cachePath}.complete`)) {
|
||||
@@ -107045,7 +107045,7 @@ var require_tool_cache = __commonJS({
|
||||
}
|
||||
function _createToolPath(tool, version, arch2) {
|
||||
return __awaiter2(this, void 0, void 0, function* () {
|
||||
const folderPath = path30.join(_getCacheDirectory(), tool, semver11.clean(version) || version, arch2 || "");
|
||||
const folderPath = path30.join(_getCacheDirectory(), tool, semver12.clean(version) || version, arch2 || "");
|
||||
core29.debug(`destination ${folderPath}`);
|
||||
const markerPath = `${folderPath}.complete`;
|
||||
yield io9.rmRF(folderPath);
|
||||
@@ -107055,15 +107055,15 @@ var require_tool_cache = __commonJS({
|
||||
});
|
||||
}
|
||||
function _completeToolPath(tool, version, arch2) {
|
||||
const folderPath = path30.join(_getCacheDirectory(), tool, semver11.clean(version) || version, arch2 || "");
|
||||
const folderPath = path30.join(_getCacheDirectory(), tool, semver12.clean(version) || version, arch2 || "");
|
||||
const markerPath = `${folderPath}.complete`;
|
||||
fs32.writeFileSync(markerPath, "");
|
||||
core29.debug("finished caching tool");
|
||||
}
|
||||
function isExplicitVersion(versionSpec) {
|
||||
const c = semver11.clean(versionSpec) || "";
|
||||
const c = semver12.clean(versionSpec) || "";
|
||||
core29.debug(`isExplicit: ${c}`);
|
||||
const valid4 = semver11.valid(c) != null;
|
||||
const valid4 = semver12.valid(c) != null;
|
||||
core29.debug(`explicit? ${valid4}`);
|
||||
return valid4;
|
||||
}
|
||||
@@ -107071,14 +107071,14 @@ var require_tool_cache = __commonJS({
|
||||
let version = "";
|
||||
core29.debug(`evaluating ${versions.length} versions`);
|
||||
versions = versions.sort((a, b) => {
|
||||
if (semver11.gt(a, b)) {
|
||||
if (semver12.gt(a, b)) {
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
});
|
||||
for (let i = versions.length - 1; i >= 0; i--) {
|
||||
const potential = versions[i];
|
||||
const satisfied = semver11.satisfies(potential, versionSpec);
|
||||
const satisfied = semver12.satisfies(potential, versionSpec);
|
||||
if (satisfied) {
|
||||
version = potential;
|
||||
break;
|
||||
@@ -166182,6 +166182,17 @@ var Env = class extends ReadOnlyEnv {
|
||||
core.exportVariable(name, val);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set some initial environment variables that we can set even without
|
||||
* knowing what version of CodeQL we're running.
|
||||
*/
|
||||
initialise(version) {
|
||||
this.export("CODEQL_ACTION_FEATURE_MULTI_LANGUAGE" /* FEATURE_MULTI_LANGUAGE */, "false");
|
||||
this.export("CODEQL_ACTION_FEATURE_SANDWICH" /* FEATURE_SANDWICH */, "false");
|
||||
this.export("CODEQL_ACTION_FEATURE_SARIF_COMBINE" /* FEATURE_SARIF_COMBINE */, "true");
|
||||
this.export("CODEQL_ACTION_FEATURE_WILL_UPLOAD" /* FEATURE_WILL_UPLOAD */, "true");
|
||||
this.export("CODEQL_ACTION_VERSION" /* VERSION */, version);
|
||||
}
|
||||
/** Gets a value indicating whether `set` was called at least once. */
|
||||
hasChanged() {
|
||||
return this.changed;
|
||||
@@ -169555,6 +169566,82 @@ function checkSchema(schema, obj, options = {}, path30 = "") {
|
||||
return result;
|
||||
}
|
||||
|
||||
// src/errors/index.ts
|
||||
function wrapError(error3) {
|
||||
return error3 instanceof Error ? error3 : new Error(String(error3));
|
||||
}
|
||||
function getErrorMessage(error3) {
|
||||
return error3 instanceof Error ? error3.message : String(error3);
|
||||
}
|
||||
function isDiskConfigurationError(e) {
|
||||
if (!(e instanceof Error)) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
// out of disk space
|
||||
e.message.includes("ENOSPC") || // access denied
|
||||
e.message.includes("EACCES")
|
||||
);
|
||||
}
|
||||
var ConfigurationError = class extends Error {
|
||||
};
|
||||
var HTTPError = class extends Error {
|
||||
status;
|
||||
constructor(message, status) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
}
|
||||
};
|
||||
function asHTTPError(arg) {
|
||||
if (!isObject2(arg) || !isString(arg.message)) {
|
||||
return void 0;
|
||||
}
|
||||
if (Number.isInteger(arg.status)) {
|
||||
return new HTTPError(arg.message, arg.status);
|
||||
}
|
||||
if (Number.isInteger(arg.httpStatusCode)) {
|
||||
return new HTTPError(arg.message, arg.httpStatusCode);
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
|
||||
// src/github.ts
|
||||
var GITHUB_DOTCOM_URL = "https://github.com";
|
||||
function parseGitHubUrl(inputUrl) {
|
||||
const originalUrl = inputUrl;
|
||||
if (inputUrl.indexOf("://") === -1) {
|
||||
inputUrl = `https://${inputUrl}`;
|
||||
}
|
||||
if (!inputUrl.startsWith("http://") && !inputUrl.startsWith("https://")) {
|
||||
throw new ConfigurationError(`"${originalUrl}" is not a http or https URL`);
|
||||
}
|
||||
let url2;
|
||||
try {
|
||||
url2 = new URL(inputUrl);
|
||||
} catch {
|
||||
throw new ConfigurationError(`"${originalUrl}" is not a valid URL`);
|
||||
}
|
||||
if (url2.hostname === "github.com" || url2.hostname === "api.github.com") {
|
||||
return GITHUB_DOTCOM_URL;
|
||||
}
|
||||
if (url2.pathname.indexOf("/api/v3") !== -1) {
|
||||
url2.pathname = url2.pathname.substring(0, url2.pathname.indexOf("/api/v3"));
|
||||
}
|
||||
if (url2.hostname.startsWith("api.")) {
|
||||
url2.hostname = url2.hostname.substring(4);
|
||||
}
|
||||
if (!url2.pathname.endsWith("/")) {
|
||||
url2.pathname = `${url2.pathname}/`;
|
||||
}
|
||||
return url2.toString();
|
||||
}
|
||||
function getCurrentInstance(env) {
|
||||
return {
|
||||
url: env.getRequired("GITHUB_SERVER_URL" /* GITHUB_SERVER_URL */),
|
||||
apiURL: env.getRequired("GITHUB_API_URL" /* GITHUB_API_URL */)
|
||||
};
|
||||
}
|
||||
|
||||
// src/util.ts
|
||||
var BASE_DATABASE_OIDS_FILE_NAME = "base-database-oids.json";
|
||||
var BROKEN_VERSIONS = ["0.0.0-20211207"];
|
||||
@@ -169816,37 +169903,6 @@ var ExhaustivityCheckingError = class extends Error {
|
||||
function assertNever(value) {
|
||||
throw new ExhaustivityCheckingError(value);
|
||||
}
|
||||
function initializeEnvironment(version, env = getEnv()) {
|
||||
env.export("CODEQL_ACTION_FEATURE_MULTI_LANGUAGE" /* FEATURE_MULTI_LANGUAGE */, "false");
|
||||
env.export("CODEQL_ACTION_FEATURE_SANDWICH" /* FEATURE_SANDWICH */, "false");
|
||||
env.export("CODEQL_ACTION_FEATURE_SARIF_COMBINE" /* FEATURE_SARIF_COMBINE */, "true");
|
||||
env.export("CODEQL_ACTION_FEATURE_WILL_UPLOAD" /* FEATURE_WILL_UPLOAD */, "true");
|
||||
env.export("CODEQL_ACTION_VERSION" /* VERSION */, version);
|
||||
}
|
||||
var HTTPError = class extends Error {
|
||||
status;
|
||||
constructor(message, status) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
}
|
||||
};
|
||||
var ConfigurationError = class extends Error {
|
||||
};
|
||||
function asHTTPError(arg) {
|
||||
if (!isObject2(arg) || !isString(arg.message)) {
|
||||
return void 0;
|
||||
}
|
||||
if (Number.isInteger(arg.status)) {
|
||||
return new HTTPError(arg.message, arg.status);
|
||||
}
|
||||
if (Number.isInteger(arg.httpStatusCode)) {
|
||||
return new HTTPError(arg.message, arg.httpStatusCode);
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
async function codeQlVersionAtLeast(codeql, requiredVersion) {
|
||||
return semver.gte((await codeql.getVersion()).version, requiredVersion);
|
||||
}
|
||||
function getBaseDatabaseOidsFilePath(config) {
|
||||
return path.join(config.dbLocation, BASE_DATABASE_OIDS_FILE_NAME);
|
||||
}
|
||||
@@ -169981,12 +170037,6 @@ function parseMatrixInput(matrixInput) {
|
||||
);
|
||||
}
|
||||
}
|
||||
function wrapError(error3) {
|
||||
return error3 instanceof Error ? error3 : new Error(String(error3));
|
||||
}
|
||||
function getErrorMessage(error3) {
|
||||
return error3 instanceof Error ? error3.message : String(error3);
|
||||
}
|
||||
function prettyPrintPack(pack) {
|
||||
return `${pack.name}${pack.version ? `@${pack.version}` : ""}${pack.path ? `:${pack.path}` : ""}`;
|
||||
}
|
||||
@@ -170630,43 +170680,6 @@ retry.VERSION = VERSION7;
|
||||
// src/api-client.ts
|
||||
var import_undici = __toESM(require_undici());
|
||||
|
||||
// src/github.ts
|
||||
var GITHUB_DOTCOM_URL = "https://github.com";
|
||||
function parseGitHubUrl(inputUrl) {
|
||||
const originalUrl = inputUrl;
|
||||
if (inputUrl.indexOf("://") === -1) {
|
||||
inputUrl = `https://${inputUrl}`;
|
||||
}
|
||||
if (!inputUrl.startsWith("http://") && !inputUrl.startsWith("https://")) {
|
||||
throw new ConfigurationError(`"${originalUrl}" is not a http or https URL`);
|
||||
}
|
||||
let url2;
|
||||
try {
|
||||
url2 = new URL(inputUrl);
|
||||
} catch {
|
||||
throw new ConfigurationError(`"${originalUrl}" is not a valid URL`);
|
||||
}
|
||||
if (url2.hostname === "github.com" || url2.hostname === "api.github.com") {
|
||||
return GITHUB_DOTCOM_URL;
|
||||
}
|
||||
if (url2.pathname.indexOf("/api/v3") !== -1) {
|
||||
url2.pathname = url2.pathname.substring(0, url2.pathname.indexOf("/api/v3"));
|
||||
}
|
||||
if (url2.hostname.startsWith("api.")) {
|
||||
url2.hostname = url2.hostname.substring(4);
|
||||
}
|
||||
if (!url2.pathname.endsWith("/")) {
|
||||
url2.pathname = `${url2.pathname}/`;
|
||||
}
|
||||
return url2.toString();
|
||||
}
|
||||
function getCurrentInstance(env) {
|
||||
return {
|
||||
url: env.getRequired("GITHUB_SERVER_URL" /* GITHUB_SERVER_URL */),
|
||||
apiURL: env.getRequired("GITHUB_API_URL" /* GITHUB_API_URL */)
|
||||
};
|
||||
}
|
||||
|
||||
// src/repository.ts
|
||||
function isRepositoryNwoStr(val) {
|
||||
return val.includes("/");
|
||||
@@ -171932,11 +171945,6 @@ var featureConfig = {
|
||||
envVar: "CODEQL_ACTION_ALLOW_MULTIPLE_ANALYSIS_KINDS",
|
||||
minimumVersion: void 0
|
||||
},
|
||||
["cleanup_toolcache_bundles" /* CleanupToolcacheBundles */]: {
|
||||
defaultValue: false,
|
||||
envVar: "CODEQL_ACTION_CLEANUP_TOOLCACHE_BUNDLES",
|
||||
minimumVersion: void 0
|
||||
},
|
||||
["cleanup_trap_caches" /* CleanupTrapCaches */]: {
|
||||
defaultValue: false,
|
||||
envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",
|
||||
@@ -172255,7 +172263,7 @@ var OfflineFeatures = class {
|
||||
}
|
||||
const minimumVersion2 = config.minimumVersion;
|
||||
if (codeql && minimumVersion2) {
|
||||
if (!await codeQlVersionAtLeast(codeql, minimumVersion2)) {
|
||||
if (!await codeql.isVersionAtLeast(minimumVersion2)) {
|
||||
this.logger.debug(
|
||||
`Feature ${feature} is disabled because the CodeQL CLI version is older than the minimum version ${minimumVersion2}.`
|
||||
);
|
||||
@@ -172678,6 +172686,7 @@ var fs16 = __toESM(require("fs"));
|
||||
var path15 = __toESM(require("path"));
|
||||
var core12 = __toESM(require_core());
|
||||
var toolrunner3 = __toESM(require_toolrunner());
|
||||
var semver10 = __toESM(require_semver2());
|
||||
|
||||
// src/cli-errors.ts
|
||||
var SUPPORTED_PLATFORMS = [
|
||||
@@ -174666,10 +174675,7 @@ function runnerHasSufficientDiskSpace(diskUsage, logger2, minimumDiskSpaceMb) {
|
||||
return true;
|
||||
}
|
||||
async function runnerHasSufficientMemory(codeql, ramInput, logger2) {
|
||||
if (await codeQlVersionAtLeast(
|
||||
codeql,
|
||||
CODEQL_VERSION_REDUCED_OVERLAY_MEMORY_USAGE
|
||||
)) {
|
||||
if (await codeql.isVersionAtLeast(CODEQL_VERSION_REDUCED_OVERLAY_MEMORY_USAGE)) {
|
||||
logger2.debug(
|
||||
`Skipping memory check for overlay analysis because CodeQL version is at least ${CODEQL_VERSION_REDUCED_OVERLAY_MEMORY_USAGE}.`
|
||||
);
|
||||
@@ -174807,7 +174813,7 @@ async function validateOverlayDatabaseMode(overlayDatabaseMode, useOverlayDataba
|
||||
);
|
||||
return new Failure("incompatible-build-mode" /* IncompatibleBuildMode */);
|
||||
}
|
||||
if (!await codeQlVersionAtLeast(codeql, CODEQL_OVERLAY_MINIMUM_VERSION)) {
|
||||
if (!await codeql.isVersionAtLeast(CODEQL_OVERLAY_MINIMUM_VERSION)) {
|
||||
logger2.warning(
|
||||
`Cannot build an ${overlayDatabaseMode} database because the CodeQL CLI is older than ${CODEQL_OVERLAY_MINIMUM_VERSION}. Falling back to creating a normal full database instead.`
|
||||
);
|
||||
@@ -176729,7 +176735,6 @@ function getToolcacheDestination({ logger: logger2 }, source) {
|
||||
}
|
||||
async function tryDeleteToolcacheBundles({
|
||||
env,
|
||||
features,
|
||||
logger: logger2
|
||||
}) {
|
||||
if (env.getOptional("CODEQL_ACTION_HAS_SET_UP_CODEQL" /* HAS_SET_UP_CODEQL */) !== void 0) {
|
||||
@@ -176738,7 +176743,7 @@ async function tryDeleteToolcacheBundles({
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (!isGitHubHostedRunner() || !isToolcacheOnWorkspaceFilesystem(logger2) || !await features.getValue("cleanup_toolcache_bundles" /* CleanupToolcacheBundles */)) {
|
||||
if (!isGitHubHostedRunner(env) || !isToolcacheOnWorkspaceFilesystem(logger2)) {
|
||||
return;
|
||||
}
|
||||
const result = await deleteToolcacheBundles({ env, logger: logger2 });
|
||||
@@ -176798,7 +176803,7 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau
|
||||
break;
|
||||
case "download": {
|
||||
const result = await downloadCodeQLBundle(
|
||||
{ env: getEnv(), features, logger: logger2 },
|
||||
{ env: getEnv(), logger: logger2 },
|
||||
source,
|
||||
apiDetails,
|
||||
zstdAvailability.version,
|
||||
@@ -177008,16 +177013,6 @@ var CODEQL_NEXT_MINIMUM_VERSION = "2.21.3";
|
||||
var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.17";
|
||||
var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-09-24";
|
||||
var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++";
|
||||
function isDiskConfigurationError(e) {
|
||||
if (!(e instanceof Error)) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
// out of disk space
|
||||
e.message.includes("ENOSPC") || // access denied
|
||||
e.message.includes("EACCES")
|
||||
);
|
||||
}
|
||||
async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, otherLanguagePacksReason, useOverlayAwareDefaultCliVersion, features, logger2, checkVersion) {
|
||||
try {
|
||||
const {
|
||||
@@ -177092,6 +177087,9 @@ async function getCodeQLForCmd(logger2, cmd, checkVersion) {
|
||||
}
|
||||
return result;
|
||||
},
|
||||
async isVersionAtLeast(requiredVersion) {
|
||||
return semver10.gte((await this.getVersion()).version, requiredVersion);
|
||||
},
|
||||
async printVersion() {
|
||||
core12.info(JSON.stringify(await this.getVersion(), null, 2));
|
||||
},
|
||||
@@ -177480,11 +177478,11 @@ Output was: ${extractorPath}`
|
||||
await runCli(cmd, args);
|
||||
}
|
||||
};
|
||||
if (checkVersion && !await codeQlVersionAtLeast(codeql, CODEQL_MINIMUM_VERSION)) {
|
||||
if (checkVersion && !await codeql.isVersionAtLeast(CODEQL_MINIMUM_VERSION)) {
|
||||
throw new ConfigurationError(
|
||||
`Expected a CodeQL CLI with version at least ${CODEQL_MINIMUM_VERSION} but got version ${(await codeql.getVersion()).version}`
|
||||
);
|
||||
} else if (checkVersion && process.env["CODEQL_ACTION_SUPPRESS_DEPRECATED_SOON_WARNING" /* SUPPRESS_DEPRECATED_SOON_WARNING */] !== "true" && !await codeQlVersionAtLeast(codeql, CODEQL_NEXT_MINIMUM_VERSION)) {
|
||||
} else if (checkVersion && process.env["CODEQL_ACTION_SUPPRESS_DEPRECATED_SOON_WARNING" /* SUPPRESS_DEPRECATED_SOON_WARNING */] !== "true" && !await codeql.isVersionAtLeast(CODEQL_NEXT_MINIMUM_VERSION)) {
|
||||
const result = await codeql.getVersion();
|
||||
core12.warning(
|
||||
`CodeQL CLI version ${result.version} was discontinued on ${GHES_MOST_RECENT_DEPRECATION_DATE} alongside GitHub Enterprise Server ${GHES_VERSION_MOST_RECENTLY_DEPRECATED} and will not be supported by the next minor release of the CodeQL Action. Please update to CodeQL CLI version ${CODEQL_NEXT_MINIMUM_VERSION} or later. For instance, if you have specified a custom version of the CLI using the 'tools' input to the 'init' Action, you can remove this input to use the default version.
|
||||
@@ -180765,7 +180763,7 @@ async function run(action) {
|
||||
let dependencyCacheResults;
|
||||
let databaseUploadResults = [];
|
||||
try {
|
||||
initializeEnvironment(getActionVersion());
|
||||
action.env.initialise(getActionVersion());
|
||||
persistInputs();
|
||||
const statusReportBase = await createStatusReportBase(
|
||||
"finish" /* Analyze */,
|
||||
@@ -183096,7 +183094,7 @@ var import_async = __toESM(require_async(), 1);
|
||||
var import_path7 = require("path");
|
||||
|
||||
// node_modules/archiver/lib/error.js
|
||||
var import_util37 = __toESM(require("util"), 1);
|
||||
var import_util36 = __toESM(require("util"), 1);
|
||||
var ERROR_CODES = {
|
||||
ABORTED: "archive was aborted",
|
||||
DIRECTORYDIRPATHREQUIRED: "diretory dirpath argument must be a non-empty string value",
|
||||
@@ -183121,7 +183119,7 @@ function ArchiverError(code, data) {
|
||||
this.code = code;
|
||||
this.data = data;
|
||||
}
|
||||
import_util37.default.inherits(ArchiverError, Error);
|
||||
import_util36.default.inherits(ArchiverError, Error);
|
||||
|
||||
// node_modules/archiver/lib/core.js
|
||||
var import_readable_stream2 = __toESM(require_ours(), 1);
|
||||
@@ -185944,8 +185942,8 @@ async function runWrapper2() {
|
||||
|
||||
// src/autobuild-action.ts
|
||||
var core17 = __toESM(require_core());
|
||||
async function sendCompletedStatusReport(config, logger2, startedAt, allLanguages, failingLanguage, cause) {
|
||||
initializeEnvironment(getActionVersion());
|
||||
async function sendCompletedStatusReport(env, config, logger2, startedAt, allLanguages, failingLanguage, cause) {
|
||||
env.initialise(getActionVersion());
|
||||
const status = getActionsStatus(cause, failingLanguage);
|
||||
const statusReportBase = await createStatusReportBase(
|
||||
"autobuild" /* Autobuild */,
|
||||
@@ -186017,6 +186015,7 @@ async function run2({
|
||||
`We were unable to automatically build your code. Please replace the call to the autobuild action with your custom build steps. ${error3.message}`
|
||||
);
|
||||
await sendCompletedStatusReport(
|
||||
env,
|
||||
config,
|
||||
logger2,
|
||||
startedAt,
|
||||
@@ -186027,7 +186026,13 @@ async function run2({
|
||||
return;
|
||||
}
|
||||
env.export("CODEQL_ACTION_AUTOBUILD_DID_COMPLETE_SUCCESSFULLY" /* AUTOBUILD_DID_COMPLETE_SUCCESSFULLY */, "true");
|
||||
await sendCompletedStatusReport(config, logger2, startedAt, languages ?? []);
|
||||
await sendCompletedStatusReport(
|
||||
env,
|
||||
config,
|
||||
logger2,
|
||||
startedAt,
|
||||
languages ?? []
|
||||
);
|
||||
}
|
||||
var autobuild = {
|
||||
name: "autobuild" /* Autobuild */,
|
||||
@@ -186042,7 +186047,7 @@ var fs29 = __toESM(require("fs"));
|
||||
var path25 = __toESM(require("path"));
|
||||
var core19 = __toESM(require_core());
|
||||
var io7 = __toESM(require_io());
|
||||
var semver10 = __toESM(require_semver2());
|
||||
var semver11 = __toESM(require_semver2());
|
||||
|
||||
// src/config/inputs.ts
|
||||
async function getToolsInput(action, repositoryProperties) {
|
||||
@@ -186455,7 +186460,7 @@ async function run3(actionState) {
|
||||
let toolsSource;
|
||||
let toolsVersion;
|
||||
try {
|
||||
initializeEnvironment(getActionVersion());
|
||||
actionState.env.initialise(getActionVersion());
|
||||
persistInputs();
|
||||
apiDetails = {
|
||||
auth: getRequiredInput("token"),
|
||||
@@ -186552,7 +186557,7 @@ async function run3(actionState) {
|
||||
) {
|
||||
const publicPreview = "2.22.1";
|
||||
const actualVer = (await codeql.getVersion()).version;
|
||||
if (semver10.lt(actualVer, publicPreview)) {
|
||||
if (semver11.lt(actualVer, publicPreview)) {
|
||||
actionState.env.export("CODEQL_ENABLE_EXPERIMENTAL_FEATURES" /* EXPERIMENTAL_FEATURES */, "true");
|
||||
logger2.info("Experimental Rust analysis enabled");
|
||||
}
|
||||
@@ -186785,7 +186790,7 @@ exec ${goBinaryPath} "$@"`
|
||||
logger2.debug(
|
||||
`${"CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS" /* JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS */} is already set to '${process.env["CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS" /* JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS */]}', so the Action will not override it.`
|
||||
);
|
||||
} else if (await codeQlVersionAtLeast(codeql, CODEQL_VERSION_JAR_MINIMIZATION) && config.dependencyCachingEnabled && config.buildMode === "none" /* None */ && config.languages.includes("java" /* java */)) {
|
||||
} else if (await codeql.isVersionAtLeast(CODEQL_VERSION_JAR_MINIMIZATION) && config.dependencyCachingEnabled && config.buildMode === "none" /* None */ && config.languages.includes("java" /* java */)) {
|
||||
actionState.env.export(
|
||||
"CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS" /* JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS */,
|
||||
"true"
|
||||
@@ -187498,7 +187503,7 @@ async function run6(actionState) {
|
||||
let toolsSource;
|
||||
let toolsVersion;
|
||||
try {
|
||||
initializeEnvironment(getActionVersion());
|
||||
actionState.env.initialise(getActionVersion());
|
||||
const apiDetails = {
|
||||
auth: getRequiredInput("token"),
|
||||
externalRepoAuth: getOptionalInput("external-repository-token"),
|
||||
@@ -188450,9 +188455,10 @@ async function sendSuccessStatusReport2(startedAt, uploadStats, logger2) {
|
||||
await sendStatusReport(statusReport);
|
||||
}
|
||||
}
|
||||
async function run8({ startedAt, logger: logger2 }) {
|
||||
async function run8(action) {
|
||||
const logger2 = action.logger;
|
||||
try {
|
||||
initializeEnvironment(getActionVersion());
|
||||
action.env.initialise(getActionVersion());
|
||||
const gitHubVersion = await getGitHubVersion();
|
||||
checkActionVersion(getActionVersion(), gitHubVersion);
|
||||
persistInputs();
|
||||
@@ -188466,7 +188472,7 @@ async function run8({ startedAt, logger: logger2 }) {
|
||||
const startingStatusReportBase = await createStatusReportBase(
|
||||
"upload-sarif" /* UploadSarif */,
|
||||
"starting",
|
||||
startedAt,
|
||||
action.startedAt,
|
||||
void 0,
|
||||
await checkDiskUsage(logger2),
|
||||
logger2
|
||||
@@ -188509,7 +188515,7 @@ async function run8({ startedAt, logger: logger2 }) {
|
||||
}
|
||||
}
|
||||
await sendSuccessStatusReport2(
|
||||
startedAt,
|
||||
action.startedAt,
|
||||
codeScanningResult?.statusReport || {},
|
||||
logger2
|
||||
);
|
||||
@@ -188520,7 +188526,7 @@ async function run8({ startedAt, logger: logger2 }) {
|
||||
const errorStatusReportBase = await createStatusReportBase(
|
||||
"upload-sarif" /* UploadSarif */,
|
||||
getActionsStatus(error3),
|
||||
startedAt,
|
||||
action.startedAt,
|
||||
void 0,
|
||||
await checkDiskUsage(logger2),
|
||||
logger2,
|
||||
|
||||
@@ -14,7 +14,6 @@ operatingSystems:
|
||||
- stable-v2.21.4
|
||||
- stable-v2.22.4
|
||||
env:
|
||||
CODEQL_ACTION_CLEANUP_TOOLCACHE_BUNDLES: true
|
||||
CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI: true
|
||||
installGo: true
|
||||
installDotNet: true
|
||||
|
||||
@@ -12,8 +12,8 @@ import {
|
||||
import { computeAutomationID } from "./api-client";
|
||||
import { EnvVar } from "./environment";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import { RecordingLogger, setupTests } from "./testing-utils";
|
||||
import { initializeEnvironment, withTmpDir } from "./util";
|
||||
import { getTestEnv, RecordingLogger, setupTests } from "./testing-utils";
|
||||
import { withTmpDir } from "./util";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
@@ -228,8 +228,9 @@ test.serial(
|
||||
);
|
||||
|
||||
test.serial("initializeEnvironment", (t) => {
|
||||
initializeEnvironment("1.2.3");
|
||||
t.deepEqual(process.env[EnvVar.VERSION], "1.2.3");
|
||||
const env = getTestEnv();
|
||||
env.initialise("1.2.3");
|
||||
t.deepEqual(env.getOptional(EnvVar.VERSION), "1.2.3");
|
||||
});
|
||||
|
||||
test.serial("fixCodeQualityCategory", (t) => {
|
||||
|
||||
@@ -238,7 +238,7 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) {
|
||||
let databaseUploadResults: DatabaseUploadResult[] = [];
|
||||
|
||||
try {
|
||||
util.initializeEnvironment(actionsUtil.getActionVersion());
|
||||
action.env.initialise(actionsUtil.getActionVersion());
|
||||
|
||||
// Make inputs accessible in the `post` step, details at
|
||||
// https://github.com/github/codeql-action/issues/2553
|
||||
|
||||
@@ -7,7 +7,7 @@ import { ProxyAgent } from "undici";
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import * as api from "./api-client";
|
||||
import { DO_NOT_RETRY_STATUSES } from "./api-client";
|
||||
import { ActionsEnvVars, RegistryProxyVars } from "./environment";
|
||||
import { ActionsEnvVars, RegistryProxyVars, getEnv } from "./environment";
|
||||
import { GITHUB_DOTCOM_API_URL, GITHUB_DOTCOM_URL } from "./github";
|
||||
import {
|
||||
callee,
|
||||
@@ -21,7 +21,7 @@ import * as util from "./util";
|
||||
setupTests(test);
|
||||
|
||||
test.beforeEach(() => {
|
||||
util.initializeEnvironment(actionsUtil.getActionVersion());
|
||||
getEnv().initialise(actionsUtil.getActionVersion());
|
||||
});
|
||||
|
||||
test.serial("getApiClient", async (t) => {
|
||||
|
||||
@@ -10,7 +10,7 @@ import { getGitHubVersion } from "./api-client";
|
||||
import { determineAutobuildLanguages, runAutobuild } from "./autobuild";
|
||||
import { getCodeQL } from "./codeql";
|
||||
import { Config, getConfig } from "./config-utils";
|
||||
import { EnvVar } from "./environment";
|
||||
import { EnvVar, type Env } from "./environment";
|
||||
import { Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import {
|
||||
@@ -26,7 +26,6 @@ import {
|
||||
checkDiskUsage,
|
||||
checkGitHubVersionInRange,
|
||||
ConfigurationError,
|
||||
initializeEnvironment,
|
||||
wrapError,
|
||||
} from "./util";
|
||||
|
||||
@@ -38,6 +37,7 @@ interface AutobuildStatusReport extends StatusReportBase {
|
||||
}
|
||||
|
||||
async function sendCompletedStatusReport(
|
||||
env: Env,
|
||||
config: Config | undefined,
|
||||
logger: Logger,
|
||||
startedAt: Date,
|
||||
@@ -45,7 +45,7 @@ async function sendCompletedStatusReport(
|
||||
failingLanguage?: string,
|
||||
cause?: Error,
|
||||
) {
|
||||
initializeEnvironment(getActionVersion());
|
||||
env.initialise(getActionVersion());
|
||||
|
||||
const status = getActionsStatus(cause, failingLanguage);
|
||||
const statusReportBase = await createStatusReportBase(
|
||||
@@ -129,6 +129,7 @@ async function run({
|
||||
`We were unable to automatically build your code. Please replace the call to the autobuild action with your custom build steps. ${error.message}`,
|
||||
);
|
||||
await sendCompletedStatusReport(
|
||||
env,
|
||||
config,
|
||||
logger,
|
||||
startedAt,
|
||||
@@ -141,7 +142,13 @@ async function run({
|
||||
|
||||
env.export(EnvVar.AUTOBUILD_DID_COMPLETE_SUCCESSFULLY, "true");
|
||||
|
||||
await sendCompletedStatusReport(config, logger, startedAt, languages ?? []);
|
||||
await sendCompletedStatusReport(
|
||||
env,
|
||||
config,
|
||||
logger,
|
||||
startedAt,
|
||||
languages ?? [],
|
||||
);
|
||||
}
|
||||
|
||||
/** Defines the `autobuild` Action. */
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
import type { Config } from "./config-utils";
|
||||
import * as defaults from "./defaults.json";
|
||||
import { DocUrl } from "./doc-url";
|
||||
import { getEnv } from "./environment";
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import { ToolsSource } from "./setup-codeql";
|
||||
@@ -37,14 +38,13 @@ import {
|
||||
} from "./testing-utils";
|
||||
import { ToolsDownloadStatusReport } from "./tools-download";
|
||||
import * as util from "./util";
|
||||
import { initializeEnvironment } from "./util";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
let stubConfig: Config;
|
||||
|
||||
test.beforeEach(() => {
|
||||
initializeEnvironment("1.2.3");
|
||||
getEnv().initialise("1.2.3");
|
||||
|
||||
stubConfig = createTestConfig({
|
||||
languages: [BuiltInLanguage.cpp],
|
||||
|
||||
@@ -4,6 +4,7 @@ import * as path from "path";
|
||||
import * as core from "@actions/core";
|
||||
import * as toolrunner from "@actions/exec/lib/toolrunner";
|
||||
import * as yaml from "js-yaml";
|
||||
import * as semver from "semver";
|
||||
|
||||
import {
|
||||
CommandInvocationError,
|
||||
@@ -19,6 +20,7 @@ import type { ActionConfig } from "./config/action-config";
|
||||
import { appendExtraQueryExclusions, type Config } from "./config-utils";
|
||||
import { DocUrl } from "./doc-url";
|
||||
import { EnvVar, getEnv, exportEnvVar } from "./environment";
|
||||
import { getErrorMessage, isDiskConfigurationError } from "./errors";
|
||||
import {
|
||||
CodeQLDefaultVersionInfo,
|
||||
Feature,
|
||||
@@ -34,7 +36,9 @@ import { ToolsDownloadStatusReport } from "./tools-download";
|
||||
import { ToolsFeature, isSupportedToolsFeature } from "./tools-features";
|
||||
import { shouldEnableIndirectTracing } from "./tracer-config";
|
||||
import * as util from "./util";
|
||||
import { BuildMode, CleanupLevel, getErrorMessage } from "./util";
|
||||
import { BuildMode, CleanupLevel } from "./util";
|
||||
|
||||
export { isDiskConfigurationError } from "./errors";
|
||||
|
||||
type Options = Array<string | number | boolean>;
|
||||
|
||||
@@ -70,6 +74,11 @@ export interface CodeQL {
|
||||
* Get a string containing the semver version of the CodeQL executable.
|
||||
*/
|
||||
getVersion(): Promise<VersionInfo>;
|
||||
/**
|
||||
* Determines whether the CLI installation represented by this {@link CodeQL} instance
|
||||
* has at least the {@link requiredVersion}.
|
||||
*/
|
||||
isVersionAtLeast(requiredVersion: string): Promise<boolean>;
|
||||
/**
|
||||
* Print version information about CodeQL.
|
||||
*/
|
||||
@@ -274,26 +283,6 @@ const GHES_MOST_RECENT_DEPRECATION_DATE = "2026-09-24";
|
||||
/** The CLI verbosity level to use for extraction in debug mode. */
|
||||
const EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++";
|
||||
|
||||
/**
|
||||
* Decides whether `e` is a disk-related error outside of our control
|
||||
* that should be classified as a `ConfigurationError`.
|
||||
*
|
||||
* @param e The error to check.
|
||||
* @returns True if the error should be treated as a `ConfigurationError` or false if not.
|
||||
*/
|
||||
export function isDiskConfigurationError(e: unknown): boolean {
|
||||
if (!(e instanceof Error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
// out of disk space
|
||||
e.message.includes("ENOSPC") ||
|
||||
// access denied
|
||||
e.message.includes("EACCES")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up CodeQL CLI access.
|
||||
*
|
||||
@@ -402,9 +391,9 @@ export function setCodeQL(codeql: Partial<CodeQL>): void {
|
||||
cachedCodeQL = createStubCodeQL(codeql);
|
||||
}
|
||||
|
||||
function resolveFunction<T>(
|
||||
function resolveFunction<K extends keyof CodeQL, T extends CodeQL[K]>(
|
||||
partialCodeql: Partial<CodeQL>,
|
||||
methodName: string,
|
||||
methodName: K,
|
||||
defaultImplementation?: T,
|
||||
): T {
|
||||
if (typeof partialCodeql[methodName] !== "function") {
|
||||
@@ -414,7 +403,7 @@ function resolveFunction<T>(
|
||||
const dummyMethod = () => {
|
||||
throw new Error(`CodeQL ${methodName} method not correctly defined`);
|
||||
};
|
||||
return dummyMethod as T;
|
||||
return dummyMethod as unknown as T;
|
||||
}
|
||||
return partialCodeql[methodName] as T;
|
||||
}
|
||||
@@ -431,6 +420,19 @@ export function createStubCodeQL(partialCodeql: Partial<CodeQL>): CodeQL {
|
||||
getVersion: resolveFunction(partialCodeql, "getVersion", async () => ({
|
||||
version: "1.0.0",
|
||||
})),
|
||||
isVersionAtLeast: resolveFunction(
|
||||
partialCodeql,
|
||||
"isVersionAtLeast",
|
||||
async (requiredVersion) => {
|
||||
return (
|
||||
!!partialCodeql.getVersion &&
|
||||
semver.gte(
|
||||
(await partialCodeql.getVersion()).version,
|
||||
requiredVersion,
|
||||
)
|
||||
);
|
||||
},
|
||||
),
|
||||
printVersion: resolveFunction(partialCodeql, "printVersion"),
|
||||
supportsFeature: resolveFunction(
|
||||
partialCodeql,
|
||||
@@ -534,6 +536,9 @@ async function getCodeQLForCmd(
|
||||
}
|
||||
return result;
|
||||
},
|
||||
async isVersionAtLeast(requiredVersion: string) {
|
||||
return semver.gte((await this.getVersion()).version, requiredVersion);
|
||||
},
|
||||
async printVersion() {
|
||||
// Reuse the cached version information rather than invoking the CLI again.
|
||||
core.info(JSON.stringify(await this.getVersion(), null, 2));
|
||||
@@ -1028,7 +1033,7 @@ async function getCodeQLForCmd(
|
||||
// CodeQL object is created.
|
||||
if (
|
||||
checkVersion &&
|
||||
!(await util.codeQlVersionAtLeast(codeql, CODEQL_MINIMUM_VERSION))
|
||||
!(await codeql.isVersionAtLeast(CODEQL_MINIMUM_VERSION))
|
||||
) {
|
||||
throw new util.ConfigurationError(
|
||||
`Expected a CodeQL CLI with version at least ${CODEQL_MINIMUM_VERSION} but got version ${
|
||||
@@ -1038,7 +1043,7 @@ async function getCodeQLForCmd(
|
||||
} else if (
|
||||
checkVersion &&
|
||||
process.env[EnvVar.SUPPRESS_DEPRECATED_SOON_WARNING] !== "true" &&
|
||||
!(await util.codeQlVersionAtLeast(codeql, CODEQL_NEXT_MINIMUM_VERSION))
|
||||
!(await codeql.isVersionAtLeast(CODEQL_NEXT_MINIMUM_VERSION))
|
||||
) {
|
||||
const result = await codeql.getVersion();
|
||||
core.warning(
|
||||
|
||||
@@ -82,7 +82,6 @@ import {
|
||||
GitHubVersion,
|
||||
ConfigurationError,
|
||||
BuildMode,
|
||||
codeQlVersionAtLeast,
|
||||
cloneObject,
|
||||
isDefined,
|
||||
checkDiskUsage,
|
||||
@@ -652,10 +651,7 @@ async function runnerHasSufficientMemory(
|
||||
logger: Logger,
|
||||
): Promise<boolean> {
|
||||
if (
|
||||
await codeQlVersionAtLeast(
|
||||
codeql,
|
||||
CODEQL_VERSION_REDUCED_OVERLAY_MEMORY_USAGE,
|
||||
)
|
||||
await codeql.isVersionAtLeast(CODEQL_VERSION_REDUCED_OVERLAY_MEMORY_USAGE)
|
||||
) {
|
||||
logger.debug(
|
||||
`Skipping memory check for overlay analysis because CodeQL version is at least ${CODEQL_VERSION_REDUCED_OVERLAY_MEMORY_USAGE}.`,
|
||||
@@ -899,7 +895,7 @@ async function validateOverlayDatabaseMode(
|
||||
);
|
||||
return new Failure(OverlayDisabledReason.IncompatibleBuildMode);
|
||||
}
|
||||
if (!(await codeQlVersionAtLeast(codeql, CODEQL_OVERLAY_MINIMUM_VERSION))) {
|
||||
if (!(await codeql.isVersionAtLeast(CODEQL_OVERLAY_MINIMUM_VERSION))) {
|
||||
logger.warning(
|
||||
`Cannot build an ${overlayDatabaseMode} database because ` +
|
||||
`the CodeQL CLI is older than ${CODEQL_OVERLAY_MINIMUM_VERSION}. ` +
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
cleanupAndUploadDatabases,
|
||||
uploadBundledDatabase,
|
||||
} from "./database-upload";
|
||||
import { getEnv } from "./environment";
|
||||
import { Feature } from "./feature-flags";
|
||||
import * as gitUtils from "./git-utils";
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
@@ -31,18 +32,12 @@ import {
|
||||
setupActionsVars,
|
||||
setupTests,
|
||||
} from "./testing-utils";
|
||||
import {
|
||||
CleanupLevel,
|
||||
GitHubVariant,
|
||||
HTTPError,
|
||||
initializeEnvironment,
|
||||
withTmpDir,
|
||||
} from "./util";
|
||||
import { CleanupLevel, GitHubVariant, HTTPError, withTmpDir } from "./util";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
test.beforeEach(() => {
|
||||
initializeEnvironment("1.2.3");
|
||||
getEnv().initialise("1.2.3");
|
||||
});
|
||||
|
||||
const testRepoName: RepositoryNwo = { owner: "github", repo: "example" };
|
||||
|
||||
@@ -281,8 +281,8 @@ export function getOptionalEnvVar(paramName: string): string | undefined {
|
||||
* in tests, while clearly signalling in regular code that the consumer of the `ReadOnlyEnv` instance
|
||||
* will only read from it.
|
||||
*/
|
||||
export class ReadOnlyEnv<T extends string | undefined = string | undefined> {
|
||||
constructor(protected readonly vars: Record<string, T>) {}
|
||||
export class ReadOnlyEnv {
|
||||
constructor(protected readonly vars: Record<string, string | undefined>) {}
|
||||
|
||||
/** Clones the object while detaching the underlying environment from the original. */
|
||||
public clone(): this {
|
||||
@@ -290,7 +290,7 @@ export class ReadOnlyEnv<T extends string | undefined = string | undefined> {
|
||||
}
|
||||
|
||||
/** Gets a copy of the underlying environment. */
|
||||
public get(): Record<string, T> {
|
||||
public get(): Record<string, string | undefined> {
|
||||
return { ...this.vars };
|
||||
}
|
||||
|
||||
@@ -305,7 +305,7 @@ export class ReadOnlyEnv<T extends string | undefined = string | undefined> {
|
||||
}
|
||||
|
||||
/** Gets the entries of the underlying `ProcessEnv`. */
|
||||
public entries(): Array<[string, T]> {
|
||||
public entries(): Array<[string, string | undefined]> {
|
||||
return Object.entries(this.vars);
|
||||
}
|
||||
|
||||
@@ -335,19 +335,17 @@ export class ReadOnlyEnv<T extends string | undefined = string | undefined> {
|
||||
* Use `ReadOnlyEnv` instead if you only plan to read from the environment.
|
||||
* This type allows writing to the environment.
|
||||
*/
|
||||
export class Env<
|
||||
T extends string | undefined = string | undefined,
|
||||
> extends ReadOnlyEnv<T> {
|
||||
export class Env extends ReadOnlyEnv {
|
||||
private changed: boolean = false;
|
||||
|
||||
/** Sets an environment variable. */
|
||||
public set(name: string, value: T): void {
|
||||
public set(name: string, value: string): void {
|
||||
this.vars[name] = value;
|
||||
this.changed = true;
|
||||
}
|
||||
|
||||
/** Sets all environment variables given by `vars`. */
|
||||
public setAll(vars: Record<string, T>): void {
|
||||
public setAll(vars: Record<string, string>): void {
|
||||
for (const [key, val] of Object.entries(vars)) {
|
||||
this.set(key, val);
|
||||
}
|
||||
@@ -361,7 +359,7 @@ export class Env<
|
||||
* @param name The name of the environment variable to set and export.
|
||||
* @param val The value to set and export for the environment variable.
|
||||
*/
|
||||
public export(name: string, val: T): void {
|
||||
public export(name: string, val: string): void {
|
||||
// Setting the environment variable for this instance is always OK, including
|
||||
// in tests, since we use fresh `Env` instances whenever needed. This allows
|
||||
// tests to pass that rely on that part of the `core.exportVariable` behaviour.
|
||||
@@ -373,6 +371,18 @@ export class Env<
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set some initial environment variables that we can set even without
|
||||
* knowing what version of CodeQL we're running.
|
||||
*/
|
||||
public initialise(version: string) {
|
||||
this.export(EnvVar.FEATURE_MULTI_LANGUAGE, "false");
|
||||
this.export(EnvVar.FEATURE_SANDWICH, "false");
|
||||
this.export(EnvVar.FEATURE_SARIF_COMBINE, "true");
|
||||
this.export(EnvVar.FEATURE_WILL_UPLOAD, "true");
|
||||
this.export(EnvVar.VERSION, version);
|
||||
}
|
||||
|
||||
/** Gets a value indicating whether `set` was called at least once. */
|
||||
public hasChanged(): boolean {
|
||||
return this.changed;
|
||||
|
||||
73
src/errors/index.ts
Normal file
73
src/errors/index.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import * as json from "../json";
|
||||
|
||||
/**
|
||||
* If {@link error} is not already an instance of {@link Error}, then this function constructs
|
||||
* an {@link Error} with a string representation of {@link error} as the message.
|
||||
*/
|
||||
export function wrapError(error: unknown): Error {
|
||||
return error instanceof Error ? error : new Error(String(error));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an appropriate message for the error.
|
||||
*
|
||||
* If the error is an {@link Error} instance, this returns the error message without
|
||||
* an `Error: ` prefix.
|
||||
*/
|
||||
export function getErrorMessage(error: unknown): string {
|
||||
return error instanceof Error ? error.message : String(error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides whether `e` is a disk-related error outside of our control
|
||||
* that should be classified as a `ConfigurationError`.
|
||||
*
|
||||
* @param e The error to check.
|
||||
* @returns True if the error should be treated as a `ConfigurationError` or false if not.
|
||||
*/
|
||||
export function isDiskConfigurationError(e: unknown): boolean {
|
||||
if (!(e instanceof Error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
// out of disk space
|
||||
e.message.includes("ENOSPC") ||
|
||||
// access denied
|
||||
e.message.includes("EACCES")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* An Error class that indicates an error that occurred due to
|
||||
* a misconfiguration of the action or the CodeQL CLI.
|
||||
*/
|
||||
export class ConfigurationError extends Error {}
|
||||
|
||||
/** Minimal representation of errors resulting from HTTP requests. */
|
||||
export class HTTPError extends Error {
|
||||
public status: number;
|
||||
|
||||
constructor(message: string, status: number) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to convert {@link arg} to a {@link HTTPError}, but returns `undefined` if
|
||||
* {@link arg} is not like a {@link HTTPError}.
|
||||
*/
|
||||
export function asHTTPError(arg: any): HTTPError | undefined {
|
||||
if (!json.isObject<any>(arg) || !json.isString(arg.message)) {
|
||||
return undefined;
|
||||
}
|
||||
if (Number.isInteger(arg.status)) {
|
||||
return new HTTPError(arg.message, arg.status as number);
|
||||
}
|
||||
// See https://github.com/actions/toolkit/blob/acb230b99a46ed33a3f04a758cd68b47b9a82908/packages/tool-cache/src/tool-cache.ts#L19
|
||||
if (Number.isInteger(arg.httpStatusCode)) {
|
||||
return new HTTPError(arg.message, arg.httpStatusCode as number);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import * as path from "path";
|
||||
import test from "ava";
|
||||
|
||||
import * as defaults from "./defaults.json";
|
||||
import { getEnv } from "./environment";
|
||||
import {
|
||||
Feature,
|
||||
featureConfig,
|
||||
@@ -26,12 +27,12 @@ import {
|
||||
setupTests,
|
||||
stubFeatureFlagApiEndpoint,
|
||||
} from "./testing-utils";
|
||||
import { GitHubVariant, initializeEnvironment, withTmpDir } from "./util";
|
||||
import { GitHubVariant, withTmpDir } from "./util";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
test.beforeEach(() => {
|
||||
initializeEnvironment("1.2.3");
|
||||
getEnv().initialise("1.2.3");
|
||||
});
|
||||
|
||||
test.serial(
|
||||
|
||||
@@ -74,11 +74,6 @@ export enum Feature {
|
||||
AllowMergeConfigFiles = "allow_merge_config_files",
|
||||
/** Controls whether we allow multiple values for the `analysis-kinds` input. */
|
||||
AllowMultipleAnalysisKinds = "allow_multiple_analysis_kinds",
|
||||
/**
|
||||
* Controls whether we delete CodeQL bundles that we are not going to use from the toolcache
|
||||
* before downloading a different bundle, in order to reclaim disk space.
|
||||
*/
|
||||
CleanupToolcacheBundles = "cleanup_toolcache_bundles",
|
||||
CleanupTrapCaches = "cleanup_trap_caches",
|
||||
/** Whether to allow the `config-file` input to be specified via a repository property. */
|
||||
ConfigFileRepositoryProperty = "config_file_repository_property",
|
||||
@@ -221,11 +216,6 @@ export const featureConfig = {
|
||||
envVar: "CODEQL_ACTION_ALLOW_MULTIPLE_ANALYSIS_KINDS",
|
||||
minimumVersion: undefined,
|
||||
},
|
||||
[Feature.CleanupToolcacheBundles]: {
|
||||
defaultValue: false,
|
||||
envVar: "CODEQL_ACTION_CLEANUP_TOOLCACHE_BUNDLES",
|
||||
minimumVersion: undefined,
|
||||
},
|
||||
[Feature.CleanupTrapCaches]: {
|
||||
defaultValue: false,
|
||||
envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",
|
||||
@@ -599,7 +589,7 @@ class OfflineFeatures implements FeatureEnablement {
|
||||
// Never use this feature if the CLI version explicitly can't support it.
|
||||
const minimumVersion = config.minimumVersion;
|
||||
if (codeql && minimumVersion) {
|
||||
if (!(await util.codeQlVersionAtLeast(codeql, minimumVersion))) {
|
||||
if (!(await codeql.isVersionAtLeast(minimumVersion))) {
|
||||
this.logger.debug(
|
||||
`Feature ${feature} is disabled because the CodeQL CLI version is older than the minimum ` +
|
||||
`version ${minimumVersion}.`,
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
LoggedMessage,
|
||||
setupTests,
|
||||
} from "../testing-utils";
|
||||
import { GitHubVariant, initializeEnvironment, withTmpDir } from "../util";
|
||||
import { getEnv, GitHubVariant, withTmpDir } from "../util";
|
||||
|
||||
import {
|
||||
assertAllFeaturesHaveDefaultValues,
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
setupTests(test);
|
||||
|
||||
test.beforeEach(() => {
|
||||
initializeEnvironment("1.2.3");
|
||||
getEnv().initialise("1.2.3");
|
||||
});
|
||||
|
||||
test("OfflineFeatures makes no API requests", async (t) => {
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
import { ActionsEnvVars, type ReadOnlyEnv } from "./environment";
|
||||
import { ConfigurationError } from "./util";
|
||||
import { ConfigurationError } from "./errors";
|
||||
|
||||
export enum GitHubVariant {
|
||||
/** [GitHub.com](https://github.com) */
|
||||
DOTCOM = "GitHub.com",
|
||||
/** [GitHub Enterprise Server](https://docs.github.com/en/enterprise-server@latest/admin/overview/about-github-enterprise-server) */
|
||||
GHES = "GitHub Enterprise Server",
|
||||
/** [GitHub Enterprise Cloud with data residency](https://docs.github.com/en/enterprise-cloud@latest/admin/data-residency/about-github-enterprise-cloud-with-data-residency) */
|
||||
GHEC_DR = "GitHub Enterprise Cloud with data residency",
|
||||
}
|
||||
|
||||
export type GitHubVersion =
|
||||
| { type: GitHubVariant.DOTCOM }
|
||||
| { type: GitHubVariant.GHEC_DR }
|
||||
| { type: GitHubVariant.GHES; version: string };
|
||||
|
||||
/** A string representing a GitHub instance address. */
|
||||
export type InstanceURL = string;
|
||||
|
||||
@@ -88,12 +88,10 @@ import {
|
||||
checkDiskUsage,
|
||||
checkForTimeout,
|
||||
checkGitHubVersionInRange,
|
||||
codeQlVersionAtLeast,
|
||||
DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||
DEFAULT_DEBUG_DATABASE_NAME,
|
||||
getCodeQLMemoryLimit,
|
||||
getThreadsFlagValue,
|
||||
initializeEnvironment,
|
||||
ConfigurationError,
|
||||
wrapError,
|
||||
checkActionVersion,
|
||||
@@ -226,7 +224,7 @@ async function run(
|
||||
let toolsVersion: string;
|
||||
|
||||
try {
|
||||
initializeEnvironment(getActionVersion());
|
||||
actionState.env.initialise(getActionVersion());
|
||||
|
||||
// Make inputs accessible in the `post` step.
|
||||
persistInputs();
|
||||
@@ -686,7 +684,7 @@ async function run(
|
||||
`${EnvVar.JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS} is already set to '${process.env[EnvVar.JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS]}', so the Action will not override it.`,
|
||||
);
|
||||
} else if (
|
||||
(await codeQlVersionAtLeast(codeql, CODEQL_VERSION_JAR_MINIMIZATION)) &&
|
||||
(await codeql.isVersionAtLeast(CODEQL_VERSION_JAR_MINIMIZATION)) &&
|
||||
config.dependencyCachingEnabled &&
|
||||
config.buildMode === BuildMode.None &&
|
||||
config.languages.includes(BuiltInLanguage.java)
|
||||
|
||||
@@ -38,7 +38,6 @@ import {
|
||||
checkDiskUsage,
|
||||
checkForTimeout,
|
||||
checkGitHubVersionInRange,
|
||||
initializeEnvironment,
|
||||
ConfigurationError,
|
||||
wrapError,
|
||||
checkActionVersion,
|
||||
@@ -108,7 +107,7 @@ async function run(
|
||||
let toolsVersion: string;
|
||||
|
||||
try {
|
||||
initializeEnvironment(getActionVersion());
|
||||
actionState.env.initialise(getActionVersion());
|
||||
|
||||
const apiDetails = {
|
||||
auth: getRequiredInput("token"),
|
||||
|
||||
@@ -11,7 +11,13 @@ import * as sinon from "sinon";
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import * as api from "./api-client";
|
||||
import * as diagnostics from "./diagnostics";
|
||||
import { ActionsEnvVars, Env, EnvVar, ReadOnlyEnv } from "./environment";
|
||||
import {
|
||||
ActionsEnvVars,
|
||||
Env,
|
||||
EnvVar,
|
||||
getEnv,
|
||||
ReadOnlyEnv,
|
||||
} from "./environment";
|
||||
import { Feature } from "./feature-flags";
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
@@ -37,18 +43,12 @@ import {
|
||||
setupTests,
|
||||
} from "./testing-utils";
|
||||
import * as toolsDownload from "./tools-download";
|
||||
import {
|
||||
getErrorMessage,
|
||||
GitHubVariant,
|
||||
HTTPError,
|
||||
initializeEnvironment,
|
||||
withTmpDir,
|
||||
} from "./util";
|
||||
import { getErrorMessage, GitHubVariant, HTTPError, withTmpDir } from "./util";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
test.beforeEach(() => {
|
||||
initializeEnvironment("1.2.3");
|
||||
getEnv().initialise("1.2.3");
|
||||
});
|
||||
|
||||
function stubDownloadAndExtract() {
|
||||
@@ -596,7 +596,7 @@ test.serial(
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
createFeatures([Feature.CleanupToolcacheBundles]),
|
||||
createFeatures([]),
|
||||
getRunnerLogger(true),
|
||||
);
|
||||
|
||||
@@ -1375,10 +1375,7 @@ for (const bundle of ["per-language", "combined", "fallback"] as const) {
|
||||
};
|
||||
});
|
||||
const addDiagnostic = sinon.stub(diagnostics, "addNoLanguageDiagnostic");
|
||||
const features = createFeatures([
|
||||
Feature.PerLanguageBundles,
|
||||
Feature.CleanupToolcacheBundles,
|
||||
]);
|
||||
const features = createFeatures([Feature.PerLanguageBundles]);
|
||||
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
@@ -1826,11 +1823,15 @@ function createToolcacheEntry(
|
||||
*/
|
||||
async function runDownloadCodeQL(
|
||||
toolcacheRoot: string,
|
||||
features: Feature[],
|
||||
bundleVersion: string | undefined,
|
||||
env = getTestEnv({
|
||||
[ActionsEnvVars.RUNNER_TOOL_CACHE]: toolcacheRoot,
|
||||
}),
|
||||
{
|
||||
env = getTestEnv({
|
||||
[ActionsEnvVars.RUNNER_ENVIRONMENT]: "github-hosted",
|
||||
[ActionsEnvVars.RUNNER_TOOL_CACHE]: toolcacheRoot,
|
||||
}),
|
||||
}: {
|
||||
env?: Env;
|
||||
} = {},
|
||||
): Promise<{
|
||||
codeqlFolder: string;
|
||||
cleanupDiagnostic: toolsDownload.ToolcacheCleanupResult | undefined;
|
||||
@@ -1841,7 +1842,6 @@ async function runDownloadCodeQL(
|
||||
const { codeqlFolder } = await setupCodeql.downloadCodeQLBundle(
|
||||
initAllState({
|
||||
env,
|
||||
features: createFeatures(features),
|
||||
}),
|
||||
{
|
||||
bundle: {
|
||||
@@ -1879,11 +1879,9 @@ async function runDownloadCodeQL(
|
||||
async function testToolcacheCleanup(
|
||||
t: ExecutionContext<unknown>,
|
||||
{
|
||||
features,
|
||||
runnerEnvironment,
|
||||
setUp,
|
||||
}: {
|
||||
features: Feature[];
|
||||
runnerEnvironment: string | undefined;
|
||||
setUp?: (env: Env) => void;
|
||||
},
|
||||
@@ -1895,12 +1893,8 @@ async function testToolcacheCleanup(
|
||||
) {
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
if (runnerEnvironment === undefined) {
|
||||
delete process.env[ActionsEnvVars.RUNNER_ENVIRONMENT];
|
||||
} else {
|
||||
process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] = runnerEnvironment;
|
||||
}
|
||||
const env = getTestEnv({
|
||||
[ActionsEnvVars.RUNNER_ENVIRONMENT]: runnerEnvironment,
|
||||
[ActionsEnvVars.RUNNER_TOOL_CACHE]: tmpDir,
|
||||
});
|
||||
setUp?.(env);
|
||||
@@ -1920,9 +1914,8 @@ async function testToolcacheCleanup(
|
||||
|
||||
const { cleanupDiagnostic } = await runDownloadCodeQL(
|
||||
tmpDir,
|
||||
features,
|
||||
CLEANUP_BUNDLE_VERSION,
|
||||
env,
|
||||
{ env },
|
||||
);
|
||||
|
||||
t.true(
|
||||
@@ -1934,28 +1927,12 @@ async function testToolcacheCleanup(
|
||||
});
|
||||
}
|
||||
|
||||
test.serial(
|
||||
"downloadCodeQLBundle does not clean up the toolcache when the feature flag is disabled",
|
||||
async (t) => {
|
||||
await testToolcacheCleanup(
|
||||
t,
|
||||
{ features: [], runnerEnvironment: "github-hosted" },
|
||||
({ cleanupDiagnostic, destinationDirectory, staleDirectory }) => {
|
||||
t.true(fs.existsSync(staleDirectory));
|
||||
t.true(fs.existsSync(destinationDirectory));
|
||||
t.is(cleanupDiagnostic, undefined);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"downloadCodeQLBundle does not clean up the toolcache when the runner is not GitHub-hosted",
|
||||
async (t) => {
|
||||
await testToolcacheCleanup(
|
||||
t,
|
||||
{
|
||||
features: [Feature.CleanupToolcacheBundles],
|
||||
runnerEnvironment: "self-hosted",
|
||||
},
|
||||
({ cleanupDiagnostic, destinationDirectory, staleDirectory }) => {
|
||||
@@ -1975,7 +1952,6 @@ test.serial(
|
||||
await testToolcacheCleanup(
|
||||
t,
|
||||
{
|
||||
features: [Feature.CleanupToolcacheBundles],
|
||||
runnerEnvironment: undefined,
|
||||
},
|
||||
({ cleanupDiagnostic, destinationDirectory, staleDirectory }) => {
|
||||
@@ -1988,12 +1964,11 @@ test.serial(
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"downloadCodeQLBundle deletes other CodeQL bundles from the toolcache when enabled on a GitHub-hosted runner",
|
||||
"downloadCodeQLBundle deletes other CodeQL bundles from the toolcache on a GitHub-hosted runner",
|
||||
async (t) => {
|
||||
await testToolcacheCleanup(
|
||||
t,
|
||||
{
|
||||
features: [Feature.CleanupToolcacheBundles],
|
||||
runnerEnvironment: "github-hosted",
|
||||
},
|
||||
({ cleanupDiagnostic, destinationDirectory, staleDirectory }) => {
|
||||
@@ -2027,7 +2002,6 @@ test.serial(
|
||||
|
||||
const { cleanupDiagnostic } = await runDownloadCodeQL(
|
||||
tmpDir,
|
||||
[Feature.CleanupToolcacheBundles],
|
||||
CLEANUP_BUNDLE_VERSION,
|
||||
);
|
||||
|
||||
@@ -2057,7 +2031,6 @@ test.serial(
|
||||
|
||||
const { cleanupDiagnostic } = await runDownloadCodeQL(
|
||||
tmpDir,
|
||||
[Feature.CleanupToolcacheBundles],
|
||||
CLEANUP_BUNDLE_VERSION,
|
||||
);
|
||||
|
||||
@@ -2189,7 +2162,6 @@ test.serial(
|
||||
|
||||
const { cleanupDiagnostic } = await runDownloadCodeQL(
|
||||
toolcacheRoot,
|
||||
[Feature.CleanupToolcacheBundles],
|
||||
CLEANUP_BUNDLE_VERSION,
|
||||
);
|
||||
|
||||
@@ -2212,7 +2184,6 @@ test.serial(
|
||||
await testToolcacheCleanup(
|
||||
t,
|
||||
{
|
||||
features: [Feature.CleanupToolcacheBundles],
|
||||
runnerEnvironment: "github-hosted",
|
||||
setUp: (env) => {
|
||||
env.set(EnvVar.HAS_SET_UP_CODEQL, "true");
|
||||
@@ -2242,9 +2213,13 @@ test.serial(
|
||||
);
|
||||
const { codeqlFolder, cleanupDiagnostic } = await runDownloadCodeQL(
|
||||
tmpDir,
|
||||
[Feature.CleanupToolcacheBundles],
|
||||
CLEANUP_BUNDLE_VERSION,
|
||||
getTestEnv({ [EnvVar.HAS_SET_UP_CODEQL]: "true" }),
|
||||
{
|
||||
env: getTestEnv({
|
||||
[ActionsEnvVars.RUNNER_ENVIRONMENT]: "github-hosted",
|
||||
[EnvVar.HAS_SET_UP_CODEQL]: "true",
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
t.true(fs.existsSync(staleDirectory));
|
||||
@@ -2312,7 +2287,7 @@ test.serial(
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
createFeatures([Feature.CleanupToolcacheBundles]),
|
||||
createFeatures([]),
|
||||
getRunnerLogger(true),
|
||||
),
|
||||
{ is: error },
|
||||
@@ -2347,7 +2322,6 @@ test.serial(
|
||||
|
||||
const { codeqlFolder, cleanupDiagnostic } = await runDownloadCodeQL(
|
||||
tmpDir,
|
||||
[Feature.CleanupToolcacheBundles],
|
||||
undefined, // bundleVersion
|
||||
);
|
||||
|
||||
@@ -2381,7 +2355,6 @@ test.serial(
|
||||
|
||||
const { cleanupDiagnostic } = await runDownloadCodeQL(
|
||||
tmpDir,
|
||||
[Feature.CleanupToolcacheBundles],
|
||||
CLEANUP_BUNDLE_VERSION,
|
||||
);
|
||||
|
||||
@@ -2417,7 +2390,6 @@ test.serial(
|
||||
|
||||
const { cleanupDiagnostic } = await runDownloadCodeQL(
|
||||
tmpDir,
|
||||
[Feature.CleanupToolcacheBundles],
|
||||
CLEANUP_BUNDLE_VERSION,
|
||||
);
|
||||
|
||||
@@ -2467,7 +2439,6 @@ test.serial(
|
||||
|
||||
const { cleanupDiagnostic } = await runDownloadCodeQL(
|
||||
toolcacheRoot,
|
||||
[Feature.CleanupToolcacheBundles],
|
||||
CLEANUP_BUNDLE_VERSION,
|
||||
);
|
||||
|
||||
|
||||
@@ -839,7 +839,7 @@ function getToolcacheDestination(
|
||||
}
|
||||
|
||||
/**
|
||||
* Reclaims disk space by deleting the CodeQL tools from the toolcache, if enabled.
|
||||
* Reclaims disk space by deleting the CodeQL tools from the toolcache on GitHub-hosted runners.
|
||||
*
|
||||
* On GitHub-hosted runners the toolcache shares a filesystem with the workspace, so tools left in
|
||||
* the toolcache take up space that the analysis could use instead. This holds wherever we extract
|
||||
@@ -847,9 +847,8 @@ function getToolcacheDestination(
|
||||
*/
|
||||
async function tryDeleteToolcacheBundles({
|
||||
env,
|
||||
features,
|
||||
logger,
|
||||
}: ActionState<["Logger", "ReadOnlyEnv", "FeatureFlags"]>): Promise<void> {
|
||||
}: ActionState<["Logger", "ReadOnlyEnv"]>): Promise<void> {
|
||||
// A step that has already set up CodeQL may hand out a path into the toolcache that a later step
|
||||
// runs, so only the first step to set it up can know that nothing else relies on the toolcache.
|
||||
if (env.getOptional(EnvVar.HAS_SET_UP_CODEQL) !== undefined) {
|
||||
@@ -860,11 +859,7 @@ async function tryDeleteToolcacheBundles({
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!isGitHubHostedRunner() ||
|
||||
!isToolcacheOnWorkspaceFilesystem(logger) ||
|
||||
!(await features.getValue(Feature.CleanupToolcacheBundles))
|
||||
) {
|
||||
if (!isGitHubHostedRunner(env) || !isToolcacheOnWorkspaceFilesystem(logger)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -983,7 +978,7 @@ export async function setupCodeQLBundle(
|
||||
break;
|
||||
case "download": {
|
||||
const result = await downloadCodeQLBundle(
|
||||
{ env: getEnv(), features, logger },
|
||||
{ env: getEnv(), logger },
|
||||
source,
|
||||
apiDetails,
|
||||
zstdAvailability.version,
|
||||
@@ -1019,7 +1014,7 @@ export async function setupCodeQLBundle(
|
||||
* @returns The extraction directory and download timings.
|
||||
*/
|
||||
export async function downloadCodeQLBundle(
|
||||
action: ActionState<["Logger", "ReadOnlyEnv", "FeatureFlags"]>,
|
||||
action: ActionState<["Logger", "ReadOnlyEnv"]>,
|
||||
source: CodeQLDownloadSource,
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
tarVersion: tar.TarVersion | undefined,
|
||||
|
||||
@@ -6,7 +6,6 @@ import * as sinon from "sinon";
|
||||
import * as actionsUtil from "../actions-util";
|
||||
import { ActionsEnvVars } from "../environment";
|
||||
import { callee, getTestEnv, setupTests } from "../testing-utils";
|
||||
import { initializeEnvironment } from "../util";
|
||||
|
||||
import { getCodeQLActionRepository } from "./repository";
|
||||
|
||||
@@ -16,7 +15,7 @@ test.serial("getCodeQLActionRepository", async (t) => {
|
||||
const initialEnv = getTestEnv({
|
||||
[ActionsEnvVars.RUNNER_TEMP]: path.dirname(__dirname),
|
||||
});
|
||||
initializeEnvironment("1.2.3", initialEnv);
|
||||
initialEnv.initialise("1.2.3");
|
||||
|
||||
const target = callee(getCodeQLActionRepository)
|
||||
.withArgs()
|
||||
|
||||
@@ -2,13 +2,12 @@ import { ActionState } from "../action-common";
|
||||
import { isRunningLocalAction } from "../actions-util";
|
||||
import * as api from "../api-client";
|
||||
import { ActionsEnvVars } from "../environment";
|
||||
import { GITHUB_DOTCOM_URL } from "../github";
|
||||
import { GITHUB_DOTCOM_URL, type InstanceURL } from "../github";
|
||||
import {
|
||||
isRepositoryNwoStr,
|
||||
parseRepositoryNwo,
|
||||
type RepositoryNwoStr,
|
||||
} from "../repository";
|
||||
import { type InstanceURL } from "../util";
|
||||
|
||||
/** The NWO of the standard CodeQL Action repository. */
|
||||
export const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action";
|
||||
|
||||
@@ -10,6 +10,7 @@ import { https } from "follow-redirects";
|
||||
import nock from "nock";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import * as errors from "./errors";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import * as tar from "./tar";
|
||||
import { setupTests } from "./testing-utils";
|
||||
@@ -164,7 +165,7 @@ test.serial(
|
||||
test.serial(
|
||||
"downloadAndExtract handles an unknown status as a non-HTTP error",
|
||||
async (t) => {
|
||||
const asHTTPError = sinon.spy(util, "asHTTPError");
|
||||
const asHTTPError = sinon.spy(errors, "asHTTPError");
|
||||
await util.withTmpDir(async (tmpDir) => {
|
||||
sinon.stub(process, "platform").value("linux");
|
||||
const archivePath = path.join(tmpDir, "codeql-bundle.tar.zst");
|
||||
|
||||
@@ -10,17 +10,18 @@ import * as analyses from "./analyses";
|
||||
import { AnalysisKind, CodeQuality, CodeScanning } from "./analyses";
|
||||
import * as api from "./api-client";
|
||||
import * as diffUtils from "./diff-informed-analysis-utils";
|
||||
import { getEnv } from "./environment";
|
||||
import { getRunnerLogger, Logger } from "./logging";
|
||||
import * as sarif from "./sarif";
|
||||
import { setupTests } from "./testing-utils";
|
||||
import * as uploadLib from "./upload-lib";
|
||||
import { UploadPayload } from "./upload-lib/types";
|
||||
import { GitHubVariant, initializeEnvironment, withTmpDir } from "./util";
|
||||
import { GitHubVariant, withTmpDir } from "./util";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
test.beforeEach(() => {
|
||||
initializeEnvironment("1.2.3");
|
||||
getEnv().initialise("1.2.3");
|
||||
});
|
||||
|
||||
test.serial("validateSarifFileSchema - valid", (t) => {
|
||||
|
||||
@@ -23,7 +23,6 @@ import {
|
||||
ConfigurationError,
|
||||
checkActionVersion,
|
||||
checkDiskUsage,
|
||||
initializeEnvironment,
|
||||
shouldSkipSarifUpload,
|
||||
wrapError,
|
||||
} from "./util";
|
||||
@@ -54,11 +53,13 @@ async function sendSuccessStatusReport(
|
||||
}
|
||||
}
|
||||
|
||||
async function run({ startedAt, logger }: ActionState<["Base", "Logger"]>) {
|
||||
async function run(action: ActionState<["Base", "Env", "Logger"]>) {
|
||||
// To capture errors appropriately, keep as much code within the try-catch as
|
||||
// possible, and only use safe functions outside.
|
||||
const logger = action.logger;
|
||||
|
||||
try {
|
||||
initializeEnvironment(getActionVersion());
|
||||
action.env.initialise(getActionVersion());
|
||||
|
||||
const gitHubVersion = await getGitHubVersion();
|
||||
checkActionVersion(getActionVersion(), gitHubVersion);
|
||||
@@ -77,7 +78,7 @@ async function run({ startedAt, logger }: ActionState<["Base", "Logger"]>) {
|
||||
const startingStatusReportBase = await createStatusReportBase(
|
||||
ActionName.UploadSarif,
|
||||
"starting",
|
||||
startedAt,
|
||||
action.startedAt,
|
||||
undefined,
|
||||
await checkDiskUsage(logger),
|
||||
logger,
|
||||
@@ -131,7 +132,7 @@ async function run({ startedAt, logger }: ActionState<["Base", "Logger"]>) {
|
||||
// so we can't wait for that here.
|
||||
}
|
||||
await sendSuccessStatusReport(
|
||||
startedAt,
|
||||
action.startedAt,
|
||||
codeScanningResult?.statusReport || {},
|
||||
logger,
|
||||
);
|
||||
@@ -147,7 +148,7 @@ async function run({ startedAt, logger }: ActionState<["Base", "Logger"]>) {
|
||||
const errorStatusReportBase = await createStatusReportBase(
|
||||
ActionName.UploadSarif,
|
||||
getActionsStatus(error),
|
||||
startedAt,
|
||||
action.startedAt,
|
||||
undefined,
|
||||
await checkDiskUsage(logger),
|
||||
logger,
|
||||
|
||||
90
src/util.ts
90
src/util.ts
@@ -20,20 +20,21 @@ import {
|
||||
getRequiredEnvParam,
|
||||
isInTestMode,
|
||||
exportEnvVar,
|
||||
getEnv,
|
||||
type Env,
|
||||
} from "./environment";
|
||||
import * as json from "./json";
|
||||
import { Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import { ConfigurationError, getErrorMessage, wrapError } from "./errors";
|
||||
import { GitHubVariant, type GitHubVersion } from "./github";
|
||||
import type { Language } from "./languages";
|
||||
import type { Logger } from "./logging";
|
||||
|
||||
// Re-export for backwards compatibility to avoid updating a lot of imports elsewhere.
|
||||
export * from "./errors";
|
||||
export {
|
||||
getRequiredEnvParam,
|
||||
getOptionalEnvVar,
|
||||
getEnv,
|
||||
isInTestMode,
|
||||
} from "./environment";
|
||||
export { GitHubVariant, type GitHubVersion } from "./github";
|
||||
|
||||
/**
|
||||
* The name of the file containing the base database OIDs, as stored in the
|
||||
@@ -47,9 +48,6 @@ const BASE_DATABASE_OIDS_FILE_NAME = "base-database-oids.json";
|
||||
*/
|
||||
const BROKEN_VERSIONS = ["0.0.0-20211207"];
|
||||
|
||||
/** A string representing a GitHub instance. */
|
||||
export type InstanceURL = string;
|
||||
|
||||
/**
|
||||
* Default name of the debugging artifact.
|
||||
*/
|
||||
@@ -470,20 +468,6 @@ const CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR =
|
||||
|
||||
let hasBeenWarnedAboutVersion = false;
|
||||
|
||||
export enum GitHubVariant {
|
||||
/** [GitHub.com](https://github.com) */
|
||||
DOTCOM = "GitHub.com",
|
||||
/** [GitHub Enterprise Server](https://docs.github.com/en/enterprise-server@latest/admin/overview/about-github-enterprise-server) */
|
||||
GHES = "GitHub Enterprise Server",
|
||||
/** [GitHub Enterprise Cloud with data residency](https://docs.github.com/en/enterprise-cloud@latest/admin/data-residency/about-github-enterprise-cloud-with-data-residency) */
|
||||
GHEC_DR = "GitHub Enterprise Cloud with data residency",
|
||||
}
|
||||
|
||||
export type GitHubVersion =
|
||||
| { type: GitHubVariant.DOTCOM }
|
||||
| { type: GitHubVariant.GHEC_DR }
|
||||
| { type: GitHubVariant.GHES; version: string };
|
||||
|
||||
export function checkGitHubVersionInRange(
|
||||
version: GitHubVersion,
|
||||
logger: Logger,
|
||||
@@ -552,54 +536,6 @@ export function assertNever(value: never): never {
|
||||
throw new ExhaustivityCheckingError(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set some initial environment variables that we can set even without
|
||||
* knowing what version of CodeQL we're running.
|
||||
*/
|
||||
export function initializeEnvironment(version: string, env: Env = getEnv()) {
|
||||
env.export(EnvVar.FEATURE_MULTI_LANGUAGE, "false");
|
||||
env.export(EnvVar.FEATURE_SANDWICH, "false");
|
||||
env.export(EnvVar.FEATURE_SARIF_COMBINE, "true");
|
||||
env.export(EnvVar.FEATURE_WILL_UPLOAD, "true");
|
||||
env.export(EnvVar.VERSION, version);
|
||||
}
|
||||
|
||||
export class HTTPError extends Error {
|
||||
public status: number;
|
||||
|
||||
constructor(message: string, status: number) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An Error class that indicates an error that occurred due to
|
||||
* a misconfiguration of the action or the CodeQL CLI.
|
||||
*/
|
||||
export class ConfigurationError extends Error {}
|
||||
|
||||
export function asHTTPError(arg: any): HTTPError | undefined {
|
||||
if (!json.isObject<any>(arg) || !json.isString(arg.message)) {
|
||||
return undefined;
|
||||
}
|
||||
if (Number.isInteger(arg.status)) {
|
||||
return new HTTPError(arg.message, arg.status as number);
|
||||
}
|
||||
// See https://github.com/actions/toolkit/blob/acb230b99a46ed33a3f04a758cd68b47b9a82908/packages/tool-cache/src/tool-cache.ts#L19
|
||||
if (Number.isInteger(arg.httpStatusCode)) {
|
||||
return new HTTPError(arg.message, arg.httpStatusCode as number);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export async function codeQlVersionAtLeast(
|
||||
codeql: CodeQL,
|
||||
requiredVersion: string,
|
||||
): Promise<boolean> {
|
||||
return semver.gte((await codeql.getVersion()).version, requiredVersion);
|
||||
}
|
||||
|
||||
export function getBaseDatabaseOidsFilePath(
|
||||
config: ActionConfig<"dbLocation">,
|
||||
): string {
|
||||
@@ -867,20 +803,6 @@ export function parseMatrixInput(
|
||||
}
|
||||
}
|
||||
|
||||
export function wrapError(error: unknown): Error {
|
||||
return error instanceof Error ? error : new Error(String(error));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an appropriate message for the error.
|
||||
*
|
||||
* If the error is an `Error` instance, this returns the error message without
|
||||
* an `Error: ` prefix.
|
||||
*/
|
||||
export function getErrorMessage(error: unknown): string {
|
||||
return error instanceof Error ? error.message : String(error);
|
||||
}
|
||||
|
||||
export function prettyPrintPack(pack: Pack) {
|
||||
return `${pack.name}${pack.version ? `@${pack.version}` : ""}${
|
||||
pack.path ? `:${pack.path}` : ""
|
||||
|
||||
@@ -2,6 +2,16 @@
|
||||
|
||||
Change-notes are Markdown files used to document user-facing changes. When making a change that affects users, create a Markdown file here that describes the change. During the next release, the change-note files in `unreleased-change-notes/` will automatically be added to `CHANGELOG.md`.
|
||||
|
||||
### What do document
|
||||
|
||||
Some guidelines to help you decide whether a change needs a change note:
|
||||
|
||||
- New functionality that is gated behind a feature flag should be documented when it is added, highlighting that the feature will only be rolled out later. Ideally, this should also include an estimate for when the feature is expected to become available.
|
||||
- When a feature flag is removed and the gated functionality becomes the default behaviour, this does not need to be documented.
|
||||
- Changes that may require users to make changes to their workflows must be documented.
|
||||
|
||||
If in doubt, see `CHANGELOG.md` for what we have included previously.
|
||||
|
||||
### Change-note file format
|
||||
|
||||
Change-note files must follow a certain format so that they can be automatically validated and processed. Failure to follow the format will result in a failed PR check.
|
||||
|
||||
Reference in New Issue
Block a user