mirror of
https://github.com/github/codeql-action.git
synced 2025-12-14 19:39:10 +08:00
Compare commits
45 Commits
v2.2.1
...
codeql-bun
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e00cd12e3e | ||
|
|
a25536bc80 | ||
|
|
a2487fb969 | ||
|
|
e187d074ed | ||
|
|
89c5165e5a | ||
|
|
ba216f7d34 | ||
|
|
68f4f0d3bb | ||
|
|
12d9a244fa | ||
|
|
17573ee1cc | ||
|
|
b6975b4b1a | ||
|
|
b011dbdedf | ||
|
|
40babc141f | ||
|
|
7ba5ed7eed | ||
|
|
21f3020df6 | ||
|
|
b872c5adfd | ||
|
|
8775e86802 | ||
|
|
a2ad80b966 | ||
|
|
c4e22e9fce | ||
|
|
db534af2ae | ||
|
|
4369dda4ae | ||
|
|
4f08c2cf20 | ||
|
|
81644f35ff | ||
|
|
9ab6aa64a0 | ||
|
|
256973e279 | ||
|
|
59b25b480f | ||
|
|
39d8d7e78f | ||
|
|
39c954c513 | ||
|
|
8af83634ca | ||
|
|
927de483f0 | ||
|
|
e4c0a1b24d | ||
|
|
d3962273b3 | ||
|
|
c3cb270725 | ||
|
|
2b674f7ab9 | ||
|
|
6d47a7c8b1 | ||
|
|
c6ff11c1c4 | ||
|
|
d3f2b2e6d2 | ||
|
|
d49282c3b5 | ||
|
|
c5c475188a | ||
|
|
f140af5e28 | ||
|
|
e0fc1c91b2 | ||
|
|
b95df0b2e7 | ||
|
|
2fed02cbe2 | ||
|
|
0b2a40fa4a | ||
|
|
395ec04a8b | ||
|
|
e1070bd101 |
@@ -33,6 +33,12 @@
|
|||||||
"alphabetize": {"order": "asc"},
|
"alphabetize": {"order": "asc"},
|
||||||
"newlines-between": "always"
|
"newlines-between": "always"
|
||||||
}],
|
}],
|
||||||
|
"max-len": ["error", {
|
||||||
|
"code": 120,
|
||||||
|
"ignoreUrls": true,
|
||||||
|
"ignoreStrings": true,
|
||||||
|
"ignoreTemplateLiterals": true
|
||||||
|
}],
|
||||||
"no-async-foreach/no-async-foreach": "error",
|
"no-async-foreach/no-async-foreach": "error",
|
||||||
"no-console": "off",
|
"no-console": "off",
|
||||||
"no-sequences": "error",
|
"no-sequences": "error",
|
||||||
|
|||||||
16
CHANGELOG.md
16
CHANGELOG.md
@@ -1,5 +1,21 @@
|
|||||||
# CodeQL Action Changelog
|
# CodeQL Action Changelog
|
||||||
|
|
||||||
|
## [UNRELEASED]
|
||||||
|
|
||||||
|
No user facing changes.
|
||||||
|
|
||||||
|
## 2.2.4 - 10 Feb 2023
|
||||||
|
|
||||||
|
No user facing changes.
|
||||||
|
|
||||||
|
## 2.2.3 - 08 Feb 2023
|
||||||
|
|
||||||
|
- Update default CodeQL bundle version to 2.12.2. [#1518](https://github.com/github/codeql-action/pull/1518)
|
||||||
|
|
||||||
|
## 2.2.2 - 06 Feb 2023
|
||||||
|
|
||||||
|
- Fix an issue where customers using the CodeQL Action with the [CodeQL Action sync tool](https://docs.github.com/en/enterprise-server@3.7/admin/code-security/managing-github-advanced-security-for-your-enterprise/configuring-code-scanning-for-your-appliance#configuring-codeql-analysis-on-a-server-without-internet-access) would not be able to obtain the CodeQL tools. [#1517](https://github.com/github/codeql-action/pull/1517)
|
||||||
|
|
||||||
## 2.2.1 - 27 Jan 2023
|
## 2.2.1 - 27 Jan 2023
|
||||||
|
|
||||||
No user facing changes.
|
No user facing changes.
|
||||||
|
|||||||
@@ -67,12 +67,8 @@ Here are a few things you can do that will increase the likelihood of your pull
|
|||||||
This mergeback incorporates the changelog updates into `main`, tags the release using the merge commit of the "Merge main into releases/v2" pull request, and bumps the patch version of the CodeQL Action.
|
This mergeback incorporates the changelog updates into `main`, tags the release using the merge commit of the "Merge main into releases/v2" pull request, and bumps the patch version of the CodeQL Action.
|
||||||
|
|
||||||
Approve the mergeback PR and automerge it.
|
Approve the mergeback PR and automerge it.
|
||||||
1. When the "Merge main into releases/v2" pull request is merged into the `releases/v2` branch, the "Update release branch" workflow will create a "Merge releases/v2 into releases/v1" pull request to merge the changes since the last release into the `releases/v1` release branch.
|
|
||||||
This ensures we keep both the `releases/v1` and `releases/v2` release branches up to date and fully supported.
|
|
||||||
|
|
||||||
Review the checklist items in the pull request description.
|
Once the mergeback has been merged to `main`, the release is complete.
|
||||||
Once you've checked off all the items, approve the PR and automerge it.
|
|
||||||
1. Once the mergeback has been merged to `main` and the "Merge releases/v2 into releases/v1" PR has been merged to `releases/v1`, the release is complete.
|
|
||||||
|
|
||||||
## Keeping the PR checks up to date (admin access required)
|
## Keeping the PR checks up to date (admin access required)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# CodeQL Action
|
# CodeQL Action
|
||||||
|
|
||||||
This action runs GitHub's industry-leading semantic code analysis engine, CodeQL, against a repository's source code to find security vulnerabilities. It then automatically uploads the results to GitHub so they can be displayed in the repository's security tab. CodeQL runs an extensible set of [queries](https://github.com/github/codeql), which have been developed by the community and the [GitHub Security Lab](https://securitylab.github.com/) to find common vulnerabilities in your code.
|
This action runs GitHub's industry-leading semantic code analysis engine, [CodeQL](https://codeql.github.com/), against a repository's source code to find security vulnerabilities. It then automatically uploads the results to GitHub so they can be displayed in the repository's security tab. CodeQL runs an extensible set of [queries](https://github.com/github/codeql), which have been developed by the community and the [GitHub Security Lab](https://securitylab.github.com/) to find common vulnerabilities in your code.
|
||||||
|
|
||||||
For a list of recent changes, see the CodeQL Action's [changelog](CHANGELOG.md).
|
For a list of recent changes, see the CodeQL Action's [changelog](CHANGELOG.md).
|
||||||
|
|
||||||
|
|||||||
11
lib/codeql.js
generated
11
lib/codeql.js
generated
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.getExtraOptions = exports.getCodeQLForCmd = exports.getCodeQLForTesting = exports.getCachedCodeQL = exports.setCodeQL = exports.getCodeQL = exports.setupCodeQL = exports.CODEQL_VERSION_BETTER_RESOLVE_LANGUAGES = exports.CODEQL_VERSION_ML_POWERED_QUERIES_WINDOWS = exports.CODEQL_VERSION_TRACING_GLIBC_2_34 = exports.CODEQL_VERSION_NEW_TRACING = exports.CODEQL_VERSION_GHES_PACK_DOWNLOAD = exports.CommandInvocationError = void 0;
|
exports.getExtraOptions = exports.getCodeQLForCmd = exports.getCodeQLForTesting = exports.getCachedCodeQL = exports.setCodeQL = exports.getCodeQL = exports.setupCodeQL = exports.CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE = exports.CODEQL_VERSION_BETTER_RESOLVE_LANGUAGES = exports.CODEQL_VERSION_ML_POWERED_QUERIES_WINDOWS = exports.CODEQL_VERSION_TRACING_GLIBC_2_34 = exports.CODEQL_VERSION_NEW_TRACING = exports.CODEQL_VERSION_GHES_PACK_DOWNLOAD = exports.CommandInvocationError = void 0;
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||||
@@ -94,6 +94,10 @@ exports.CODEQL_VERSION_ML_POWERED_QUERIES_WINDOWS = "2.9.0";
|
|||||||
* --extractor-options-verbosity that we need.
|
* --extractor-options-verbosity that we need.
|
||||||
*/
|
*/
|
||||||
exports.CODEQL_VERSION_BETTER_RESOLVE_LANGUAGES = "2.10.3";
|
exports.CODEQL_VERSION_BETTER_RESOLVE_LANGUAGES = "2.10.3";
|
||||||
|
/**
|
||||||
|
* Versions 2.11.1+ of the CodeQL Bundle include a `security-experimental` built-in query suite for each language.
|
||||||
|
*/
|
||||||
|
exports.CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE = "2.12.1";
|
||||||
/**
|
/**
|
||||||
* Set up CodeQL CLI access.
|
* Set up CodeQL CLI access.
|
||||||
*
|
*
|
||||||
@@ -101,16 +105,15 @@ exports.CODEQL_VERSION_BETTER_RESOLVE_LANGUAGES = "2.10.3";
|
|||||||
* @param apiDetails
|
* @param apiDetails
|
||||||
* @param tempDir
|
* @param tempDir
|
||||||
* @param variant
|
* @param variant
|
||||||
* @param bypassToolcache
|
|
||||||
* @param defaultCliVersion
|
* @param defaultCliVersion
|
||||||
* @param logger
|
* @param logger
|
||||||
* @param checkVersion Whether to check that CodeQL CLI meets the minimum
|
* @param checkVersion Whether to check that CodeQL CLI meets the minimum
|
||||||
* version requirement. Must be set to true outside tests.
|
* version requirement. Must be set to true outside tests.
|
||||||
* @returns a { CodeQL, toolsVersion } object.
|
* @returns a { CodeQL, toolsVersion } object.
|
||||||
*/
|
*/
|
||||||
async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, bypassToolcache, defaultCliVersion, logger, checkVersion) {
|
async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger, checkVersion) {
|
||||||
try {
|
try {
|
||||||
const { codeqlFolder, toolsDownloadDurationMs, toolsSource, toolsVersion } = await setupCodeql.setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, bypassToolcache, defaultCliVersion, logger);
|
const { codeqlFolder, toolsDownloadDurationMs, toolsSource, toolsVersion } = await setupCodeql.setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger);
|
||||||
let codeqlCmd = path.join(codeqlFolder, "codeql", "codeql");
|
let codeqlCmd = path.join(codeqlFolder, "codeql", "codeql");
|
||||||
if (process.platform === "win32") {
|
if (process.platform === "win32") {
|
||||||
codeqlCmd += ".exe";
|
codeqlCmd += ".exe";
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
60
lib/codeql.test.js
generated
60
lib/codeql.test.js
generated
@@ -97,7 +97,7 @@ ava_1.default.beforeEach(() => {
|
|||||||
* @returns the download URL for the bundle. This can be passed to the tools parameter of
|
* @returns the download URL for the bundle. This can be passed to the tools parameter of
|
||||||
* `codeql.setupCodeQL`.
|
* `codeql.setupCodeQL`.
|
||||||
*/
|
*/
|
||||||
function mockDownloadApi({ apiDetails = sampleApiDetails, isPinned, tagName, }) {
|
function mockDownloadApi({ apiDetails = sampleApiDetails, isPinned, repo = "github/codeql-action", platformSpecific = true, tagName, }) {
|
||||||
const platform = process.platform === "win32"
|
const platform = process.platform === "win32"
|
||||||
? "win64"
|
? "win64"
|
||||||
: process.platform === "linux"
|
: process.platform === "linux"
|
||||||
@@ -105,7 +105,7 @@ function mockDownloadApi({ apiDetails = sampleApiDetails, isPinned, tagName, })
|
|||||||
: "osx64";
|
: "osx64";
|
||||||
const baseUrl = apiDetails?.url ?? "https://example.com";
|
const baseUrl = apiDetails?.url ?? "https://example.com";
|
||||||
const relativeUrl = apiDetails
|
const relativeUrl = apiDetails
|
||||||
? `/github/codeql-action/releases/download/${tagName}/codeql-bundle-${platform}.tar.gz`
|
? `/${repo}/releases/download/${tagName}/codeql-bundle${platformSpecific ? `-${platform}` : ""}.tar.gz`
|
||||||
: `/download/${tagName}/codeql-bundle.tar.gz`;
|
: `/download/${tagName}/codeql-bundle.tar.gz`;
|
||||||
(0, nock_1.default)(baseUrl)
|
(0, nock_1.default)(baseUrl)
|
||||||
.get(relativeUrl)
|
.get(relativeUrl)
|
||||||
@@ -114,7 +114,7 @@ function mockDownloadApi({ apiDetails = sampleApiDetails, isPinned, tagName, })
|
|||||||
}
|
}
|
||||||
async function installIntoToolcache({ apiDetails = sampleApiDetails, cliVersion, isPinned, tagName, tmpDir, }) {
|
async function installIntoToolcache({ apiDetails = sampleApiDetails, cliVersion, isPinned, tagName, tmpDir, }) {
|
||||||
const url = mockDownloadApi({ apiDetails, isPinned, tagName });
|
const url = mockDownloadApi({ apiDetails, isPinned, tagName });
|
||||||
await codeql.setupCodeQL(cliVersion !== undefined ? undefined : url, apiDetails, tmpDir, util.GitHubVariant.GHES, false, cliVersion !== undefined
|
await codeql.setupCodeQL(cliVersion !== undefined ? undefined : url, apiDetails, tmpDir, util.GitHubVariant.GHES, cliVersion !== undefined
|
||||||
? { cliVersion, tagName, variant: util.GitHubVariant.GHES }
|
? { cliVersion, tagName, variant: util.GitHubVariant.GHES }
|
||||||
: SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
|
: SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
|
||||||
}
|
}
|
||||||
@@ -153,7 +153,7 @@ function mockApiDetails(apiDetails) {
|
|||||||
tagName: `codeql-bundle-${version}`,
|
tagName: `codeql-bundle-${version}`,
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
});
|
});
|
||||||
const result = await codeql.setupCodeQL(url, sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, false, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
|
const result = await codeql.setupCodeQL(url, sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
|
||||||
t.assert(toolcache.find("CodeQL", `0.0.0-${version}`));
|
t.assert(toolcache.find("CodeQL", `0.0.0-${version}`));
|
||||||
t.is(result.toolsVersion, `0.0.0-${version}`);
|
t.is(result.toolsVersion, `0.0.0-${version}`);
|
||||||
t.is(result.toolsSource, init_1.ToolsSource.Download);
|
t.is(result.toolsSource, init_1.ToolsSource.Download);
|
||||||
@@ -173,7 +173,7 @@ function mockApiDetails(apiDetails) {
|
|||||||
const url = mockDownloadApi({
|
const url = mockDownloadApi({
|
||||||
tagName: "codeql-bundle-20200610",
|
tagName: "codeql-bundle-20200610",
|
||||||
});
|
});
|
||||||
const result = await codeql.setupCodeQL(url, sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, false, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
|
const result = await codeql.setupCodeQL(url, sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
|
||||||
t.assert(toolcache.find("CodeQL", "0.0.0-20200610"));
|
t.assert(toolcache.find("CodeQL", "0.0.0-20200610"));
|
||||||
t.deepEqual(result.toolsVersion, "0.0.0-20200610");
|
t.deepEqual(result.toolsVersion, "0.0.0-20200610");
|
||||||
t.is(result.toolsSource, init_1.ToolsSource.Download);
|
t.is(result.toolsSource, init_1.ToolsSource.Download);
|
||||||
@@ -207,7 +207,7 @@ for (const { cliVersion, expectedToolcacheVersion, } of EXPLICITLY_REQUESTED_BUN
|
|||||||
const url = mockDownloadApi({
|
const url = mockDownloadApi({
|
||||||
tagName: "codeql-bundle-20200610",
|
tagName: "codeql-bundle-20200610",
|
||||||
});
|
});
|
||||||
const result = await codeql.setupCodeQL(url, sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, false, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
|
const result = await codeql.setupCodeQL(url, sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
|
||||||
t.assert(releaseApiMock.isDone(), "Releases API should have been called");
|
t.assert(releaseApiMock.isDone(), "Releases API should have been called");
|
||||||
t.assert(toolcache.find("CodeQL", expectedToolcacheVersion));
|
t.assert(toolcache.find("CodeQL", expectedToolcacheVersion));
|
||||||
t.deepEqual(result.toolsVersion, cliVersion);
|
t.deepEqual(result.toolsVersion, cliVersion);
|
||||||
@@ -256,7 +256,7 @@ for (const { githubReleases, toolcacheVersion } of [
|
|||||||
}))),
|
}))),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
const result = await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, false, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
|
const result = await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
|
||||||
t.is(result.toolsVersion, SAMPLE_DEFAULT_CLI_VERSION.cliVersion);
|
t.is(result.toolsVersion, SAMPLE_DEFAULT_CLI_VERSION.cliVersion);
|
||||||
t.is(result.toolsSource, init_1.ToolsSource.Toolcache);
|
t.is(result.toolsSource, init_1.ToolsSource.Toolcache);
|
||||||
t.is(result.toolsDownloadDurationMs, undefined);
|
t.is(result.toolsDownloadDurationMs, undefined);
|
||||||
@@ -272,7 +272,7 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
|
|||||||
isPinned: true,
|
isPinned: true,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
});
|
});
|
||||||
const result = await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, variant, false, {
|
const result = await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, variant, {
|
||||||
cliVersion: defaults.cliVersion,
|
cliVersion: defaults.cliVersion,
|
||||||
tagName: defaults.bundleVersion,
|
tagName: defaults.bundleVersion,
|
||||||
variant,
|
variant,
|
||||||
@@ -295,7 +295,7 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
|
|||||||
mockDownloadApi({
|
mockDownloadApi({
|
||||||
tagName: defaults.bundleVersion,
|
tagName: defaults.bundleVersion,
|
||||||
});
|
});
|
||||||
const result = await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, variant, false, {
|
const result = await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, variant, {
|
||||||
cliVersion: defaults.cliVersion,
|
cliVersion: defaults.cliVersion,
|
||||||
tagName: defaults.bundleVersion,
|
tagName: defaults.bundleVersion,
|
||||||
variant,
|
variant,
|
||||||
@@ -319,7 +319,7 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
|
|||||||
mockDownloadApi({
|
mockDownloadApi({
|
||||||
tagName: defaults.bundleVersion,
|
tagName: defaults.bundleVersion,
|
||||||
});
|
});
|
||||||
const result = await codeql.setupCodeQL("latest", sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, false, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
|
const result = await codeql.setupCodeQL("latest", sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
|
||||||
t.deepEqual(result.toolsVersion, defaults.cliVersion);
|
t.deepEqual(result.toolsVersion, defaults.cliVersion);
|
||||||
t.is(result.toolsSource, init_1.ToolsSource.Download);
|
t.is(result.toolsSource, init_1.ToolsSource.Download);
|
||||||
t.assert(Number.isInteger(result.toolsDownloadDurationMs));
|
t.assert(Number.isInteger(result.toolsDownloadDurationMs));
|
||||||
@@ -327,7 +327,11 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
|
|||||||
t.is(cachedVersions.length, 2);
|
t.is(cachedVersions.length, 2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
(0, ava_1.default)("download codeql bundle from github ae endpoint", async (t) => {
|
for (const isBundleVersionInUrl of [true, false]) {
|
||||||
|
const inclusionString = isBundleVersionInUrl
|
||||||
|
? "includes"
|
||||||
|
: "does not include";
|
||||||
|
(0, ava_1.default)(`download codeql bundle from github ae endpoint (URL ${inclusionString} bundle version)`, async (t) => {
|
||||||
await util.withTmpDir(async (tmpDir) => {
|
await util.withTmpDir(async (tmpDir) => {
|
||||||
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
|
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
|
||||||
const bundleAssetID = 10;
|
const bundleAssetID = 10;
|
||||||
@@ -337,6 +341,9 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
|
|||||||
? "linux64"
|
? "linux64"
|
||||||
: "osx64";
|
: "osx64";
|
||||||
const codeQLBundleName = `codeql-bundle-${platform}.tar.gz`;
|
const codeQLBundleName = `codeql-bundle-${platform}.tar.gz`;
|
||||||
|
const eventualDownloadUrl = isBundleVersionInUrl
|
||||||
|
? `https://example.githubenterprise.com/github/codeql-action/releases/download/${defaults.bundleVersion}/${codeQLBundleName}`
|
||||||
|
: `https://example.githubenterprise.com/api/v3/repos/github/codeql-action/releases/assets/${bundleAssetID}`;
|
||||||
(0, nock_1.default)("https://example.githubenterprise.com")
|
(0, nock_1.default)("https://example.githubenterprise.com")
|
||||||
.get(`/api/v3/enterprise/code-scanning/codeql-bundle/find/${defaults.bundleVersion}`)
|
.get(`/api/v3/enterprise/code-scanning/codeql-bundle/find/${defaults.bundleVersion}`)
|
||||||
.reply(200, {
|
.reply(200, {
|
||||||
@@ -345,15 +352,15 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
|
|||||||
(0, nock_1.default)("https://example.githubenterprise.com")
|
(0, nock_1.default)("https://example.githubenterprise.com")
|
||||||
.get(`/api/v3/enterprise/code-scanning/codeql-bundle/download/${bundleAssetID}`)
|
.get(`/api/v3/enterprise/code-scanning/codeql-bundle/download/${bundleAssetID}`)
|
||||||
.reply(200, {
|
.reply(200, {
|
||||||
url: `https://example.githubenterprise.com/github/codeql-action/releases/download/${defaults.bundleVersion}/${codeQLBundleName}`,
|
url: eventualDownloadUrl,
|
||||||
});
|
});
|
||||||
(0, nock_1.default)("https://example.githubenterprise.com")
|
(0, nock_1.default)("https://example.githubenterprise.com")
|
||||||
.get(`/github/codeql-action/releases/download/${defaults.bundleVersion}/${codeQLBundleName}`)
|
.get(eventualDownloadUrl.replace("https://example.githubenterprise.com", ""))
|
||||||
.replyWithFile(200, path_1.default.join(__dirname, `/../src/testdata/codeql-bundle-pinned.tar.gz`));
|
.replyWithFile(200, path_1.default.join(__dirname, `/../src/testdata/codeql-bundle-pinned.tar.gz`));
|
||||||
mockApiDetails(sampleGHAEApiDetails);
|
mockApiDetails(sampleGHAEApiDetails);
|
||||||
sinon.stub(actionsUtil, "isRunningLocalAction").returns(false);
|
sinon.stub(actionsUtil, "isRunningLocalAction").returns(false);
|
||||||
process.env["GITHUB_ACTION_REPOSITORY"] = "github/codeql-action";
|
process.env["GITHUB_ACTION_REPOSITORY"] = "github/codeql-action";
|
||||||
const result = await codeql.setupCodeQL(undefined, sampleGHAEApiDetails, tmpDir, util.GitHubVariant.GHAE, false, {
|
const result = await codeql.setupCodeQL(undefined, sampleGHAEApiDetails, tmpDir, util.GitHubVariant.GHAE, {
|
||||||
cliVersion: defaults.cliVersion,
|
cliVersion: defaults.cliVersion,
|
||||||
tagName: defaults.bundleVersion,
|
tagName: defaults.bundleVersion,
|
||||||
variant: util.GitHubVariant.GHAE,
|
variant: util.GitHubVariant.GHAE,
|
||||||
@@ -364,6 +371,31 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
|
|||||||
t.is(cachedVersions.length, 1);
|
t.is(cachedVersions.length, 1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
(0, ava_1.default)("bundle URL from another repo is cached as 0.0.0-bundleVersion", async (t) => {
|
||||||
|
await util.withTmpDir(async (tmpDir) => {
|
||||||
|
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
|
||||||
|
mockApiDetails(sampleApiDetails);
|
||||||
|
sinon.stub(actionsUtil, "isRunningLocalAction").returns(true);
|
||||||
|
const releasesApiMock = mockReleaseApi({
|
||||||
|
assetNames: ["cli-version-2.12.2.txt"],
|
||||||
|
tagName: "codeql-bundle-20230203",
|
||||||
|
});
|
||||||
|
mockDownloadApi({
|
||||||
|
repo: "dsp-testing/codeql-cli-nightlies",
|
||||||
|
platformSpecific: false,
|
||||||
|
tagName: "codeql-bundle-20230203",
|
||||||
|
});
|
||||||
|
const result = await codeql.setupCodeQL("https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/codeql-bundle-20230203/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
|
||||||
|
t.is(result.toolsVersion, "0.0.0-20230203");
|
||||||
|
t.is(result.toolsSource, init_1.ToolsSource.Download);
|
||||||
|
t.true(Number.isInteger(result.toolsDownloadDurationMs));
|
||||||
|
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
||||||
|
t.is(cachedVersions.length, 1);
|
||||||
|
t.is(cachedVersions[0], "0.0.0-20230203");
|
||||||
|
t.false(releasesApiMock.isDone());
|
||||||
|
});
|
||||||
|
});
|
||||||
(0, ava_1.default)("getExtraOptions works for explicit paths", (t) => {
|
(0, ava_1.default)("getExtraOptions works for explicit paths", (t) => {
|
||||||
t.deepEqual(codeql.getExtraOptions({}, ["foo"], []), []);
|
t.deepEqual(codeql.getExtraOptions({}, ["foo"], []), []);
|
||||||
t.deepEqual(codeql.getExtraOptions({ foo: [42] }, ["foo"], []), ["42"]);
|
t.deepEqual(codeql.getExtraOptions({ foo: [42] }, ["foo"], []), ["42"]);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
19
lib/config-utils.js
generated
19
lib/config-utils.js
generated
@@ -131,7 +131,11 @@ async function addDefaultQueries(codeQL, languages, resultMap) {
|
|||||||
await runResolveQueries(codeQL, resultMap, suites, undefined);
|
await runResolveQueries(codeQL, resultMap, suites, undefined);
|
||||||
}
|
}
|
||||||
// The set of acceptable values for built-in suites from the codeql bundle
|
// The set of acceptable values for built-in suites from the codeql bundle
|
||||||
const builtinSuites = ["security-extended", "security-and-quality"];
|
const builtinSuites = [
|
||||||
|
"security-experimental",
|
||||||
|
"security-extended",
|
||||||
|
"security-and-quality",
|
||||||
|
];
|
||||||
/**
|
/**
|
||||||
* Determine the set of queries associated with suiteName's suites and add them to resultMap.
|
* Determine the set of queries associated with suiteName's suites and add them to resultMap.
|
||||||
* Throws an error if suiteName is not a valid builtin suite.
|
* Throws an error if suiteName is not a valid builtin suite.
|
||||||
@@ -143,6 +147,12 @@ async function addBuiltinSuiteQueries(languages, codeQL, resultMap, packs, suite
|
|||||||
if (!found) {
|
if (!found) {
|
||||||
throw new Error(getQueryUsesInvalid(configFile, suiteName));
|
throw new Error(getQueryUsesInvalid(configFile, suiteName));
|
||||||
}
|
}
|
||||||
|
if (suiteName === "security-experimental" &&
|
||||||
|
!(await (0, util_1.codeQlVersionAbove)(codeQL, codeql_1.CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE))) {
|
||||||
|
throw new Error(`The 'security-experimental' suite is not supported on CodeQL CLI versions earlier than
|
||||||
|
${codeql_1.CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE}. Please upgrade to CodeQL CLI version
|
||||||
|
${codeql_1.CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE} or later.`);
|
||||||
|
}
|
||||||
// If we're running the JavaScript security-extended analysis (or a superset of it), the repo is
|
// If we're running the JavaScript security-extended analysis (or a superset of it), the repo is
|
||||||
// opted into the ML-powered queries beta, and a user hasn't already added the ML-powered query
|
// opted into the ML-powered queries beta, and a user hasn't already added the ML-powered query
|
||||||
// pack, then add the ML-powered query pack so that we run ML-powered queries.
|
// pack, then add the ML-powered query pack so that we run ML-powered queries.
|
||||||
@@ -151,7 +161,9 @@ async function addBuiltinSuiteQueries(languages, codeQL, resultMap, packs, suite
|
|||||||
(process.platform !== "win32" ||
|
(process.platform !== "win32" ||
|
||||||
(await (0, util_1.codeQlVersionAbove)(codeQL, codeql_1.CODEQL_VERSION_ML_POWERED_QUERIES_WINDOWS))) &&
|
(await (0, util_1.codeQlVersionAbove)(codeQL, codeql_1.CODEQL_VERSION_ML_POWERED_QUERIES_WINDOWS))) &&
|
||||||
languages.includes("javascript") &&
|
languages.includes("javascript") &&
|
||||||
(found === "security-extended" || found === "security-and-quality") &&
|
(found === "security-experimental" ||
|
||||||
|
found === "security-extended" ||
|
||||||
|
found === "security-and-quality") &&
|
||||||
!packs.javascript?.some(isMlPoweredJsQueriesPack) &&
|
!packs.javascript?.some(isMlPoweredJsQueriesPack) &&
|
||||||
(await featureEnablement.getValue(feature_flags_1.Feature.MlPoweredQueriesEnabled, codeQL))) {
|
(await featureEnablement.getValue(feature_flags_1.Feature.MlPoweredQueriesEnabled, codeQL))) {
|
||||||
if (!packs.javascript) {
|
if (!packs.javascript) {
|
||||||
@@ -893,7 +905,8 @@ exports.parsePacks = parsePacks;
|
|||||||
* Without a '+', an input value will override the corresponding value in the config file.
|
* Without a '+', an input value will override the corresponding value in the config file.
|
||||||
*
|
*
|
||||||
* @param inputValue The input value to process.
|
* @param inputValue The input value to process.
|
||||||
* @returns true if the input value should replace the corresponding value in the config file, false if it should be appended.
|
* @returns true if the input value should replace the corresponding value in the config file,
|
||||||
|
* false if it should be appended.
|
||||||
*/
|
*/
|
||||||
function shouldCombine(inputValue) {
|
function shouldCombine(inputValue) {
|
||||||
return !!inputValue?.trim().startsWith("+");
|
return !!inputValue?.trim().startsWith("+");
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
5
lib/config-utils.test.js
generated
5
lib/config-utils.test.js
generated
@@ -1014,7 +1014,7 @@ const mlPoweredQueriesMacro = ava_1.default.macro({
|
|||||||
// Test that the ~0.1.0 version of ML-powered queries is run on v2.8.3 of the CLI.
|
// Test that the ~0.1.0 version of ML-powered queries is run on v2.8.3 of the CLI.
|
||||||
(0, ava_1.default)(mlPoweredQueriesMacro, "2.8.3", true, undefined, "security-extended", process.platform === "win32" ? undefined : "~0.1.0");
|
(0, ava_1.default)(mlPoweredQueriesMacro, "2.8.3", true, undefined, "security-extended", process.platform === "win32" ? undefined : "~0.1.0");
|
||||||
// Test that ML-powered queries aren't run when the user hasn't specified that we should run the
|
// Test that ML-powered queries aren't run when the user hasn't specified that we should run the
|
||||||
// `security-extended` or `security-and-quality` query suite.
|
// `security-extended`, `security-and-quality`, or `security-experimental` query suite.
|
||||||
(0, ava_1.default)(mlPoweredQueriesMacro, "2.7.5", true, undefined, undefined, undefined);
|
(0, ava_1.default)(mlPoweredQueriesMacro, "2.7.5", true, undefined, undefined, undefined);
|
||||||
// Test that ML-powered queries are run on non-Windows platforms running `security-extended` on
|
// Test that ML-powered queries are run on non-Windows platforms running `security-extended` on
|
||||||
// versions of the CodeQL CLI prior to 2.9.0.
|
// versions of the CodeQL CLI prior to 2.9.0.
|
||||||
@@ -1042,6 +1042,9 @@ const mlPoweredQueriesMacro = ava_1.default.macro({
|
|||||||
// Test that ML-powered queries are run on all platforms running `security-and-quality` on CodeQL
|
// Test that ML-powered queries are run on all platforms running `security-and-quality` on CodeQL
|
||||||
// CLI 2.11.3+.
|
// CLI 2.11.3+.
|
||||||
(0, ava_1.default)(mlPoweredQueriesMacro, "2.11.3", true, undefined, "security-and-quality", "~0.4.0");
|
(0, ava_1.default)(mlPoweredQueriesMacro, "2.11.3", true, undefined, "security-and-quality", "~0.4.0");
|
||||||
|
// Test that ML-powered queries are run on all platforms running `security-experimental` on CodeQL
|
||||||
|
// CLI 2.12.1+.
|
||||||
|
(0, ava_1.default)(mlPoweredQueriesMacro, "2.12.1", true, undefined, "security-experimental", "~0.4.0");
|
||||||
const calculateAugmentationMacro = ava_1.default.macro({
|
const calculateAugmentationMacro = ava_1.default.macro({
|
||||||
exec: async (t, _title, rawPacksInput, rawQueriesInput, languages, expectedAugmentationProperties) => {
|
exec: async (t, _title, rawPacksInput, rawQueriesInput, languages, expectedAugmentationProperties) => {
|
||||||
const actualAugmentationProperties = configUtils.calculateAugmentation(rawPacksInput, rawQueriesInput, languages);
|
const actualAugmentationProperties = configUtils.calculateAugmentation(rawPacksInput, rawQueriesInput, languages);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"bundleVersion": "codeql-bundle-20230120",
|
"bundleVersion": "codeql-bundle-20230207",
|
||||||
"cliVersion": "2.12.1",
|
"cliVersion": "2.12.2",
|
||||||
"priorBundleVersion": "codeql-bundle-20230105",
|
"priorBundleVersion": "codeql-bundle-20230120",
|
||||||
"priorCliVersion": "2.12.0"
|
"priorCliVersion": "2.12.1"
|
||||||
}
|
}
|
||||||
|
|||||||
37
lib/feature-flags.js
generated
37
lib/feature-flags.js
generated
@@ -34,27 +34,12 @@ const DEFAULT_VERSION_FEATURE_FLAG_PREFIX = "default_codeql_version_";
|
|||||||
const DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled";
|
const DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled";
|
||||||
var Feature;
|
var Feature;
|
||||||
(function (Feature) {
|
(function (Feature) {
|
||||||
Feature["BypassToolcacheEnabled"] = "bypass_toolcache_enabled";
|
|
||||||
Feature["BypassToolcacheKotlinSwiftEnabled"] = "bypass_toolcache_kotlin_swift_enabled";
|
|
||||||
Feature["CliConfigFileEnabled"] = "cli_config_file_enabled";
|
Feature["CliConfigFileEnabled"] = "cli_config_file_enabled";
|
||||||
Feature["DisableKotlinAnalysisEnabled"] = "disable_kotlin_analysis_enabled";
|
Feature["DisableKotlinAnalysisEnabled"] = "disable_kotlin_analysis_enabled";
|
||||||
Feature["MlPoweredQueriesEnabled"] = "ml_powered_queries_enabled";
|
Feature["MlPoweredQueriesEnabled"] = "ml_powered_queries_enabled";
|
||||||
Feature["TrapCachingEnabled"] = "trap_caching_enabled";
|
|
||||||
Feature["UploadFailedSarifEnabled"] = "upload_failed_sarif_enabled";
|
Feature["UploadFailedSarifEnabled"] = "upload_failed_sarif_enabled";
|
||||||
})(Feature = exports.Feature || (exports.Feature = {}));
|
})(Feature = exports.Feature || (exports.Feature = {}));
|
||||||
exports.featureConfig = {
|
exports.featureConfig = {
|
||||||
[Feature.BypassToolcacheEnabled]: {
|
|
||||||
envVar: "CODEQL_BYPASS_TOOLCACHE",
|
|
||||||
// Cannot specify a minimum version because this flag is checked before we have
|
|
||||||
// access to the CodeQL instance.
|
|
||||||
minimumVersion: undefined,
|
|
||||||
},
|
|
||||||
[Feature.BypassToolcacheKotlinSwiftEnabled]: {
|
|
||||||
envVar: "CODEQL_BYPASS_TOOLCACHE_KOTLIN_SWIFT",
|
|
||||||
// Cannot specify a minimum version because this flag is checked before we have
|
|
||||||
// access to the CodeQL instance.
|
|
||||||
minimumVersion: undefined,
|
|
||||||
},
|
|
||||||
[Feature.DisableKotlinAnalysisEnabled]: {
|
[Feature.DisableKotlinAnalysisEnabled]: {
|
||||||
envVar: "CODEQL_DISABLE_KOTLIN_ANALYSIS",
|
envVar: "CODEQL_DISABLE_KOTLIN_ANALYSIS",
|
||||||
minimumVersion: undefined,
|
minimumVersion: undefined,
|
||||||
@@ -67,10 +52,6 @@ exports.featureConfig = {
|
|||||||
envVar: "CODEQL_ML_POWERED_QUERIES",
|
envVar: "CODEQL_ML_POWERED_QUERIES",
|
||||||
minimumVersion: "2.7.5",
|
minimumVersion: "2.7.5",
|
||||||
},
|
},
|
||||||
[Feature.TrapCachingEnabled]: {
|
|
||||||
envVar: "CODEQL_TRAP_CACHING",
|
|
||||||
minimumVersion: undefined,
|
|
||||||
},
|
|
||||||
[Feature.UploadFailedSarifEnabled]: {
|
[Feature.UploadFailedSarifEnabled]: {
|
||||||
envVar: "CODEQL_ACTION_UPLOAD_FAILED_SARIF",
|
envVar: "CODEQL_ACTION_UPLOAD_FAILED_SARIF",
|
||||||
minimumVersion: "2.11.3",
|
minimumVersion: "2.11.3",
|
||||||
@@ -105,10 +86,6 @@ class Features {
|
|||||||
if (!codeql && exports.featureConfig[feature].minimumVersion) {
|
if (!codeql && exports.featureConfig[feature].minimumVersion) {
|
||||||
throw new Error(`Internal error: A minimum version is specified for feature ${feature}, but no instance of CodeQL was provided.`);
|
throw new Error(`Internal error: A minimum version is specified for feature ${feature}, but no instance of CodeQL was provided.`);
|
||||||
}
|
}
|
||||||
// Bypassing the toolcache is disabled in test mode.
|
|
||||||
if (feature === Feature.BypassToolcacheEnabled && util.isInTestMode()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const envVar = (process.env[exports.featureConfig[feature].envVar] || "").toLocaleLowerCase();
|
const envVar = (process.env[exports.featureConfig[feature].envVar] || "").toLocaleLowerCase();
|
||||||
// Do not use this feature if user explicitly disables it via an environment variable.
|
// Do not use this feature if user explicitly disables it via an environment variable.
|
||||||
if (envVar === "false") {
|
if (envVar === "false") {
|
||||||
@@ -136,7 +113,7 @@ class GitHubFeatureFlags {
|
|||||||
this.repositoryNwo = repositoryNwo;
|
this.repositoryNwo = repositoryNwo;
|
||||||
this.featureFlagsFile = featureFlagsFile;
|
this.featureFlagsFile = featureFlagsFile;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
/**/
|
this.hasAccessedRemoteFeatureFlags = false; // Not accessed by default.
|
||||||
}
|
}
|
||||||
getCliVersionFromFeatureFlag(f) {
|
getCliVersionFromFeatureFlag(f) {
|
||||||
if (!f.startsWith(DEFAULT_VERSION_FEATURE_FLAG_PREFIX) ||
|
if (!f.startsWith(DEFAULT_VERSION_FEATURE_FLAG_PREFIX) ||
|
||||||
@@ -157,7 +134,9 @@ class GitHubFeatureFlags {
|
|||||||
const defaultDotComCliVersion = await this.getDefaultDotcomCliVersion();
|
const defaultDotComCliVersion = await this.getDefaultDotcomCliVersion();
|
||||||
return {
|
return {
|
||||||
cliVersion: defaultDotComCliVersion.version,
|
cliVersion: defaultDotComCliVersion.version,
|
||||||
toolsFeatureFlagsValid: defaultDotComCliVersion.toolsFeatureFlagsValid,
|
toolsFeatureFlagsValid: this.hasAccessedRemoteFeatureFlags
|
||||||
|
? defaultDotComCliVersion.toolsFeatureFlagsValid
|
||||||
|
: undefined,
|
||||||
variant,
|
variant,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -188,7 +167,9 @@ class GitHubFeatureFlags {
|
|||||||
`shipped with the Action. This is ${defaults.cliVersion}.`);
|
`shipped with the Action. This is ${defaults.cliVersion}.`);
|
||||||
return {
|
return {
|
||||||
version: defaults.cliVersion,
|
version: defaults.cliVersion,
|
||||||
toolsFeatureFlagsValid: false,
|
toolsFeatureFlagsValid: this.hasAccessedRemoteFeatureFlags
|
||||||
|
? false
|
||||||
|
: undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const maxCliVersion = enabledFeatureFlagCliVersions.reduce((maxVersion, currentVersion) => currentVersion > maxVersion ? currentVersion : maxVersion, enabledFeatureFlagCliVersions[0]);
|
const maxCliVersion = enabledFeatureFlagCliVersions.reduce((maxVersion, currentVersion) => currentVersion > maxVersion ? currentVersion : maxVersion, enabledFeatureFlagCliVersions[0]);
|
||||||
@@ -255,6 +236,7 @@ class GitHubFeatureFlags {
|
|||||||
// Do nothing when not running against github.com
|
// Do nothing when not running against github.com
|
||||||
if (this.gitHubVersion.type !== util.GitHubVariant.DOTCOM) {
|
if (this.gitHubVersion.type !== util.GitHubVariant.DOTCOM) {
|
||||||
this.logger.debug("Not running against github.com. Disabling all toggleable features.");
|
this.logger.debug("Not running against github.com. Disabling all toggleable features.");
|
||||||
|
this.hasAccessedRemoteFeatureFlags = false;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -265,6 +247,7 @@ class GitHubFeatureFlags {
|
|||||||
const remoteFlags = response.data;
|
const remoteFlags = response.data;
|
||||||
this.logger.debug("Loaded the following default values for the feature flags from the Code Scanning API: " +
|
this.logger.debug("Loaded the following default values for the feature flags from the Code Scanning API: " +
|
||||||
`${JSON.stringify(remoteFlags)}`);
|
`${JSON.stringify(remoteFlags)}`);
|
||||||
|
this.hasAccessedRemoteFeatureFlags = true;
|
||||||
return remoteFlags;
|
return remoteFlags;
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
@@ -273,6 +256,7 @@ class GitHubFeatureFlags {
|
|||||||
"As a result, it will not be opted into any experimental features. " +
|
"As a result, it will not be opted into any experimental features. " +
|
||||||
"This could be because the Action is running on a pull request from a fork. If not, " +
|
"This could be because the Action is running on a pull request from a fork. If not, " +
|
||||||
`please ensure the Action has the 'security-events: write' permission. Details: ${e}`);
|
`please ensure the Action has the 'security-events: write' permission. Details: ${e}`);
|
||||||
|
this.hasAccessedRemoteFeatureFlags = false;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -283,7 +267,6 @@ class GitHubFeatureFlags {
|
|||||||
throw new Error(`Encountered an error while trying to determine feature enablement: ${e}`);
|
throw new Error(`Encountered an error while trying to determine feature enablement: ${e}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//# sourceMappingURL=feature-flags.js.map
|
//# sourceMappingURL=feature-flags.js.map
|
||||||
File diff suppressed because one or more lines are too long
23
lib/init-action.js
generated
23
lib/init-action.js
generated
@@ -46,12 +46,13 @@ async function sendInitStatusReport(actionStatus, startedAt, config, toolsDownlo
|
|||||||
tools_source: toolsSource || init_1.ToolsSource.Unknown,
|
tools_source: toolsSource || init_1.ToolsSource.Unknown,
|
||||||
workflow_languages: workflowLanguages || "",
|
workflow_languages: workflowLanguages || "",
|
||||||
};
|
};
|
||||||
let initToolsDownloadFields = {};
|
const initToolsDownloadFields = {};
|
||||||
if (toolsSource === init_1.ToolsSource.Download) {
|
if (toolsDownloadDurationMs !== undefined) {
|
||||||
initToolsDownloadFields = {
|
initToolsDownloadFields.tools_download_duration_ms =
|
||||||
tools_download_duration_ms: toolsDownloadDurationMs,
|
toolsDownloadDurationMs;
|
||||||
tools_feature_flags_valid: toolsFeatureFlagsValid,
|
}
|
||||||
};
|
if (toolsFeatureFlagsValid !== undefined) {
|
||||||
|
initToolsDownloadFields.tools_feature_flags_valid = toolsFeatureFlagsValid;
|
||||||
}
|
}
|
||||||
if (config !== undefined) {
|
if (config !== undefined) {
|
||||||
const languages = config.languages.join(",");
|
const languages = config.languages.join(",");
|
||||||
@@ -122,13 +123,13 @@ async function run() {
|
|||||||
if (codeQLDefaultVersionInfo.variant === util_1.GitHubVariant.DOTCOM) {
|
if (codeQLDefaultVersionInfo.variant === util_1.GitHubVariant.DOTCOM) {
|
||||||
toolsFeatureFlagsValid = codeQLDefaultVersionInfo.toolsFeatureFlagsValid;
|
toolsFeatureFlagsValid = codeQLDefaultVersionInfo.toolsFeatureFlagsValid;
|
||||||
}
|
}
|
||||||
const initCodeQLResult = await (0, init_1.initCodeQL)((0, actions_util_1.getOptionalInput)("tools"), apiDetails, (0, actions_util_1.getTemporaryDirectory)(), gitHubVersion.type, await (0, util_1.shouldBypassToolcache)(features, (0, actions_util_1.getOptionalInput)("tools"), (0, actions_util_1.getOptionalInput)("languages"), repositoryNwo, logger), codeQLDefaultVersionInfo, logger);
|
const initCodeQLResult = await (0, init_1.initCodeQL)((0, actions_util_1.getOptionalInput)("tools"), apiDetails, (0, actions_util_1.getTemporaryDirectory)(), gitHubVersion.type, codeQLDefaultVersionInfo, logger);
|
||||||
codeql = initCodeQLResult.codeql;
|
codeql = initCodeQLResult.codeql;
|
||||||
toolsDownloadDurationMs = initCodeQLResult.toolsDownloadDurationMs;
|
toolsDownloadDurationMs = initCodeQLResult.toolsDownloadDurationMs;
|
||||||
toolsVersion = initCodeQLResult.toolsVersion;
|
toolsVersion = initCodeQLResult.toolsVersion;
|
||||||
toolsSource = initCodeQLResult.toolsSource;
|
toolsSource = initCodeQLResult.toolsSource;
|
||||||
await (0, util_1.enrichEnvironment)(codeql);
|
await (0, util_1.enrichEnvironment)(codeql);
|
||||||
config = await (0, init_1.initConfig)((0, actions_util_1.getOptionalInput)("languages"), (0, actions_util_1.getOptionalInput)("queries"), (0, actions_util_1.getOptionalInput)("packs"), (0, actions_util_1.getOptionalInput)("registries"), (0, actions_util_1.getOptionalInput)("config-file"), (0, actions_util_1.getOptionalInput)("db-location"), await getTrapCachingEnabled(features),
|
config = await (0, init_1.initConfig)((0, actions_util_1.getOptionalInput)("languages"), (0, actions_util_1.getOptionalInput)("queries"), (0, actions_util_1.getOptionalInput)("packs"), (0, actions_util_1.getOptionalInput)("registries"), (0, actions_util_1.getOptionalInput)("config-file"), (0, actions_util_1.getOptionalInput)("db-location"), getTrapCachingEnabled(),
|
||||||
// Debug mode is enabled if:
|
// Debug mode is enabled if:
|
||||||
// - The `init` Action is passed `debug: true`.
|
// - The `init` Action is passed `debug: true`.
|
||||||
// - Actions step debugging is enabled (e.g. by [enabling debug logging for a rerun](https://docs.github.com/en/actions/managing-workflow-runs/re-running-workflows-and-jobs#re-running-all-the-jobs-in-a-workflow),
|
// - Actions step debugging is enabled (e.g. by [enabling debug logging for a rerun](https://docs.github.com/en/actions/managing-workflow-runs/re-running-workflows-and-jobs#re-running-all-the-jobs-in-a-workflow),
|
||||||
@@ -192,7 +193,7 @@ async function run() {
|
|||||||
}
|
}
|
||||||
await sendInitStatusReport("success", startedAt, config, toolsDownloadDurationMs, toolsFeatureFlagsValid, toolsSource, toolsVersion, logger);
|
await sendInitStatusReport("success", startedAt, config, toolsDownloadDurationMs, toolsFeatureFlagsValid, toolsSource, toolsVersion, logger);
|
||||||
}
|
}
|
||||||
async function getTrapCachingEnabled(featureEnablement) {
|
function getTrapCachingEnabled() {
|
||||||
// If the workflow specified something always respect that
|
// If the workflow specified something always respect that
|
||||||
const trapCaching = (0, actions_util_1.getOptionalInput)("trap-caching");
|
const trapCaching = (0, actions_util_1.getOptionalInput)("trap-caching");
|
||||||
if (trapCaching !== undefined)
|
if (trapCaching !== undefined)
|
||||||
@@ -200,8 +201,8 @@ async function getTrapCachingEnabled(featureEnablement) {
|
|||||||
// On self-hosted runners which may have slow network access, disable TRAP caching by default
|
// On self-hosted runners which may have slow network access, disable TRAP caching by default
|
||||||
if (!(0, util_1.isHostedRunner)())
|
if (!(0, util_1.isHostedRunner)())
|
||||||
return false;
|
return false;
|
||||||
// On hosted runners, respect the feature flag
|
// On hosted runners, enable TRAP caching by default
|
||||||
return await featureEnablement.getValue(feature_flags_1.Feature.TrapCachingEnabled);
|
return true;
|
||||||
}
|
}
|
||||||
async function runWrapper() {
|
async function runWrapper() {
|
||||||
try {
|
try {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
4
lib/init.js
generated
4
lib/init.js
generated
@@ -41,9 +41,9 @@ var ToolsSource;
|
|||||||
ToolsSource["Toolcache"] = "TOOLCACHE";
|
ToolsSource["Toolcache"] = "TOOLCACHE";
|
||||||
ToolsSource["Download"] = "DOWNLOAD";
|
ToolsSource["Download"] = "DOWNLOAD";
|
||||||
})(ToolsSource = exports.ToolsSource || (exports.ToolsSource = {}));
|
})(ToolsSource = exports.ToolsSource || (exports.ToolsSource = {}));
|
||||||
async function initCodeQL(toolsInput, apiDetails, tempDir, variant, bypassToolcache, defaultCliVersion, logger) {
|
async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger) {
|
||||||
logger.startGroup("Setup CodeQL tools");
|
logger.startGroup("Setup CodeQL tools");
|
||||||
const { codeql, toolsDownloadDurationMs, toolsSource, toolsVersion } = await (0, codeql_1.setupCodeQL)(toolsInput, apiDetails, tempDir, variant, bypassToolcache, defaultCliVersion, logger, true);
|
const { codeql, toolsDownloadDurationMs, toolsSource, toolsVersion } = await (0, codeql_1.setupCodeQL)(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger, true);
|
||||||
await codeql.printVersion();
|
await codeql.printVersion();
|
||||||
logger.endGroup();
|
logger.endGroup();
|
||||||
return { codeql, toolsDownloadDurationMs, toolsSource, toolsVersion };
|
return { codeql, toolsDownloadDurationMs, toolsSource, toolsVersion };
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
|
||||||
3
lib/languages.js
generated
3
lib/languages.js
generated
@@ -1,6 +1,6 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.isScannedLanguage = exports.isTracedLanguage = exports.parseLanguage = exports.resolveAlias = exports.KOTLIN_SWIFT_BYPASS = exports.LANGUAGE_ALIASES = exports.Language = void 0;
|
exports.isScannedLanguage = exports.isTracedLanguage = exports.parseLanguage = exports.resolveAlias = exports.LANGUAGE_ALIASES = exports.Language = void 0;
|
||||||
// All the languages supported by CodeQL
|
// All the languages supported by CodeQL
|
||||||
var Language;
|
var Language;
|
||||||
(function (Language) {
|
(function (Language) {
|
||||||
@@ -21,7 +21,6 @@ exports.LANGUAGE_ALIASES = {
|
|||||||
kotlin: Language.java,
|
kotlin: Language.java,
|
||||||
typescript: Language.javascript,
|
typescript: Language.javascript,
|
||||||
};
|
};
|
||||||
exports.KOTLIN_SWIFT_BYPASS = ["kotlin", "swift"];
|
|
||||||
function resolveAlias(lang) {
|
function resolveAlias(lang) {
|
||||||
return exports.LANGUAGE_ALIASES[lang] || lang;
|
return exports.LANGUAGE_ALIASES[lang] || lang;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"languages.js","sourceRoot":"","sources":["../src/languages.ts"],"names":[],"mappings":";;;AAAA,wCAAwC;AACxC,IAAY,QASX;AATD,WAAY,QAAQ;IAClB,6BAAiB,CAAA;IACjB,uBAAW,CAAA;IACX,qBAAS,CAAA;IACT,yBAAa,CAAA;IACb,qCAAyB,CAAA;IACzB,6BAAiB,CAAA;IACjB,yBAAa,CAAA;IACb,2BAAe,CAAA;AACjB,CAAC,EATW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QASnB;AAED,iCAAiC;AACpB,QAAA,gBAAgB,GAAiC;IAC5D,CAAC,EAAE,QAAQ,CAAC,GAAG;IACf,KAAK,EAAE,QAAQ,CAAC,GAAG;IACnB,IAAI,EAAE,QAAQ,CAAC,MAAM;IACrB,MAAM,EAAE,QAAQ,CAAC,IAAI;IACrB,UAAU,EAAE,QAAQ,CAAC,UAAU;CAChC,CAAC;AAIW,QAAA,mBAAmB,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAEvD,SAAgB,YAAY,CAAC,IAAqB;IAChD,OAAO,wBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;AACxC,CAAC;AAFD,oCAEC;AAED;;;;;;;;;GASG;AACH,SAAgB,aAAa,CAAC,QAAgB;IAC5C,0BAA0B;IAC1B,QAAQ,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAEzC,6BAA6B;IAC7B,IAAI,QAAQ,IAAI,QAAQ,EAAE;QACxB,OAAO,QAAoB,CAAC;KAC7B;IAED,iEAAiE;IACjE,oCAAoC;IACpC,IAAI,QAAQ,IAAI,wBAAgB,EAAE;QAChC,OAAO,QAAQ,CAAC;KACjB;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAhBD,sCAgBC;AAED,SAAgB,gBAAgB,CAAC,QAAkB;IACjD,OAAO;QACL,QAAQ,CAAC,GAAG;QACZ,QAAQ,CAAC,MAAM;QACf,QAAQ,CAAC,EAAE;QACX,QAAQ,CAAC,IAAI;QACb,QAAQ,CAAC,KAAK;KACf,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACvB,CAAC;AARD,4CAQC;AAED,SAAgB,iBAAiB,CAAC,QAAkB;IAClD,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;AACrC,CAAC;AAFD,8CAEC"}
|
{"version":3,"file":"languages.js","sourceRoot":"","sources":["../src/languages.ts"],"names":[],"mappings":";;;AAAA,wCAAwC;AACxC,IAAY,QASX;AATD,WAAY,QAAQ;IAClB,6BAAiB,CAAA;IACjB,uBAAW,CAAA;IACX,qBAAS,CAAA;IACT,yBAAa,CAAA;IACb,qCAAyB,CAAA;IACzB,6BAAiB,CAAA;IACjB,yBAAa,CAAA;IACb,2BAAe,CAAA;AACjB,CAAC,EATW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QASnB;AAED,iCAAiC;AACpB,QAAA,gBAAgB,GAAiC;IAC5D,CAAC,EAAE,QAAQ,CAAC,GAAG;IACf,KAAK,EAAE,QAAQ,CAAC,GAAG;IACnB,IAAI,EAAE,QAAQ,CAAC,MAAM;IACrB,MAAM,EAAE,QAAQ,CAAC,IAAI;IACrB,UAAU,EAAE,QAAQ,CAAC,UAAU;CAChC,CAAC;AAIF,SAAgB,YAAY,CAAC,IAAqB;IAChD,OAAO,wBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;AACxC,CAAC;AAFD,oCAEC;AAED;;;;;;;;;GASG;AACH,SAAgB,aAAa,CAAC,QAAgB;IAC5C,0BAA0B;IAC1B,QAAQ,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAEzC,6BAA6B;IAC7B,IAAI,QAAQ,IAAI,QAAQ,EAAE;QACxB,OAAO,QAAoB,CAAC;KAC7B;IAED,iEAAiE;IACjE,oCAAoC;IACpC,IAAI,QAAQ,IAAI,wBAAgB,EAAE;QAChC,OAAO,QAAQ,CAAC;KACjB;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAhBD,sCAgBC;AAED,SAAgB,gBAAgB,CAAC,QAAkB;IACjD,OAAO;QACL,QAAQ,CAAC,GAAG;QACZ,QAAQ,CAAC,MAAM;QACf,QAAQ,CAAC,EAAE;QACX,QAAQ,CAAC,IAAI;QACb,QAAQ,CAAC,KAAK;KACf,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACvB,CAAC;AARD,4CAQC;AAED,SAAgB,iBAAiB,CAAC,QAAkB;IAClD,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;AACrC,CAAC;AAFD,8CAEC"}
|
||||||
277
lib/setup-codeql.js
generated
277
lib/setup-codeql.js
generated
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.setupCodeQLBundle = exports.getCodeQLURLVersion = exports.downloadCodeQL = exports.getCodeQLSource = exports.convertToSemVer = exports.getBundleVersionFromUrl = exports.tryFindCliVersionDotcomOnly = exports.findCodeQLBundleTagDotcomOnly = exports.getCodeQLActionRepository = exports.CODEQL_DEFAULT_ACTION_REPOSITORY = void 0;
|
exports.setupCodeQLBundle = exports.getCodeQLURLVersion = exports.downloadCodeQL = exports.tryGetFallbackToolcacheVersion = exports.getCodeQLSource = exports.convertToSemVer = exports.tryGetBundleVersionFromUrl = exports.tryFindCliVersionDotcomOnly = exports.findCodeQLBundleTagDotcomOnly = exports.getCodeQLActionRepository = exports.CODEQL_DEFAULT_ACTION_REPOSITORY = void 0;
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
const perf_hooks_1 = require("perf_hooks");
|
const perf_hooks_1 = require("perf_hooks");
|
||||||
@@ -211,21 +211,30 @@ async function getCodeQLBundleDownloadURL(tagName, apiDetails, variant, logger)
|
|||||||
}
|
}
|
||||||
return `https://github.com/${exports.CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${codeQLBundleName}`;
|
return `https://github.com/${exports.CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${codeQLBundleName}`;
|
||||||
}
|
}
|
||||||
function getBundleVersionFromTagName(tagName) {
|
function tryGetBundleVersionFromTagName(tagName, logger) {
|
||||||
const match = tagName.match(/^codeql-bundle-(.*)$/);
|
const match = tagName.match(/^codeql-bundle-(.*)$/);
|
||||||
if (match === null || match.length < 2) {
|
if (match === null || match.length < 2) {
|
||||||
throw new Error(`Malformed bundle tag name: ${tagName}. Bundle version could not be inferred`);
|
logger.debug(`Could not determine bundle version from tag ${tagName}.`);
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
return match[1];
|
return match[1];
|
||||||
}
|
}
|
||||||
function getBundleVersionFromUrl(url) {
|
function tryGetTagNameFromUrl(url, logger) {
|
||||||
const match = url.match(/\/(codeql-bundle-.*)\//);
|
const match = url.match(/\/(codeql-bundle-.*)\//);
|
||||||
if (match === null || match.length < 2) {
|
if (match === null || match.length < 2) {
|
||||||
throw new Error(`Malformed tools url: ${url}. Bundle version could not be inferred`);
|
logger.debug(`Could not determine tag name for URL ${url}.`);
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
return getBundleVersionFromTagName(match[1]);
|
return match[1];
|
||||||
}
|
}
|
||||||
exports.getBundleVersionFromUrl = getBundleVersionFromUrl;
|
function tryGetBundleVersionFromUrl(url, logger) {
|
||||||
|
const tagName = tryGetTagNameFromUrl(url, logger);
|
||||||
|
if (tagName === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return tryGetBundleVersionFromTagName(tagName, logger);
|
||||||
|
}
|
||||||
|
exports.tryGetBundleVersionFromUrl = tryGetBundleVersionFromUrl;
|
||||||
function convertToSemVer(version, logger) {
|
function convertToSemVer(version, logger) {
|
||||||
if (!semver.valid(version)) {
|
if (!semver.valid(version)) {
|
||||||
logger.debug(`Bundle version ${version} is not in SemVer format. Will treat it as pre-release 0.0.0-${version}.`);
|
logger.debug(`Bundle version ${version} is not in SemVer format. Will treat it as pre-release 0.0.0-${version}.`);
|
||||||
@@ -238,18 +247,10 @@ function convertToSemVer(version, logger) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
exports.convertToSemVer = convertToSemVer;
|
exports.convertToSemVer = convertToSemVer;
|
||||||
async function getOrFindBundleTagName(version, logger) {
|
|
||||||
if (version.variant === util.GitHubVariant.DOTCOM) {
|
|
||||||
return await findCodeQLBundleTagDotcomOnly(version.cliVersion, logger);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return version.tagName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Look for a version of the CodeQL tools in the cache which could override the requested CLI version.
|
* Look for a version of the CodeQL tools in the cache which could override the requested CLI version.
|
||||||
*/
|
*/
|
||||||
async function findOverridingToolsInCache(requestedCliVersion, logger) {
|
async function findOverridingToolsInCache(humanReadableVersion, logger) {
|
||||||
const candidates = toolcache
|
const candidates = toolcache
|
||||||
.findAllVersions("CodeQL")
|
.findAllVersions("CodeQL")
|
||||||
.filter(util_1.isGoodVersion)
|
.filter(util_1.isGoodVersion)
|
||||||
@@ -260,7 +261,7 @@ async function findOverridingToolsInCache(requestedCliVersion, logger) {
|
|||||||
.filter(({ folder }) => fs.existsSync(path.join(folder, "pinned-version")));
|
.filter(({ folder }) => fs.existsSync(path.join(folder, "pinned-version")));
|
||||||
if (candidates.length === 1) {
|
if (candidates.length === 1) {
|
||||||
const candidate = candidates[0];
|
const candidate = candidates[0];
|
||||||
logger.debug(`CodeQL tools version ${candidate.version} in toolcache overriding version ${requestedCliVersion}.`);
|
logger.debug(`CodeQL tools version ${candidate.version} in toolcache overriding version ${humanReadableVersion}.`);
|
||||||
return {
|
return {
|
||||||
codeqlFolder: candidate.folder,
|
codeqlFolder: candidate.folder,
|
||||||
sourceType: "toolcache",
|
sourceType: "toolcache",
|
||||||
@@ -276,7 +277,7 @@ async function findOverridingToolsInCache(requestedCliVersion, logger) {
|
|||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
async function getCodeQLSource(toolsInput, bypassToolcache, defaultCliVersion, apiDetails, variant, logger) {
|
async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, logger) {
|
||||||
if (toolsInput && toolsInput !== "latest" && !toolsInput.startsWith("http")) {
|
if (toolsInput && toolsInput !== "latest" && !toolsInput.startsWith("http")) {
|
||||||
return {
|
return {
|
||||||
codeqlTarPath: toolsInput,
|
codeqlTarPath: toolsInput,
|
||||||
@@ -284,124 +285,166 @@ async function getCodeQLSource(toolsInput, bypassToolcache, defaultCliVersion, a
|
|||||||
toolsVersion: "local",
|
toolsVersion: "local",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const forceLatestReason =
|
|
||||||
// We use the special value of 'latest' to prioritize the version in the
|
|
||||||
// defaults over any pinned cached version.
|
|
||||||
toolsInput === "latest"
|
|
||||||
? '"tools: latest" was requested'
|
|
||||||
: // If the user hasn't requested a particular CodeQL version, then bypass
|
|
||||||
// the toolcache when the appropriate feature is enabled. This
|
|
||||||
// allows us to quickly rollback a broken bundle that has made its way
|
|
||||||
// into the toolcache.
|
|
||||||
toolsInput === undefined && bypassToolcache
|
|
||||||
? "a specific version of the CodeQL tools was not requested and the bypass toolcache feature is enabled"
|
|
||||||
: undefined;
|
|
||||||
const forceLatest = forceLatestReason !== undefined;
|
|
||||||
if (forceLatest) {
|
|
||||||
logger.debug(`Forcing the latest version of the CodeQL tools since ${forceLatestReason}.`);
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* The requested version is:
|
* Whether the tools shipped with the Action, i.e. those in `defaults.json`, have been forced.
|
||||||
*
|
*
|
||||||
* 1. The one in `defaults.json`, if forceLatest is true.
|
* We use the special value of 'latest' to prioritize the version in `defaults.json` over the
|
||||||
* 2. The version specified by the tools input URL, if one was provided.
|
* version specified by the feature flags on Dotcom and over any pinned cached version on
|
||||||
* 3. The default CLI version, otherwise.
|
* Enterprise Server.
|
||||||
|
|
||||||
* We include a `variant` property to let us verify using the type system that
|
|
||||||
* `tagName` is only undefined when the variant is Dotcom. This lets us ensure
|
|
||||||
* that we can always compute `tagName`, either by using the existing tag name
|
|
||||||
* on enterprise instances, or calling `findCodeQLBundleTagDotcomOnly` on
|
|
||||||
* Dotcom.
|
|
||||||
*/
|
*/
|
||||||
const requestedVersion = forceLatest
|
const forceShippedTools = toolsInput === "latest";
|
||||||
? // case 1
|
if (forceShippedTools) {
|
||||||
{
|
logger.info("Overriding the version of the CodeQL tools by the version shipped with the Action since " +
|
||||||
cliVersion: defaults.cliVersion,
|
`"tools: latest" was requested.`);
|
||||||
syntheticCliVersion: defaults.cliVersion,
|
|
||||||
tagName: defaults.bundleVersion,
|
|
||||||
variant,
|
|
||||||
}
|
}
|
||||||
: toolsInput !== undefined
|
/** CLI version number, for example 2.12.1. */
|
||||||
? // case 2
|
let cliVersion;
|
||||||
{
|
/** Tag name of the CodeQL bundle, for example `codeql-bundle-20230120`. */
|
||||||
syntheticCliVersion: convertToSemVer(getBundleVersionFromUrl(toolsInput), logger),
|
let tagName;
|
||||||
tagName: `codeql-bundle-${getBundleVersionFromUrl(toolsInput)}`,
|
/**
|
||||||
url: toolsInput,
|
* URL of the CodeQL bundle.
|
||||||
variant,
|
*
|
||||||
|
* This does not always include a tag name.
|
||||||
|
*/
|
||||||
|
let url;
|
||||||
|
if (forceShippedTools) {
|
||||||
|
cliVersion = defaults.cliVersion;
|
||||||
|
tagName = defaults.bundleVersion;
|
||||||
}
|
}
|
||||||
: // case 3
|
else if (toolsInput !== undefined) {
|
||||||
{
|
// If a tools URL was provided, then use that.
|
||||||
...defaultCliVersion,
|
tagName = tryGetTagNameFromUrl(toolsInput, logger);
|
||||||
syntheticCliVersion: defaultCliVersion.cliVersion,
|
url = toolsInput;
|
||||||
};
|
}
|
||||||
// If we find the specified version, we always use that.
|
else {
|
||||||
let codeqlFolder = toolcache.find("CodeQL", requestedVersion.syntheticCliVersion);
|
// Otherwise, use the default CLI version passed in.
|
||||||
let tagName = requestedVersion["tagName"];
|
cliVersion = defaultCliVersion.cliVersion;
|
||||||
|
tagName = defaultCliVersion["tagName"];
|
||||||
|
}
|
||||||
|
const bundleVersion = tagName && tryGetBundleVersionFromTagName(tagName, logger);
|
||||||
|
const humanReadableVersion = cliVersion ??
|
||||||
|
(bundleVersion && convertToSemVer(bundleVersion, logger)) ??
|
||||||
|
tagName ??
|
||||||
|
url ??
|
||||||
|
"unknown";
|
||||||
|
logger.debug("Attempting to obtain CodeQL tools. " +
|
||||||
|
`CLI version: ${cliVersion ?? "unknown"}, ` +
|
||||||
|
`bundle tag name: ${tagName ?? "unknown"}, ` +
|
||||||
|
`URL: ${url ?? "unspecified"}.`);
|
||||||
|
let codeqlFolder;
|
||||||
|
if (cliVersion) {
|
||||||
|
// If we find the specified CLI version, we always use that.
|
||||||
|
codeqlFolder = toolcache.find("CodeQL", cliVersion);
|
||||||
|
// Fall back to matching `x.y.z-<tagName>`.
|
||||||
if (!codeqlFolder) {
|
if (!codeqlFolder) {
|
||||||
logger.debug("Didn't find a version of the CodeQL tools in the toolcache with a version number " +
|
logger.debug("Didn't find a version of the CodeQL tools in the toolcache with a version number " +
|
||||||
`exactly matching ${requestedVersion.syntheticCliVersion}.`);
|
`exactly matching ${cliVersion}.`);
|
||||||
if (requestedVersion.cliVersion) {
|
|
||||||
const allVersions = toolcache.findAllVersions("CodeQL");
|
const allVersions = toolcache.findAllVersions("CodeQL");
|
||||||
logger.debug(`Found the following versions of the CodeQL tools in the toolcache: ${JSON.stringify(allVersions)}.`);
|
logger.debug(`Found the following versions of the CodeQL tools in the toolcache: ${JSON.stringify(allVersions)}.`);
|
||||||
// If there is exactly one version of the CodeQL tools in the toolcache, and that version is
|
// If there is exactly one version of the CodeQL tools in the toolcache, and that version is
|
||||||
// the form `x.y.z-<tagName>`, then use it.
|
// the form `x.y.z-<tagName>`, then use it.
|
||||||
const candidateVersions = allVersions.filter((version) => version.startsWith(`${requestedVersion.cliVersion}-`));
|
const candidateVersions = allVersions.filter((version) => version.startsWith(`${cliVersion}-`));
|
||||||
if (candidateVersions.length === 1) {
|
if (candidateVersions.length === 1) {
|
||||||
logger.debug("Exactly one candidate version found, using that.");
|
logger.debug(`Exactly one version of the CodeQL tools starting with ${cliVersion} found in the ` +
|
||||||
|
"toolcache, using that.");
|
||||||
codeqlFolder = toolcache.find("CodeQL", candidateVersions[0]);
|
codeqlFolder = toolcache.find("CodeQL", candidateVersions[0]);
|
||||||
}
|
}
|
||||||
|
else if (candidateVersions.length === 0) {
|
||||||
|
logger.debug(`Didn't find any versions of the CodeQL tools starting with ${cliVersion} ` +
|
||||||
|
`in the toolcache. Trying next fallback method.`);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
logger.debug("Did not find exactly one version of the CodeQL tools starting with the requested version.");
|
logger.warning(`Found ${candidateVersions.length} versions of the CodeQL tools starting with ` +
|
||||||
|
`${cliVersion} in the toolcache, but at most one was expected.`);
|
||||||
|
logger.debug("Trying next fallback method.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!codeqlFolder && requestedVersion.cliVersion) {
|
// Fall back to matching `0.0.0-<bundleVersion>`.
|
||||||
// Fall back to accepting a `0.0.0-<bundleVersion>` version if we didn't find the
|
if (!codeqlFolder && (cliVersion || tagName)) {
|
||||||
// `x.y.z` version. This is to support old versions of the toolcache.
|
if (cliVersion || tagName) {
|
||||||
//
|
const fallbackVersion = await tryGetFallbackToolcacheVersion(cliVersion, tagName, variant, logger);
|
||||||
// If we are on Dotcom, we will make an HTTP request to the Releases API here
|
if (fallbackVersion) {
|
||||||
// to find the tag name for the requested version.
|
|
||||||
tagName =
|
|
||||||
tagName || (await getOrFindBundleTagName(requestedVersion, logger));
|
|
||||||
const fallbackVersion = convertToSemVer(getBundleVersionFromTagName(tagName), logger);
|
|
||||||
logger.debug(`Computed a fallback toolcache version number of ${fallbackVersion} for CodeQL tools version ` +
|
|
||||||
`${requestedVersion.cliVersion}.`);
|
|
||||||
codeqlFolder = toolcache.find("CodeQL", fallbackVersion);
|
codeqlFolder = toolcache.find("CodeQL", fallbackVersion);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
logger.debug("Could not determine a fallback toolcache version number for CodeQL tools version " +
|
||||||
|
`${humanReadableVersion}.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logger.debug("Both the CLI version and the bundle version are unknown, so we will not be able to find " +
|
||||||
|
"the requested version of the CodeQL tools in the toolcache.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (codeqlFolder) {
|
||||||
|
logger.info(`Found CodeQL tools version ${humanReadableVersion} in the toolcache.`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logger.info(`Did not find CodeQL tools version ${humanReadableVersion} in the toolcache.`);
|
||||||
|
}
|
||||||
if (codeqlFolder) {
|
if (codeqlFolder) {
|
||||||
return {
|
return {
|
||||||
codeqlFolder,
|
codeqlFolder,
|
||||||
sourceType: "toolcache",
|
sourceType: "toolcache",
|
||||||
toolsVersion: requestedVersion.syntheticCliVersion,
|
toolsVersion: cliVersion ?? humanReadableVersion,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
logger.debug(`Did not find CodeQL tools version ${requestedVersion.syntheticCliVersion} in the toolcache.`);
|
|
||||||
// If we don't find the requested version on Enterprise, we may allow a
|
// If we don't find the requested version on Enterprise, we may allow a
|
||||||
// different version to save download time if the version hasn't been
|
// different version to save download time if the version hasn't been
|
||||||
// specified explicitly (in which case we always honor it).
|
// specified explicitly (in which case we always honor it).
|
||||||
if (variant !== util.GitHubVariant.DOTCOM && !forceLatest && !toolsInput) {
|
if (variant !== util.GitHubVariant.DOTCOM &&
|
||||||
const result = await findOverridingToolsInCache(requestedVersion.syntheticCliVersion, logger);
|
!forceShippedTools &&
|
||||||
|
!toolsInput) {
|
||||||
|
const result = await findOverridingToolsInCache(humanReadableVersion, logger);
|
||||||
if (result !== undefined) {
|
if (result !== undefined) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!url) {
|
||||||
|
if (!tagName && cliVersion && variant === util.GitHubVariant.DOTCOM) {
|
||||||
|
tagName = await findCodeQLBundleTagDotcomOnly(cliVersion, logger);
|
||||||
|
}
|
||||||
|
else if (!tagName) {
|
||||||
|
throw new Error(`Could not obtain the requested version (${humanReadableVersion}) of the CodeQL tools ` +
|
||||||
|
"since we could not compute the tag name.");
|
||||||
|
}
|
||||||
|
url = await getCodeQLBundleDownloadURL(tagName, apiDetails, variant, logger);
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
cliVersion: requestedVersion.cliVersion || undefined,
|
bundleVersion: tagName && tryGetBundleVersionFromTagName(tagName, logger),
|
||||||
codeqlURL: requestedVersion["url"] ||
|
cliVersion,
|
||||||
(await getCodeQLBundleDownloadURL(tagName ||
|
codeqlURL: url,
|
||||||
// The check on `requestedVersion.tagName` is redundant but lets us
|
|
||||||
// use the property that if we don't know `requestedVersion.tagName`,
|
|
||||||
// then we must know `requestedVersion.cliVersion`. This property is
|
|
||||||
// required by the type of `getOrFindBundleTagName`.
|
|
||||||
(requestedVersion.tagName !== undefined
|
|
||||||
? requestedVersion.tagName
|
|
||||||
: await getOrFindBundleTagName(requestedVersion, logger)), apiDetails, variant, logger)),
|
|
||||||
sourceType: "download",
|
sourceType: "download",
|
||||||
toolsVersion: requestedVersion.syntheticCliVersion,
|
toolsVersion: cliVersion ?? humanReadableVersion,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
exports.getCodeQLSource = getCodeQLSource;
|
exports.getCodeQLSource = getCodeQLSource;
|
||||||
async function downloadCodeQL(codeqlURL, maybeCliVersion, apiDetails, variant, tempDir, logger) {
|
/**
|
||||||
|
* Gets a fallback version number to use when looking for CodeQL in the toolcache if we didn't find
|
||||||
|
* the `x.y.z` version. This is to support old versions of the toolcache.
|
||||||
|
*/
|
||||||
|
async function tryGetFallbackToolcacheVersion(cliVersion, tagName, variant, logger) {
|
||||||
|
//
|
||||||
|
// If we are on Dotcom, we will make an HTTP request to the Releases API here
|
||||||
|
// to find the tag name for the requested version.
|
||||||
|
if (cliVersion && !tagName && variant === util.GitHubVariant.DOTCOM) {
|
||||||
|
tagName = await findCodeQLBundleTagDotcomOnly(cliVersion, logger);
|
||||||
|
}
|
||||||
|
if (!tagName) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const bundleVersion = tryGetBundleVersionFromTagName(tagName, logger);
|
||||||
|
if (!bundleVersion) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const fallbackVersion = convertToSemVer(bundleVersion, logger);
|
||||||
|
logger.debug(`Computed a fallback toolcache version number of ${fallbackVersion} for CodeQL version ` +
|
||||||
|
`${cliVersion ?? tagName}.`);
|
||||||
|
return fallbackVersion;
|
||||||
|
}
|
||||||
|
exports.tryGetFallbackToolcacheVersion = tryGetFallbackToolcacheVersion;
|
||||||
|
async function downloadCodeQL(codeqlURL, maybeBundleVersion, maybeCliVersion, apiDetails, variant, tempDir, logger) {
|
||||||
const parsedCodeQLURL = new URL(codeqlURL);
|
const parsedCodeQLURL = new URL(codeqlURL);
|
||||||
const searchParams = new URLSearchParams(parsedCodeQLURL.search);
|
const searchParams = new URLSearchParams(parsedCodeQLURL.search);
|
||||||
const headers = {
|
const headers = {
|
||||||
@@ -411,12 +454,13 @@ async function downloadCodeQL(codeqlURL, maybeCliVersion, apiDetails, variant, t
|
|||||||
// from the same GitHub instance the Action is running on.
|
// from the same GitHub instance the Action is running on.
|
||||||
// This avoids leaking Enterprise tokens to dotcom.
|
// This avoids leaking Enterprise tokens to dotcom.
|
||||||
// We also don't want to send an authorization header if there's already a token provided in the URL.
|
// We also don't want to send an authorization header if there's already a token provided in the URL.
|
||||||
|
let authorization = undefined;
|
||||||
if (searchParams.has("token")) {
|
if (searchParams.has("token")) {
|
||||||
logger.debug("CodeQL tools URL contains an authorization token.");
|
logger.debug("CodeQL tools URL contains an authorization token.");
|
||||||
}
|
}
|
||||||
else if (codeqlURL.startsWith(`${apiDetails.url}/`)) {
|
else if (codeqlURL.startsWith(`${apiDetails.url}/`)) {
|
||||||
logger.debug("Providing an authorization token to download CodeQL tools.");
|
logger.debug("Providing an authorization token to download CodeQL tools.");
|
||||||
headers.authorization = `token ${apiDetails.auth}`;
|
authorization = `token ${apiDetails.auth}`;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger.debug("Downloading CodeQL tools without an authorization token.");
|
logger.debug("Downloading CodeQL tools without an authorization token.");
|
||||||
@@ -425,16 +469,26 @@ async function downloadCodeQL(codeqlURL, maybeCliVersion, apiDetails, variant, t
|
|||||||
const dest = path.join(tempDir, (0, uuid_1.v4)());
|
const dest = path.join(tempDir, (0, uuid_1.v4)());
|
||||||
const finalHeaders = Object.assign({ "User-Agent": "CodeQL Action" }, headers);
|
const finalHeaders = Object.assign({ "User-Agent": "CodeQL Action" }, headers);
|
||||||
const toolsDownloadStart = perf_hooks_1.performance.now();
|
const toolsDownloadStart = perf_hooks_1.performance.now();
|
||||||
const codeqlPath = await toolcache.downloadTool(codeqlURL, dest, undefined, finalHeaders);
|
const codeqlPath = await toolcache.downloadTool(codeqlURL, dest, authorization, finalHeaders);
|
||||||
const toolsDownloadDurationMs = Math.round(perf_hooks_1.performance.now() - toolsDownloadStart);
|
const toolsDownloadDurationMs = Math.round(perf_hooks_1.performance.now() - toolsDownloadStart);
|
||||||
logger.debug(`CodeQL bundle download to ${codeqlPath} complete.`);
|
logger.debug(`CodeQL bundle download to ${codeqlPath} complete.`);
|
||||||
const codeqlExtracted = await toolcache.extractTar(codeqlPath);
|
const codeqlExtracted = await toolcache.extractTar(codeqlPath);
|
||||||
const bundleVersion = getBundleVersionFromUrl(codeqlURL);
|
const bundleVersion = maybeBundleVersion ?? tryGetBundleVersionFromUrl(codeqlURL, logger);
|
||||||
|
if (bundleVersion === undefined) {
|
||||||
|
logger.debug("Could not cache CodeQL tools because we could not determine the bundle version from the " +
|
||||||
|
`URL ${codeqlURL}.`);
|
||||||
|
return {
|
||||||
|
toolsVersion: maybeCliVersion ?? "unknown",
|
||||||
|
codeqlFolder: codeqlExtracted,
|
||||||
|
toolsDownloadDurationMs,
|
||||||
|
};
|
||||||
|
}
|
||||||
// Try to compute the CLI version for this bundle
|
// Try to compute the CLI version for this bundle
|
||||||
const cliVersion = maybeCliVersion ||
|
if (maybeCliVersion === undefined &&
|
||||||
(variant === util.GitHubVariant.DOTCOM &&
|
variant === util.GitHubVariant.DOTCOM &&
|
||||||
(await tryFindCliVersionDotcomOnly(`codeql-bundle-${bundleVersion}`, logger))) ||
|
codeqlURL.includes(`/${exports.CODEQL_DEFAULT_ACTION_REPOSITORY}/`)) {
|
||||||
undefined;
|
maybeCliVersion = await tryFindCliVersionDotcomOnly(`codeql-bundle-${bundleVersion}`, logger);
|
||||||
|
}
|
||||||
// Include both the CLI version and the bundle version in the toolcache version number. That way
|
// Include both the CLI version and the bundle version in the toolcache version number. That way
|
||||||
// if the user requests the same URL again, we can get it from the cache without having to call
|
// if the user requests the same URL again, we can get it from the cache without having to call
|
||||||
// any of the Releases API.
|
// any of the Releases API.
|
||||||
@@ -444,11 +498,11 @@ async function downloadCodeQL(codeqlURL, maybeCliVersion, apiDetails, variant, t
|
|||||||
// CLI release. In principle, it should be enough to just check that the CLI version isn't a
|
// CLI release. In principle, it should be enough to just check that the CLI version isn't a
|
||||||
// pre-release, but the version numbers of CodeQL nightlies have the format `x.y.z+<timestamp>`,
|
// pre-release, but the version numbers of CodeQL nightlies have the format `x.y.z+<timestamp>`,
|
||||||
// and we don't want these nightlies to override stable CLI versions in the toolcache.
|
// and we don't want these nightlies to override stable CLI versions in the toolcache.
|
||||||
const toolcacheVersion = cliVersion && cliVersion.match(/^[0-9]+\.[0-9]+\.[0-9]+$/)
|
const toolcacheVersion = maybeCliVersion?.match(/^[0-9]+\.[0-9]+\.[0-9]+$/)
|
||||||
? `${cliVersion}-${bundleVersion}`
|
? `${maybeCliVersion}-${bundleVersion}`
|
||||||
: convertToSemVer(bundleVersion, logger);
|
: convertToSemVer(bundleVersion, logger);
|
||||||
return {
|
return {
|
||||||
toolsVersion: cliVersion || toolcacheVersion,
|
toolsVersion: maybeCliVersion ?? toolcacheVersion,
|
||||||
codeqlFolder: await toolcache.cacheDir(codeqlExtracted, "CodeQL", toolcacheVersion),
|
codeqlFolder: await toolcache.cacheDir(codeqlExtracted, "CodeQL", toolcacheVersion),
|
||||||
toolsDownloadDurationMs,
|
toolsDownloadDurationMs,
|
||||||
};
|
};
|
||||||
@@ -469,15 +523,14 @@ exports.getCodeQLURLVersion = getCodeQLURLVersion;
|
|||||||
* @param apiDetails
|
* @param apiDetails
|
||||||
* @param tempDir
|
* @param tempDir
|
||||||
* @param variant
|
* @param variant
|
||||||
* @param bypassToolcache
|
|
||||||
* @param defaultCliVersion
|
* @param defaultCliVersion
|
||||||
* @param logger
|
* @param logger
|
||||||
* @param checkVersion Whether to check that CodeQL CLI meets the minimum
|
* @param checkVersion Whether to check that CodeQL CLI meets the minimum
|
||||||
* version requirement. Must be set to true outside tests.
|
* version requirement. Must be set to true outside tests.
|
||||||
* @returns the path to the extracted bundle, and the version of the tools
|
* @returns the path to the extracted bundle, and the version of the tools
|
||||||
*/
|
*/
|
||||||
async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, bypassToolcache, defaultCliVersion, logger) {
|
async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger) {
|
||||||
const source = await getCodeQLSource(toolsInput, bypassToolcache, defaultCliVersion, apiDetails, variant, logger);
|
const source = await getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, logger);
|
||||||
let codeqlFolder;
|
let codeqlFolder;
|
||||||
let toolsVersion = source.toolsVersion;
|
let toolsVersion = source.toolsVersion;
|
||||||
let toolsDownloadDurationMs;
|
let toolsDownloadDurationMs;
|
||||||
@@ -493,7 +546,7 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, bypas
|
|||||||
toolsSource = init_1.ToolsSource.Toolcache;
|
toolsSource = init_1.ToolsSource.Toolcache;
|
||||||
break;
|
break;
|
||||||
case "download": {
|
case "download": {
|
||||||
const result = await downloadCodeQL(source.codeqlURL, source.cliVersion, apiDetails, variant, tempDir, logger);
|
const result = await downloadCodeQL(source.codeqlURL, source.bundleVersion, source.cliVersion, apiDetails, variant, tempDir, logger);
|
||||||
toolsVersion = result.toolsVersion;
|
toolsVersion = result.toolsVersion;
|
||||||
codeqlFolder = result.codeqlFolder;
|
codeqlFolder = result.codeqlFolder;
|
||||||
toolsDownloadDurationMs = result.toolsDownloadDurationMs;
|
toolsDownloadDurationMs = result.toolsDownloadDurationMs;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
7
lib/upload-lib.js
generated
7
lib/upload-lib.js
generated
@@ -293,7 +293,8 @@ async function waitForProcessing(repositoryNwo, sarifID, logger, options = {
|
|||||||
if (Date.now() >
|
if (Date.now() >
|
||||||
statusCheckingStarted + STATUS_CHECK_TIMEOUT_MILLISECONDS) {
|
statusCheckingStarted + STATUS_CHECK_TIMEOUT_MILLISECONDS) {
|
||||||
// If the analysis hasn't finished processing in the allotted time, we continue anyway rather than failing.
|
// If the analysis hasn't finished processing in the allotted time, we continue anyway rather than failing.
|
||||||
// It's possible the analysis will eventually finish processing, but it's not worth spending more Actions time waiting.
|
// It's possible the analysis will eventually finish processing, but it's not worth spending more
|
||||||
|
// Actions time waiting.
|
||||||
logger.warning("Timed out waiting for analysis to finish processing. Continuing.");
|
logger.warning("Timed out waiting for analysis to finish processing. Continuing.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -329,7 +330,9 @@ async function waitForProcessing(repositoryNwo, sarifID, logger, options = {
|
|||||||
else {
|
else {
|
||||||
util.assertNever(status);
|
util.assertNever(status);
|
||||||
}
|
}
|
||||||
await util.delay(STATUS_CHECK_FREQUENCY_MILLISECONDS);
|
await util.delay(STATUS_CHECK_FREQUENCY_MILLISECONDS, {
|
||||||
|
allowProcessExit: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
60
lib/util.js
generated
60
lib/util.js
generated
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.parseMatrixInput = exports.shouldBypassToolcache = exports.isHostedRunner = exports.checkForTimeout = exports.withTimeout = exports.tryGetFolderBytes = exports.listFolder = exports.doesDirectoryExist = exports.logCodeScanningConfigInCli = exports.useCodeScanningConfigInCli = exports.isInTestMode = exports.getMlPoweredJsQueriesStatus = exports.getMlPoweredJsQueriesPack = exports.ML_POWERED_JS_QUERIES_PACK_NAME = exports.isGoodVersion = exports.delay = exports.bundleDb = exports.codeQlVersionAbove = exports.getCachedCodeQlVersion = exports.cacheCodeQlVersion = exports.isHTTPError = exports.UserError = exports.HTTPError = exports.getRequiredEnvParam = exports.enrichEnvironment = exports.initializeEnvironment = exports.EnvVar = exports.assertNever = exports.apiVersionInRange = exports.DisallowedAPIVersionReason = exports.checkGitHubVersionInRange = exports.getGitHubVersion = exports.GitHubVariant = exports.parseGitHubUrl = exports.getCodeQLDatabasePath = exports.getThreadsFlag = exports.getThreadsFlagValue = exports.getAddSnippetsFlag = exports.getMemoryFlag = exports.getMemoryFlagValue = exports.withTmpDir = exports.getToolNames = exports.getExtraOptionsEnvParam = exports.DID_AUTOBUILD_GO_ENV_VAR_NAME = exports.DEFAULT_DEBUG_DATABASE_NAME = exports.DEFAULT_DEBUG_ARTIFACT_NAME = exports.GITHUB_DOTCOM_URL = void 0;
|
exports.parseMatrixInput = exports.isHostedRunner = exports.checkForTimeout = exports.withTimeout = exports.tryGetFolderBytes = exports.listFolder = exports.doesDirectoryExist = exports.logCodeScanningConfigInCli = exports.useCodeScanningConfigInCli = exports.isInTestMode = exports.getMlPoweredJsQueriesStatus = exports.getMlPoweredJsQueriesPack = exports.ML_POWERED_JS_QUERIES_PACK_NAME = exports.isGoodVersion = exports.delay = exports.bundleDb = exports.codeQlVersionAbove = exports.getCachedCodeQlVersion = exports.cacheCodeQlVersion = exports.isHTTPError = exports.UserError = exports.HTTPError = exports.getRequiredEnvParam = exports.enrichEnvironment = exports.initializeEnvironment = exports.EnvVar = exports.assertNever = exports.apiVersionInRange = exports.DisallowedAPIVersionReason = exports.checkGitHubVersionInRange = exports.getGitHubVersion = exports.GitHubVariant = exports.parseGitHubUrl = exports.getCodeQLDatabasePath = exports.getThreadsFlag = exports.getThreadsFlagValue = exports.getAddSnippetsFlag = exports.getMemoryFlag = exports.getMemoryFlagValue = exports.withTmpDir = exports.getToolNames = exports.getExtraOptionsEnvParam = exports.DID_AUTOBUILD_GO_ENV_VAR_NAME = exports.DEFAULT_DEBUG_DATABASE_NAME = exports.DEFAULT_DEBUG_ARTIFACT_NAME = exports.GITHUB_DOTCOM_URL = void 0;
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const os = __importStar(require("os"));
|
const os = __importStar(require("os"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
@@ -40,7 +40,6 @@ const apiCompatibility = __importStar(require("./api-compatibility.json"));
|
|||||||
const codeql_1 = require("./codeql");
|
const codeql_1 = require("./codeql");
|
||||||
const config_utils_1 = require("./config-utils");
|
const config_utils_1 = require("./config-utils");
|
||||||
const feature_flags_1 = require("./feature-flags");
|
const feature_flags_1 = require("./feature-flags");
|
||||||
const languages_1 = require("./languages");
|
|
||||||
const shared_environment_1 = require("./shared-environment");
|
const shared_environment_1 = require("./shared-environment");
|
||||||
/**
|
/**
|
||||||
* Specifies bundle versions that are known to be broken
|
* Specifies bundle versions that are known to be broken
|
||||||
@@ -456,10 +455,20 @@ async function bundleDb(config, language, codeql, dbName) {
|
|||||||
return databaseBundlePath;
|
return databaseBundlePath;
|
||||||
}
|
}
|
||||||
exports.bundleDb = bundleDb;
|
exports.bundleDb = bundleDb;
|
||||||
async function delay(milliseconds) {
|
/**
|
||||||
|
* @param milliseconds time to delay
|
||||||
|
* @param opts options
|
||||||
|
* @param opts.allowProcessExit if true, the timer will not prevent the process from exiting
|
||||||
|
*/
|
||||||
|
async function delay(milliseconds, { allowProcessExit }) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const timer = setTimeout(resolve, milliseconds);
|
||||||
|
if (allowProcessExit) {
|
||||||
// Immediately `unref` the timer such that it only prevents the process from exiting if the
|
// Immediately `unref` the timer such that it only prevents the process from exiting if the
|
||||||
// surrounding promise is being awaited.
|
// surrounding promise is being awaited.
|
||||||
return new Promise((resolve) => setTimeout(resolve, milliseconds).unref());
|
timer.unref();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
exports.delay = delay;
|
exports.delay = delay;
|
||||||
function isGoodVersion(versionSpec) {
|
function isGoodVersion(versionSpec) {
|
||||||
@@ -637,7 +646,7 @@ async function withTimeout(timeoutMs, promise, onTimeout) {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
const timeoutTask = async () => {
|
const timeoutTask = async () => {
|
||||||
await delay(timeoutMs);
|
await delay(timeoutMs, { allowProcessExit: true });
|
||||||
if (!finished) {
|
if (!finished) {
|
||||||
// Workaround: While the promise racing below will allow the main code
|
// Workaround: While the promise racing below will allow the main code
|
||||||
// to continue, the process won't normally exit until the asynchronous
|
// to continue, the process won't normally exit until the asynchronous
|
||||||
@@ -660,7 +669,7 @@ exports.withTimeout = withTimeout;
|
|||||||
async function checkForTimeout() {
|
async function checkForTimeout() {
|
||||||
if (hadTimeout === true) {
|
if (hadTimeout === true) {
|
||||||
core.info("A timeout occurred, force exiting the process after 30 seconds to prevent hanging.");
|
core.info("A timeout occurred, force exiting the process after 30 seconds to prevent hanging.");
|
||||||
await delay(30000);
|
await delay(30000, { allowProcessExit: true });
|
||||||
process.exit();
|
process.exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -685,45 +694,6 @@ function isHostedRunner() {
|
|||||||
process.env["RUNNER_TOOL_CACHE"]?.includes("hostedtoolcache"));
|
process.env["RUNNER_TOOL_CACHE"]?.includes("hostedtoolcache"));
|
||||||
}
|
}
|
||||||
exports.isHostedRunner = isHostedRunner;
|
exports.isHostedRunner = isHostedRunner;
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param featuresEnablement The features enabled for the current run
|
|
||||||
* @param languagesInput Languages input from the workflow
|
|
||||||
* @param repository The owner/name of the repository
|
|
||||||
* @param logger A logger
|
|
||||||
* @returns A boolean indicating whether or not the toolcache should be bypassed and the latest codeql should be downloaded.
|
|
||||||
*/
|
|
||||||
async function shouldBypassToolcache(featuresEnablement, codeqlUrl, languagesInput, repository, logger) {
|
|
||||||
// An explicit codeql url is specified, that means the toolcache will not be used.
|
|
||||||
if (codeqlUrl) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Check if the toolcache is disabled for all languages
|
|
||||||
if (await featuresEnablement.getValue(feature_flags_1.Feature.BypassToolcacheEnabled)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Check if the toolcache is disabled for kotlin and swift.
|
|
||||||
if (!(await featuresEnablement.getValue(feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Now check to see if kotlin or swift is one of the languages being analyzed.
|
|
||||||
const { rawLanguages, autodetected } = await (0, config_utils_1.getRawLanguages)(languagesInput, repository, logger);
|
|
||||||
let bypass = rawLanguages.some((lang) => languages_1.KOTLIN_SWIFT_BYPASS.includes(lang));
|
|
||||||
if (bypass) {
|
|
||||||
logger.info(`Bypassing toolcache for kotlin or swift. Languages: ${rawLanguages}`);
|
|
||||||
}
|
|
||||||
else if (!autodetected && rawLanguages.includes(languages_1.Language.java)) {
|
|
||||||
// special case: java was explicitly specified, but there might be
|
|
||||||
// some kotlin in the repository, so we need to make a request for that.
|
|
||||||
const langsInRepo = await (0, config_utils_1.getLanguagesInRepo)(repository, logger);
|
|
||||||
if (langsInRepo.includes("kotlin")) {
|
|
||||||
logger.info(`Bypassing toolcache for kotlin.`);
|
|
||||||
bypass = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bypass;
|
|
||||||
}
|
|
||||||
exports.shouldBypassToolcache = shouldBypassToolcache;
|
|
||||||
function parseMatrixInput(matrixInput) {
|
function parseMatrixInput(matrixInput) {
|
||||||
if (matrixInput === undefined || matrixInput === "null") {
|
if (matrixInput === undefined || matrixInput === "null") {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
115
lib/util.test.js
generated
115
lib/util.test.js
generated
@@ -33,9 +33,7 @@ const github = __importStar(require("@actions/github"));
|
|||||||
const ava_1 = __importDefault(require("ava"));
|
const ava_1 = __importDefault(require("ava"));
|
||||||
const sinon = __importStar(require("sinon"));
|
const sinon = __importStar(require("sinon"));
|
||||||
const api = __importStar(require("./api-client"));
|
const api = __importStar(require("./api-client"));
|
||||||
const feature_flags_1 = require("./feature-flags");
|
|
||||||
const logging_1 = require("./logging");
|
const logging_1 = require("./logging");
|
||||||
const repository_1 = require("./repository");
|
|
||||||
const testing_utils_1 = require("./testing-utils");
|
const testing_utils_1 = require("./testing-utils");
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
(0, testing_utils_1.setupTests)(ava_1.default);
|
(0, testing_utils_1.setupTests)(ava_1.default);
|
||||||
@@ -325,117 +323,4 @@ const shortTime = 10;
|
|||||||
t.deepEqual(shortTaskTimedOut, false);
|
t.deepEqual(shortTaskTimedOut, false);
|
||||||
t.deepEqual(result, 99);
|
t.deepEqual(result, 99);
|
||||||
});
|
});
|
||||||
const mockRepositoryNwo = (0, repository_1.parseRepositoryNwo)("owner/repo");
|
|
||||||
// eslint-disable-next-line github/array-foreach
|
|
||||||
[
|
|
||||||
{
|
|
||||||
name: "disabled",
|
|
||||||
features: [],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: undefined,
|
|
||||||
languagesInRepository: [],
|
|
||||||
expected: false,
|
|
||||||
expectedApiCall: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "disabled even though swift kotlin bypassed",
|
|
||||||
features: [feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: undefined,
|
|
||||||
languagesInRepository: [],
|
|
||||||
expected: false,
|
|
||||||
expectedApiCall: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "disabled even though swift kotlin analyzed",
|
|
||||||
features: [],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: " sWiFt , KoTlIn ",
|
|
||||||
languagesInRepository: [],
|
|
||||||
expected: false,
|
|
||||||
expectedApiCall: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "toolcache bypass all",
|
|
||||||
features: [feature_flags_1.Feature.BypassToolcacheEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: undefined,
|
|
||||||
languagesInRepository: [],
|
|
||||||
expected: true,
|
|
||||||
expectedApiCall: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "custom CodeQL",
|
|
||||||
features: [],
|
|
||||||
hasCustomCodeQL: true,
|
|
||||||
languagesInput: undefined,
|
|
||||||
languagesInRepository: [],
|
|
||||||
expected: true,
|
|
||||||
expectedApiCall: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "bypass swift",
|
|
||||||
features: [feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: " sWiFt ,other",
|
|
||||||
languagesInRepository: [],
|
|
||||||
expected: true,
|
|
||||||
expectedApiCall: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "bypass kotlin",
|
|
||||||
features: [feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: "other, KoTlIn ",
|
|
||||||
languagesInRepository: [],
|
|
||||||
expected: true,
|
|
||||||
expectedApiCall: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "bypass kotlin language from repository",
|
|
||||||
features: [feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: "",
|
|
||||||
languagesInRepository: ["KoTlIn", "other"],
|
|
||||||
expected: true,
|
|
||||||
expectedApiCall: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "bypass swift language from repository",
|
|
||||||
features: [feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: "",
|
|
||||||
languagesInRepository: ["SwiFt", "other"],
|
|
||||||
expected: true,
|
|
||||||
expectedApiCall: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "bypass java from input if there is kotlin in repository",
|
|
||||||
features: [feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: "java",
|
|
||||||
languagesInRepository: ["kotlin", "other"],
|
|
||||||
expected: true,
|
|
||||||
expectedApiCall: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "don't bypass java from input if there is no kotlin in repository",
|
|
||||||
features: [feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: "java",
|
|
||||||
languagesInRepository: ["java", "other"],
|
|
||||||
expected: false,
|
|
||||||
expectedApiCall: true,
|
|
||||||
},
|
|
||||||
].forEach((args) => {
|
|
||||||
(0, ava_1.default)(`shouldBypassToolcache: ${args.name}`, async (t) => {
|
|
||||||
const mockRequest = (0, testing_utils_1.mockLanguagesInRepo)(args.languagesInRepository);
|
|
||||||
const mockLogger = (0, logging_1.getRunnerLogger)(true);
|
|
||||||
const featureEnablement = (0, testing_utils_1.createFeatures)(args.features);
|
|
||||||
const codeqlUrl = args.hasCustomCodeQL ? "custom-codeql-url" : undefined;
|
|
||||||
const actual = await util.shouldBypassToolcache(featureEnablement, codeqlUrl, args.languagesInput, mockRepositoryNwo, mockLogger);
|
|
||||||
t.deepEqual(actual, args.expected);
|
|
||||||
t.deepEqual(mockRequest.called, args.expectedApiCall);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
//# sourceMappingURL=util.test.js.map
|
//# sourceMappingURL=util.test.js.map
|
||||||
File diff suppressed because one or more lines are too long
2
node_modules/.package-lock.json
generated
vendored
2
node_modules/.package-lock.json
generated
vendored
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "codeql",
|
"name": "codeql",
|
||||||
"version": "2.2.1",
|
"version": "2.2.5",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "codeql",
|
"name": "codeql",
|
||||||
"version": "2.2.1",
|
"version": "2.2.5",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "codeql",
|
"name": "codeql",
|
||||||
"version": "2.2.1",
|
"version": "2.2.5",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/artifact": "^1.1.0",
|
"@actions/artifact": "^1.1.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "codeql",
|
"name": "codeql",
|
||||||
"version": "2.2.1",
|
"version": "2.2.5",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "CodeQL action",
|
"description": "CodeQL action",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -87,10 +87,14 @@ test.beforeEach(() => {
|
|||||||
function mockDownloadApi({
|
function mockDownloadApi({
|
||||||
apiDetails = sampleApiDetails,
|
apiDetails = sampleApiDetails,
|
||||||
isPinned,
|
isPinned,
|
||||||
|
repo = "github/codeql-action",
|
||||||
|
platformSpecific = true,
|
||||||
tagName,
|
tagName,
|
||||||
}: {
|
}: {
|
||||||
apiDetails?: GitHubApiDetails;
|
apiDetails?: GitHubApiDetails;
|
||||||
isPinned?: boolean;
|
isPinned?: boolean;
|
||||||
|
repo?: string;
|
||||||
|
platformSpecific?: boolean;
|
||||||
tagName: string;
|
tagName: string;
|
||||||
}): string {
|
}): string {
|
||||||
const platform =
|
const platform =
|
||||||
@@ -102,7 +106,9 @@ function mockDownloadApi({
|
|||||||
|
|
||||||
const baseUrl = apiDetails?.url ?? "https://example.com";
|
const baseUrl = apiDetails?.url ?? "https://example.com";
|
||||||
const relativeUrl = apiDetails
|
const relativeUrl = apiDetails
|
||||||
? `/github/codeql-action/releases/download/${tagName}/codeql-bundle-${platform}.tar.gz`
|
? `/${repo}/releases/download/${tagName}/codeql-bundle${
|
||||||
|
platformSpecific ? `-${platform}` : ""
|
||||||
|
}.tar.gz`
|
||||||
: `/download/${tagName}/codeql-bundle.tar.gz`;
|
: `/download/${tagName}/codeql-bundle.tar.gz`;
|
||||||
|
|
||||||
nock(baseUrl)
|
nock(baseUrl)
|
||||||
@@ -137,7 +143,6 @@ async function installIntoToolcache({
|
|||||||
apiDetails,
|
apiDetails,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
util.GitHubVariant.GHES,
|
util.GitHubVariant.GHES,
|
||||||
false,
|
|
||||||
cliVersion !== undefined
|
cliVersion !== undefined
|
||||||
? { cliVersion, tagName, variant: util.GitHubVariant.GHES }
|
? { cliVersion, tagName, variant: util.GitHubVariant.GHES }
|
||||||
: SAMPLE_DEFAULT_CLI_VERSION,
|
: SAMPLE_DEFAULT_CLI_VERSION,
|
||||||
@@ -199,7 +204,6 @@ test("downloads and caches explicitly requested bundles that aren't in the toolc
|
|||||||
sampleApiDetails,
|
sampleApiDetails,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
util.GitHubVariant.DOTCOM,
|
util.GitHubVariant.DOTCOM,
|
||||||
false,
|
|
||||||
SAMPLE_DEFAULT_CLI_VERSION,
|
SAMPLE_DEFAULT_CLI_VERSION,
|
||||||
getRunnerLogger(true),
|
getRunnerLogger(true),
|
||||||
false
|
false
|
||||||
@@ -233,7 +237,6 @@ test("downloads an explicitly requested bundle even if a different version is ca
|
|||||||
sampleApiDetails,
|
sampleApiDetails,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
util.GitHubVariant.DOTCOM,
|
util.GitHubVariant.DOTCOM,
|
||||||
false,
|
|
||||||
SAMPLE_DEFAULT_CLI_VERSION,
|
SAMPLE_DEFAULT_CLI_VERSION,
|
||||||
getRunnerLogger(true),
|
getRunnerLogger(true),
|
||||||
false
|
false
|
||||||
@@ -284,7 +287,6 @@ for (const {
|
|||||||
sampleApiDetails,
|
sampleApiDetails,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
util.GitHubVariant.DOTCOM,
|
util.GitHubVariant.DOTCOM,
|
||||||
false,
|
|
||||||
SAMPLE_DEFAULT_CLI_VERSION,
|
SAMPLE_DEFAULT_CLI_VERSION,
|
||||||
getRunnerLogger(true),
|
getRunnerLogger(true),
|
||||||
false
|
false
|
||||||
@@ -352,7 +354,6 @@ for (const { githubReleases, toolcacheVersion } of [
|
|||||||
sampleApiDetails,
|
sampleApiDetails,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
util.GitHubVariant.DOTCOM,
|
util.GitHubVariant.DOTCOM,
|
||||||
false,
|
|
||||||
SAMPLE_DEFAULT_CLI_VERSION,
|
SAMPLE_DEFAULT_CLI_VERSION,
|
||||||
getRunnerLogger(true),
|
getRunnerLogger(true),
|
||||||
false
|
false
|
||||||
@@ -381,7 +382,6 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
|
|||||||
sampleApiDetails,
|
sampleApiDetails,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
variant,
|
variant,
|
||||||
false,
|
|
||||||
{
|
{
|
||||||
cliVersion: defaults.cliVersion,
|
cliVersion: defaults.cliVersion,
|
||||||
tagName: defaults.bundleVersion,
|
tagName: defaults.bundleVersion,
|
||||||
@@ -417,7 +417,6 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
|
|||||||
sampleApiDetails,
|
sampleApiDetails,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
variant,
|
variant,
|
||||||
false,
|
|
||||||
{
|
{
|
||||||
cliVersion: defaults.cliVersion,
|
cliVersion: defaults.cliVersion,
|
||||||
tagName: defaults.bundleVersion,
|
tagName: defaults.bundleVersion,
|
||||||
@@ -454,7 +453,6 @@ test('downloads bundle if "latest" tools specified but not cached', async (t) =>
|
|||||||
sampleApiDetails,
|
sampleApiDetails,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
util.GitHubVariant.DOTCOM,
|
util.GitHubVariant.DOTCOM,
|
||||||
false,
|
|
||||||
SAMPLE_DEFAULT_CLI_VERSION,
|
SAMPLE_DEFAULT_CLI_VERSION,
|
||||||
getRunnerLogger(true),
|
getRunnerLogger(true),
|
||||||
false
|
false
|
||||||
@@ -468,7 +466,11 @@ test('downloads bundle if "latest" tools specified but not cached', async (t) =>
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test("download codeql bundle from github ae endpoint", async (t) => {
|
for (const isBundleVersionInUrl of [true, false]) {
|
||||||
|
const inclusionString = isBundleVersionInUrl
|
||||||
|
? "includes"
|
||||||
|
: "does not include";
|
||||||
|
test(`download codeql bundle from github ae endpoint (URL ${inclusionString} bundle version)`, async (t) => {
|
||||||
await util.withTmpDir(async (tmpDir) => {
|
await util.withTmpDir(async (tmpDir) => {
|
||||||
setupActionsVars(tmpDir, tmpDir);
|
setupActionsVars(tmpDir, tmpDir);
|
||||||
|
|
||||||
@@ -482,6 +484,10 @@ test("download codeql bundle from github ae endpoint", async (t) => {
|
|||||||
: "osx64";
|
: "osx64";
|
||||||
const codeQLBundleName = `codeql-bundle-${platform}.tar.gz`;
|
const codeQLBundleName = `codeql-bundle-${platform}.tar.gz`;
|
||||||
|
|
||||||
|
const eventualDownloadUrl = isBundleVersionInUrl
|
||||||
|
? `https://example.githubenterprise.com/github/codeql-action/releases/download/${defaults.bundleVersion}/${codeQLBundleName}`
|
||||||
|
: `https://example.githubenterprise.com/api/v3/repos/github/codeql-action/releases/assets/${bundleAssetID}`;
|
||||||
|
|
||||||
nock("https://example.githubenterprise.com")
|
nock("https://example.githubenterprise.com")
|
||||||
.get(
|
.get(
|
||||||
`/api/v3/enterprise/code-scanning/codeql-bundle/find/${defaults.bundleVersion}`
|
`/api/v3/enterprise/code-scanning/codeql-bundle/find/${defaults.bundleVersion}`
|
||||||
@@ -495,12 +501,15 @@ test("download codeql bundle from github ae endpoint", async (t) => {
|
|||||||
`/api/v3/enterprise/code-scanning/codeql-bundle/download/${bundleAssetID}`
|
`/api/v3/enterprise/code-scanning/codeql-bundle/download/${bundleAssetID}`
|
||||||
)
|
)
|
||||||
.reply(200, {
|
.reply(200, {
|
||||||
url: `https://example.githubenterprise.com/github/codeql-action/releases/download/${defaults.bundleVersion}/${codeQLBundleName}`,
|
url: eventualDownloadUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
nock("https://example.githubenterprise.com")
|
nock("https://example.githubenterprise.com")
|
||||||
.get(
|
.get(
|
||||||
`/github/codeql-action/releases/download/${defaults.bundleVersion}/${codeQLBundleName}`
|
eventualDownloadUrl.replace(
|
||||||
|
"https://example.githubenterprise.com",
|
||||||
|
""
|
||||||
|
)
|
||||||
)
|
)
|
||||||
.replyWithFile(
|
.replyWithFile(
|
||||||
200,
|
200,
|
||||||
@@ -516,7 +525,6 @@ test("download codeql bundle from github ae endpoint", async (t) => {
|
|||||||
sampleGHAEApiDetails,
|
sampleGHAEApiDetails,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
util.GitHubVariant.GHAE,
|
util.GitHubVariant.GHAE,
|
||||||
false,
|
|
||||||
{
|
{
|
||||||
cliVersion: defaults.cliVersion,
|
cliVersion: defaults.cliVersion,
|
||||||
tagName: defaults.bundleVersion,
|
tagName: defaults.bundleVersion,
|
||||||
@@ -533,6 +541,45 @@ test("download codeql bundle from github ae endpoint", async (t) => {
|
|||||||
t.is(cachedVersions.length, 1);
|
t.is(cachedVersions.length, 1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
test("bundle URL from another repo is cached as 0.0.0-bundleVersion", async (t) => {
|
||||||
|
await util.withTmpDir(async (tmpDir) => {
|
||||||
|
setupActionsVars(tmpDir, tmpDir);
|
||||||
|
|
||||||
|
mockApiDetails(sampleApiDetails);
|
||||||
|
sinon.stub(actionsUtil, "isRunningLocalAction").returns(true);
|
||||||
|
const releasesApiMock = mockReleaseApi({
|
||||||
|
assetNames: ["cli-version-2.12.2.txt"],
|
||||||
|
tagName: "codeql-bundle-20230203",
|
||||||
|
});
|
||||||
|
mockDownloadApi({
|
||||||
|
repo: "dsp-testing/codeql-cli-nightlies",
|
||||||
|
platformSpecific: false,
|
||||||
|
tagName: "codeql-bundle-20230203",
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await codeql.setupCodeQL(
|
||||||
|
"https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/codeql-bundle-20230203/codeql-bundle.tar.gz",
|
||||||
|
sampleApiDetails,
|
||||||
|
tmpDir,
|
||||||
|
util.GitHubVariant.DOTCOM,
|
||||||
|
SAMPLE_DEFAULT_CLI_VERSION,
|
||||||
|
getRunnerLogger(true),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
t.is(result.toolsVersion, "0.0.0-20230203");
|
||||||
|
t.is(result.toolsSource, ToolsSource.Download);
|
||||||
|
t.true(Number.isInteger(result.toolsDownloadDurationMs));
|
||||||
|
|
||||||
|
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
||||||
|
t.is(cachedVersions.length, 1);
|
||||||
|
t.is(cachedVersions[0], "0.0.0-20230203");
|
||||||
|
|
||||||
|
t.false(releasesApiMock.isDone());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test("getExtraOptions works for explicit paths", (t) => {
|
test("getExtraOptions works for explicit paths", (t) => {
|
||||||
t.deepEqual(codeql.getExtraOptions({}, ["foo"], []), []);
|
t.deepEqual(codeql.getExtraOptions({}, ["foo"], []), []);
|
||||||
|
|||||||
@@ -278,6 +278,11 @@ export const CODEQL_VERSION_ML_POWERED_QUERIES_WINDOWS = "2.9.0";
|
|||||||
*/
|
*/
|
||||||
export const CODEQL_VERSION_BETTER_RESOLVE_LANGUAGES = "2.10.3";
|
export const CODEQL_VERSION_BETTER_RESOLVE_LANGUAGES = "2.10.3";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Versions 2.11.1+ of the CodeQL Bundle include a `security-experimental` built-in query suite for each language.
|
||||||
|
*/
|
||||||
|
export const CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE = "2.12.1";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up CodeQL CLI access.
|
* Set up CodeQL CLI access.
|
||||||
*
|
*
|
||||||
@@ -285,7 +290,6 @@ export const CODEQL_VERSION_BETTER_RESOLVE_LANGUAGES = "2.10.3";
|
|||||||
* @param apiDetails
|
* @param apiDetails
|
||||||
* @param tempDir
|
* @param tempDir
|
||||||
* @param variant
|
* @param variant
|
||||||
* @param bypassToolcache
|
|
||||||
* @param defaultCliVersion
|
* @param defaultCliVersion
|
||||||
* @param logger
|
* @param logger
|
||||||
* @param checkVersion Whether to check that CodeQL CLI meets the minimum
|
* @param checkVersion Whether to check that CodeQL CLI meets the minimum
|
||||||
@@ -297,7 +301,6 @@ export async function setupCodeQL(
|
|||||||
apiDetails: api.GitHubApiDetails,
|
apiDetails: api.GitHubApiDetails,
|
||||||
tempDir: string,
|
tempDir: string,
|
||||||
variant: util.GitHubVariant,
|
variant: util.GitHubVariant,
|
||||||
bypassToolcache: boolean,
|
|
||||||
defaultCliVersion: CodeQLDefaultVersionInfo,
|
defaultCliVersion: CodeQLDefaultVersionInfo,
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
checkVersion: boolean
|
checkVersion: boolean
|
||||||
@@ -314,7 +317,6 @@ export async function setupCodeQL(
|
|||||||
apiDetails,
|
apiDetails,
|
||||||
tempDir,
|
tempDir,
|
||||||
variant,
|
variant,
|
||||||
bypassToolcache,
|
|
||||||
defaultCliVersion,
|
defaultCliVersion,
|
||||||
logger
|
logger
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1993,7 +1993,7 @@ test(
|
|||||||
process.platform === "win32" ? undefined : "~0.1.0"
|
process.platform === "win32" ? undefined : "~0.1.0"
|
||||||
);
|
);
|
||||||
// Test that ML-powered queries aren't run when the user hasn't specified that we should run the
|
// Test that ML-powered queries aren't run when the user hasn't specified that we should run the
|
||||||
// `security-extended` or `security-and-quality` query suite.
|
// `security-extended`, `security-and-quality`, or `security-experimental` query suite.
|
||||||
test(mlPoweredQueriesMacro, "2.7.5", true, undefined, undefined, undefined);
|
test(mlPoweredQueriesMacro, "2.7.5", true, undefined, undefined, undefined);
|
||||||
// Test that ML-powered queries are run on non-Windows platforms running `security-extended` on
|
// Test that ML-powered queries are run on non-Windows platforms running `security-extended` on
|
||||||
// versions of the CodeQL CLI prior to 2.9.0.
|
// versions of the CodeQL CLI prior to 2.9.0.
|
||||||
@@ -2074,7 +2074,6 @@ test(
|
|||||||
"security-extended",
|
"security-extended",
|
||||||
"~0.4.0"
|
"~0.4.0"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Test that ML-powered queries are run on all platforms running `security-and-quality` on CodeQL
|
// Test that ML-powered queries are run on all platforms running `security-and-quality` on CodeQL
|
||||||
// CLI 2.11.3+.
|
// CLI 2.11.3+.
|
||||||
test(
|
test(
|
||||||
@@ -2085,6 +2084,16 @@ test(
|
|||||||
"security-and-quality",
|
"security-and-quality",
|
||||||
"~0.4.0"
|
"~0.4.0"
|
||||||
);
|
);
|
||||||
|
// Test that ML-powered queries are run on all platforms running `security-experimental` on CodeQL
|
||||||
|
// CLI 2.12.1+.
|
||||||
|
test(
|
||||||
|
mlPoweredQueriesMacro,
|
||||||
|
"2.12.1",
|
||||||
|
true,
|
||||||
|
undefined,
|
||||||
|
"security-experimental",
|
||||||
|
"~0.4.0"
|
||||||
|
);
|
||||||
|
|
||||||
const calculateAugmentationMacro = test.macro({
|
const calculateAugmentationMacro = test.macro({
|
||||||
exec: async (
|
exec: async (
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
CodeQL,
|
CodeQL,
|
||||||
CODEQL_VERSION_GHES_PACK_DOWNLOAD,
|
CODEQL_VERSION_GHES_PACK_DOWNLOAD,
|
||||||
CODEQL_VERSION_ML_POWERED_QUERIES_WINDOWS,
|
CODEQL_VERSION_ML_POWERED_QUERIES_WINDOWS,
|
||||||
|
CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE,
|
||||||
ResolveQueriesOutput,
|
ResolveQueriesOutput,
|
||||||
} from "./codeql";
|
} from "./codeql";
|
||||||
import * as externalQueries from "./external-queries";
|
import * as externalQueries from "./external-queries";
|
||||||
@@ -380,7 +381,11 @@ async function addDefaultQueries(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The set of acceptable values for built-in suites from the codeql bundle
|
// The set of acceptable values for built-in suites from the codeql bundle
|
||||||
const builtinSuites = ["security-extended", "security-and-quality"] as const;
|
const builtinSuites = [
|
||||||
|
"security-experimental",
|
||||||
|
"security-extended",
|
||||||
|
"security-and-quality",
|
||||||
|
] as const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine the set of queries associated with suiteName's suites and add them to resultMap.
|
* Determine the set of queries associated with suiteName's suites and add them to resultMap.
|
||||||
@@ -401,6 +406,19 @@ async function addBuiltinSuiteQueries(
|
|||||||
if (!found) {
|
if (!found) {
|
||||||
throw new Error(getQueryUsesInvalid(configFile, suiteName));
|
throw new Error(getQueryUsesInvalid(configFile, suiteName));
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
suiteName === "security-experimental" &&
|
||||||
|
!(await codeQlVersionAbove(
|
||||||
|
codeQL,
|
||||||
|
CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE
|
||||||
|
))
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
`The 'security-experimental' suite is not supported on CodeQL CLI versions earlier than
|
||||||
|
${CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE}. Please upgrade to CodeQL CLI version
|
||||||
|
${CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE} or later.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// If we're running the JavaScript security-extended analysis (or a superset of it), the repo is
|
// If we're running the JavaScript security-extended analysis (or a superset of it), the repo is
|
||||||
// opted into the ML-powered queries beta, and a user hasn't already added the ML-powered query
|
// opted into the ML-powered queries beta, and a user hasn't already added the ML-powered query
|
||||||
@@ -413,7 +431,9 @@ async function addBuiltinSuiteQueries(
|
|||||||
CODEQL_VERSION_ML_POWERED_QUERIES_WINDOWS
|
CODEQL_VERSION_ML_POWERED_QUERIES_WINDOWS
|
||||||
))) &&
|
))) &&
|
||||||
languages.includes("javascript") &&
|
languages.includes("javascript") &&
|
||||||
(found === "security-extended" || found === "security-and-quality") &&
|
(found === "security-experimental" ||
|
||||||
|
found === "security-extended" ||
|
||||||
|
found === "security-and-quality") &&
|
||||||
!packs.javascript?.some(isMlPoweredJsQueriesPack) &&
|
!packs.javascript?.some(isMlPoweredJsQueriesPack) &&
|
||||||
(await featureEnablement.getValue(Feature.MlPoweredQueriesEnabled, codeQL))
|
(await featureEnablement.getValue(Feature.MlPoweredQueriesEnabled, codeQL))
|
||||||
) {
|
) {
|
||||||
@@ -1630,7 +1650,8 @@ export function parsePacks(
|
|||||||
* Without a '+', an input value will override the corresponding value in the config file.
|
* Without a '+', an input value will override the corresponding value in the config file.
|
||||||
*
|
*
|
||||||
* @param inputValue The input value to process.
|
* @param inputValue The input value to process.
|
||||||
* @returns true if the input value should replace the corresponding value in the config file, false if it should be appended.
|
* @returns true if the input value should replace the corresponding value in the config file,
|
||||||
|
* false if it should be appended.
|
||||||
*/
|
*/
|
||||||
function shouldCombine(inputValue?: string): boolean {
|
function shouldCombine(inputValue?: string): boolean {
|
||||||
return !!inputValue?.trim().startsWith("+");
|
return !!inputValue?.trim().startsWith("+");
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"bundleVersion": "codeql-bundle-20230120",
|
"bundleVersion": "codeql-bundle-20230207",
|
||||||
"cliVersion": "2.12.1",
|
"cliVersion": "2.12.2",
|
||||||
"priorBundleVersion": "codeql-bundle-20230105",
|
"priorBundleVersion": "codeql-bundle-20230120",
|
||||||
"priorCliVersion": "2.12.0"
|
"priorCliVersion": "2.12.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,12 +34,9 @@ export interface FeatureEnablement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum Feature {
|
export enum Feature {
|
||||||
BypassToolcacheEnabled = "bypass_toolcache_enabled",
|
|
||||||
BypassToolcacheKotlinSwiftEnabled = "bypass_toolcache_kotlin_swift_enabled",
|
|
||||||
CliConfigFileEnabled = "cli_config_file_enabled",
|
CliConfigFileEnabled = "cli_config_file_enabled",
|
||||||
DisableKotlinAnalysisEnabled = "disable_kotlin_analysis_enabled",
|
DisableKotlinAnalysisEnabled = "disable_kotlin_analysis_enabled",
|
||||||
MlPoweredQueriesEnabled = "ml_powered_queries_enabled",
|
MlPoweredQueriesEnabled = "ml_powered_queries_enabled",
|
||||||
TrapCachingEnabled = "trap_caching_enabled",
|
|
||||||
UploadFailedSarifEnabled = "upload_failed_sarif_enabled",
|
UploadFailedSarifEnabled = "upload_failed_sarif_enabled",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,18 +44,6 @@ export const featureConfig: Record<
|
|||||||
Feature,
|
Feature,
|
||||||
{ envVar: string; minimumVersion: string | undefined }
|
{ envVar: string; minimumVersion: string | undefined }
|
||||||
> = {
|
> = {
|
||||||
[Feature.BypassToolcacheEnabled]: {
|
|
||||||
envVar: "CODEQL_BYPASS_TOOLCACHE",
|
|
||||||
// Cannot specify a minimum version because this flag is checked before we have
|
|
||||||
// access to the CodeQL instance.
|
|
||||||
minimumVersion: undefined,
|
|
||||||
},
|
|
||||||
[Feature.BypassToolcacheKotlinSwiftEnabled]: {
|
|
||||||
envVar: "CODEQL_BYPASS_TOOLCACHE_KOTLIN_SWIFT",
|
|
||||||
// Cannot specify a minimum version because this flag is checked before we have
|
|
||||||
// access to the CodeQL instance.
|
|
||||||
minimumVersion: undefined,
|
|
||||||
},
|
|
||||||
[Feature.DisableKotlinAnalysisEnabled]: {
|
[Feature.DisableKotlinAnalysisEnabled]: {
|
||||||
envVar: "CODEQL_DISABLE_KOTLIN_ANALYSIS",
|
envVar: "CODEQL_DISABLE_KOTLIN_ANALYSIS",
|
||||||
minimumVersion: undefined,
|
minimumVersion: undefined,
|
||||||
@@ -71,10 +56,6 @@ export const featureConfig: Record<
|
|||||||
envVar: "CODEQL_ML_POWERED_QUERIES",
|
envVar: "CODEQL_ML_POWERED_QUERIES",
|
||||||
minimumVersion: "2.7.5",
|
minimumVersion: "2.7.5",
|
||||||
},
|
},
|
||||||
[Feature.TrapCachingEnabled]: {
|
|
||||||
envVar: "CODEQL_TRAP_CACHING",
|
|
||||||
minimumVersion: undefined,
|
|
||||||
},
|
|
||||||
[Feature.UploadFailedSarifEnabled]: {
|
[Feature.UploadFailedSarifEnabled]: {
|
||||||
envVar: "CODEQL_ACTION_UPLOAD_FAILED_SARIF",
|
envVar: "CODEQL_ACTION_UPLOAD_FAILED_SARIF",
|
||||||
minimumVersion: "2.11.3",
|
minimumVersion: "2.11.3",
|
||||||
@@ -138,11 +119,6 @@ export class Features implements FeatureEnablement {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bypassing the toolcache is disabled in test mode.
|
|
||||||
if (feature === Feature.BypassToolcacheEnabled && util.isInTestMode()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const envVar = (
|
const envVar = (
|
||||||
process.env[featureConfig[feature].envVar] || ""
|
process.env[featureConfig[feature].envVar] || ""
|
||||||
).toLocaleLowerCase();
|
).toLocaleLowerCase();
|
||||||
@@ -172,13 +148,17 @@ export class Features implements FeatureEnablement {
|
|||||||
class GitHubFeatureFlags implements FeatureEnablement {
|
class GitHubFeatureFlags implements FeatureEnablement {
|
||||||
private cachedApiResponse: GitHubFeatureFlagsApiResponse | undefined;
|
private cachedApiResponse: GitHubFeatureFlagsApiResponse | undefined;
|
||||||
|
|
||||||
|
// We cache whether the feature flags were accessed or not in order to accurately report whether flags were
|
||||||
|
// incorrectly configured vs. inaccessible in our telemetry.
|
||||||
|
private hasAccessedRemoteFeatureFlags: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly gitHubVersion: util.GitHubVersion,
|
private readonly gitHubVersion: util.GitHubVersion,
|
||||||
private readonly repositoryNwo: RepositoryNwo,
|
private readonly repositoryNwo: RepositoryNwo,
|
||||||
private readonly featureFlagsFile: string,
|
private readonly featureFlagsFile: string,
|
||||||
private readonly logger: Logger
|
private readonly logger: Logger
|
||||||
) {
|
) {
|
||||||
/**/
|
this.hasAccessedRemoteFeatureFlags = false; // Not accessed by default.
|
||||||
}
|
}
|
||||||
|
|
||||||
private getCliVersionFromFeatureFlag(f: string): string | undefined {
|
private getCliVersionFromFeatureFlag(f: string): string | undefined {
|
||||||
@@ -211,7 +191,9 @@ class GitHubFeatureFlags implements FeatureEnablement {
|
|||||||
const defaultDotComCliVersion = await this.getDefaultDotcomCliVersion();
|
const defaultDotComCliVersion = await this.getDefaultDotcomCliVersion();
|
||||||
return {
|
return {
|
||||||
cliVersion: defaultDotComCliVersion.version,
|
cliVersion: defaultDotComCliVersion.version,
|
||||||
toolsFeatureFlagsValid: defaultDotComCliVersion.toolsFeatureFlagsValid,
|
toolsFeatureFlagsValid: this.hasAccessedRemoteFeatureFlags
|
||||||
|
? defaultDotComCliVersion.toolsFeatureFlagsValid
|
||||||
|
: undefined,
|
||||||
variant,
|
variant,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -224,7 +206,7 @@ class GitHubFeatureFlags implements FeatureEnablement {
|
|||||||
|
|
||||||
async getDefaultDotcomCliVersion(): Promise<{
|
async getDefaultDotcomCliVersion(): Promise<{
|
||||||
version: string;
|
version: string;
|
||||||
toolsFeatureFlagsValid: boolean;
|
toolsFeatureFlagsValid: boolean | undefined;
|
||||||
}> {
|
}> {
|
||||||
const response = await this.getAllFeatures();
|
const response = await this.getAllFeatures();
|
||||||
|
|
||||||
@@ -252,7 +234,9 @@ class GitHubFeatureFlags implements FeatureEnablement {
|
|||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
version: defaults.cliVersion,
|
version: defaults.cliVersion,
|
||||||
toolsFeatureFlagsValid: false,
|
toolsFeatureFlagsValid: this.hasAccessedRemoteFeatureFlags
|
||||||
|
? false
|
||||||
|
: undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,6 +334,7 @@ class GitHubFeatureFlags implements FeatureEnablement {
|
|||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
"Not running against github.com. Disabling all toggleable features."
|
"Not running against github.com. Disabling all toggleable features."
|
||||||
);
|
);
|
||||||
|
this.hasAccessedRemoteFeatureFlags = false;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -365,6 +350,7 @@ class GitHubFeatureFlags implements FeatureEnablement {
|
|||||||
"Loaded the following default values for the feature flags from the Code Scanning API: " +
|
"Loaded the following default values for the feature flags from the Code Scanning API: " +
|
||||||
`${JSON.stringify(remoteFlags)}`
|
`${JSON.stringify(remoteFlags)}`
|
||||||
);
|
);
|
||||||
|
this.hasAccessedRemoteFeatureFlags = true;
|
||||||
return remoteFlags;
|
return remoteFlags;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (util.isHTTPError(e) && e.status === 403) {
|
if (util.isHTTPError(e) && e.status === 403) {
|
||||||
@@ -374,6 +360,7 @@ class GitHubFeatureFlags implements FeatureEnablement {
|
|||||||
"This could be because the Action is running on a pull request from a fork. If not, " +
|
"This could be because the Action is running on a pull request from a fork. If not, " +
|
||||||
`please ensure the Action has the 'security-events: write' permission. Details: ${e}`
|
`please ensure the Action has the 'security-events: write' permission. Details: ${e}`
|
||||||
);
|
);
|
||||||
|
this.hasAccessedRemoteFeatureFlags = false;
|
||||||
return {};
|
return {};
|
||||||
} else {
|
} else {
|
||||||
// Some features, such as `ml_powered_queries_enabled` affect the produced alerts.
|
// Some features, such as `ml_powered_queries_enabled` affect the produced alerts.
|
||||||
@@ -385,6 +372,5 @@ class GitHubFeatureFlags implements FeatureEnablement {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
import { getGitHubVersion } from "./api-client";
|
import { getGitHubVersion } from "./api-client";
|
||||||
import { CodeQL, CODEQL_VERSION_NEW_TRACING } from "./codeql";
|
import { CodeQL, CODEQL_VERSION_NEW_TRACING } from "./codeql";
|
||||||
import * as configUtils from "./config-utils";
|
import * as configUtils from "./config-utils";
|
||||||
import { Feature, FeatureEnablement, Features } from "./feature-flags";
|
import { Feature, Features } from "./feature-flags";
|
||||||
import {
|
import {
|
||||||
initCodeQL,
|
initCodeQL,
|
||||||
initConfig,
|
initConfig,
|
||||||
@@ -43,7 +43,6 @@ import {
|
|||||||
GitHubVariant,
|
GitHubVariant,
|
||||||
initializeEnvironment,
|
initializeEnvironment,
|
||||||
isHostedRunner,
|
isHostedRunner,
|
||||||
shouldBypassToolcache,
|
|
||||||
} from "./util";
|
} from "./util";
|
||||||
import { validateWorkflow } from "./workflow";
|
import { validateWorkflow } from "./workflow";
|
||||||
|
|
||||||
@@ -87,7 +86,9 @@ interface InitWithConfigStatusReport extends InitStatusReport {
|
|||||||
interface InitToolsDownloadFields {
|
interface InitToolsDownloadFields {
|
||||||
/** Time taken to download the bundle, in milliseconds. */
|
/** Time taken to download the bundle, in milliseconds. */
|
||||||
tools_download_duration_ms?: number;
|
tools_download_duration_ms?: number;
|
||||||
/** Whether the relevant tools dotcom feature flags have been misconfigured. Only populated if we attempt to determine the default version based on the dotcom feature flags. */
|
/**
|
||||||
|
* Whether the relevant tools dotcom feature flags have been misconfigured.
|
||||||
|
* Only populated if we attempt to determine the default version based on the dotcom feature flags. */
|
||||||
tools_feature_flags_valid?: boolean;
|
tools_feature_flags_valid?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,13 +118,14 @@ async function sendInitStatusReport(
|
|||||||
workflow_languages: workflowLanguages || "",
|
workflow_languages: workflowLanguages || "",
|
||||||
};
|
};
|
||||||
|
|
||||||
let initToolsDownloadFields: InitToolsDownloadFields = {};
|
const initToolsDownloadFields: InitToolsDownloadFields = {};
|
||||||
|
|
||||||
if (toolsSource === ToolsSource.Download) {
|
if (toolsDownloadDurationMs !== undefined) {
|
||||||
initToolsDownloadFields = {
|
initToolsDownloadFields.tools_download_duration_ms =
|
||||||
tools_download_duration_ms: toolsDownloadDurationMs,
|
toolsDownloadDurationMs;
|
||||||
tools_feature_flags_valid: toolsFeatureFlagsValid,
|
}
|
||||||
};
|
if (toolsFeatureFlagsValid !== undefined) {
|
||||||
|
initToolsDownloadFields.tools_feature_flags_valid = toolsFeatureFlagsValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config !== undefined) {
|
if (config !== undefined) {
|
||||||
@@ -236,13 +238,6 @@ async function run() {
|
|||||||
apiDetails,
|
apiDetails,
|
||||||
getTemporaryDirectory(),
|
getTemporaryDirectory(),
|
||||||
gitHubVersion.type,
|
gitHubVersion.type,
|
||||||
await shouldBypassToolcache(
|
|
||||||
features,
|
|
||||||
getOptionalInput("tools"),
|
|
||||||
getOptionalInput("languages"),
|
|
||||||
repositoryNwo,
|
|
||||||
logger
|
|
||||||
),
|
|
||||||
codeQLDefaultVersionInfo,
|
codeQLDefaultVersionInfo,
|
||||||
logger
|
logger
|
||||||
);
|
);
|
||||||
@@ -259,7 +254,7 @@ async function run() {
|
|||||||
getOptionalInput("registries"),
|
getOptionalInput("registries"),
|
||||||
getOptionalInput("config-file"),
|
getOptionalInput("config-file"),
|
||||||
getOptionalInput("db-location"),
|
getOptionalInput("db-location"),
|
||||||
await getTrapCachingEnabled(features),
|
getTrapCachingEnabled(),
|
||||||
// Debug mode is enabled if:
|
// Debug mode is enabled if:
|
||||||
// - The `init` Action is passed `debug: true`.
|
// - The `init` Action is passed `debug: true`.
|
||||||
// - Actions step debugging is enabled (e.g. by [enabling debug logging for a rerun](https://docs.github.com/en/actions/managing-workflow-runs/re-running-workflows-and-jobs#re-running-all-the-jobs-in-a-workflow),
|
// - Actions step debugging is enabled (e.g. by [enabling debug logging for a rerun](https://docs.github.com/en/actions/managing-workflow-runs/re-running-workflows-and-jobs#re-running-all-the-jobs-in-a-workflow),
|
||||||
@@ -391,9 +386,7 @@ async function run() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getTrapCachingEnabled(
|
function getTrapCachingEnabled(): boolean {
|
||||||
featureEnablement: FeatureEnablement
|
|
||||||
): Promise<boolean> {
|
|
||||||
// If the workflow specified something always respect that
|
// If the workflow specified something always respect that
|
||||||
const trapCaching = getOptionalInput("trap-caching");
|
const trapCaching = getOptionalInput("trap-caching");
|
||||||
if (trapCaching !== undefined) return trapCaching === "true";
|
if (trapCaching !== undefined) return trapCaching === "true";
|
||||||
@@ -401,8 +394,8 @@ async function getTrapCachingEnabled(
|
|||||||
// On self-hosted runners which may have slow network access, disable TRAP caching by default
|
// On self-hosted runners which may have slow network access, disable TRAP caching by default
|
||||||
if (!isHostedRunner()) return false;
|
if (!isHostedRunner()) return false;
|
||||||
|
|
||||||
// On hosted runners, respect the feature flag
|
// On hosted runners, enable TRAP caching by default
|
||||||
return await featureEnablement.getValue(Feature.TrapCachingEnabled);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runWrapper() {
|
async function runWrapper() {
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ export async function initCodeQL(
|
|||||||
apiDetails: GitHubApiDetails,
|
apiDetails: GitHubApiDetails,
|
||||||
tempDir: string,
|
tempDir: string,
|
||||||
variant: util.GitHubVariant,
|
variant: util.GitHubVariant,
|
||||||
bypassToolcache: boolean,
|
|
||||||
defaultCliVersion: CodeQLDefaultVersionInfo,
|
defaultCliVersion: CodeQLDefaultVersionInfo,
|
||||||
logger: Logger
|
logger: Logger
|
||||||
): Promise<{
|
): Promise<{
|
||||||
@@ -43,7 +42,6 @@ export async function initCodeQL(
|
|||||||
apiDetails,
|
apiDetails,
|
||||||
tempDir,
|
tempDir,
|
||||||
variant,
|
variant,
|
||||||
bypassToolcache,
|
|
||||||
defaultCliVersion,
|
defaultCliVersion,
|
||||||
logger,
|
logger,
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ export const LANGUAGE_ALIASES: { [lang: string]: Language } = {
|
|||||||
|
|
||||||
export type LanguageOrAlias = Language | keyof typeof LANGUAGE_ALIASES;
|
export type LanguageOrAlias = Language | keyof typeof LANGUAGE_ALIASES;
|
||||||
|
|
||||||
export const KOTLIN_SWIFT_BYPASS = ["kotlin", "swift"];
|
|
||||||
|
|
||||||
export function resolveAlias(lang: LanguageOrAlias): Language {
|
export function resolveAlias(lang: LanguageOrAlias): Language {
|
||||||
return LANGUAGE_ALIASES[lang] || lang;
|
return LANGUAGE_ALIASES[lang] || lang;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -241,24 +241,36 @@ async function getCodeQLBundleDownloadURL(
|
|||||||
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${codeQLBundleName}`;
|
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${codeQLBundleName}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBundleVersionFromTagName(tagName: string): string {
|
function tryGetBundleVersionFromTagName(
|
||||||
|
tagName: string,
|
||||||
|
logger: Logger
|
||||||
|
): string | undefined {
|
||||||
const match = tagName.match(/^codeql-bundle-(.*)$/);
|
const match = tagName.match(/^codeql-bundle-(.*)$/);
|
||||||
if (match === null || match.length < 2) {
|
if (match === null || match.length < 2) {
|
||||||
throw new Error(
|
logger.debug(`Could not determine bundle version from tag ${tagName}.`);
|
||||||
`Malformed bundle tag name: ${tagName}. Bundle version could not be inferred`
|
return undefined;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return match[1];
|
return match[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBundleVersionFromUrl(url: string): string {
|
function tryGetTagNameFromUrl(url: string, logger: Logger): string | undefined {
|
||||||
const match = url.match(/\/(codeql-bundle-.*)\//);
|
const match = url.match(/\/(codeql-bundle-.*)\//);
|
||||||
if (match === null || match.length < 2) {
|
if (match === null || match.length < 2) {
|
||||||
throw new Error(
|
logger.debug(`Could not determine tag name for URL ${url}.`);
|
||||||
`Malformed tools url: ${url}. Bundle version could not be inferred`
|
return undefined;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return getBundleVersionFromTagName(match[1]);
|
return match[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function tryGetBundleVersionFromUrl(
|
||||||
|
url: string,
|
||||||
|
logger: Logger
|
||||||
|
): string | undefined {
|
||||||
|
const tagName = tryGetTagNameFromUrl(url, logger);
|
||||||
|
if (tagName === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return tryGetBundleVersionFromTagName(tagName, logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function convertToSemVer(version: string, logger: Logger): string {
|
export function convertToSemVer(version: string, logger: Logger): string {
|
||||||
@@ -291,6 +303,8 @@ type CodeQLToolsSource =
|
|||||||
toolsVersion: string;
|
toolsVersion: string;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
|
/** Bundle version of the tools, if known. */
|
||||||
|
bundleVersion?: string;
|
||||||
/** CLI version of the tools, if known. */
|
/** CLI version of the tools, if known. */
|
||||||
cliVersion?: string;
|
cliVersion?: string;
|
||||||
codeqlURL: string;
|
codeqlURL: string;
|
||||||
@@ -299,22 +313,11 @@ type CodeQLToolsSource =
|
|||||||
toolsVersion: string;
|
toolsVersion: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getOrFindBundleTagName(
|
|
||||||
version: CodeQLDefaultVersionInfo,
|
|
||||||
logger: Logger
|
|
||||||
): Promise<string> {
|
|
||||||
if (version.variant === util.GitHubVariant.DOTCOM) {
|
|
||||||
return await findCodeQLBundleTagDotcomOnly(version.cliVersion, logger);
|
|
||||||
} else {
|
|
||||||
return version.tagName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look for a version of the CodeQL tools in the cache which could override the requested CLI version.
|
* Look for a version of the CodeQL tools in the cache which could override the requested CLI version.
|
||||||
*/
|
*/
|
||||||
async function findOverridingToolsInCache(
|
async function findOverridingToolsInCache(
|
||||||
requestedCliVersion: string,
|
humanReadableVersion: string,
|
||||||
logger: Logger
|
logger: Logger
|
||||||
): Promise<CodeQLToolsSource | undefined> {
|
): Promise<CodeQLToolsSource | undefined> {
|
||||||
const candidates = toolcache
|
const candidates = toolcache
|
||||||
@@ -329,7 +332,7 @@ async function findOverridingToolsInCache(
|
|||||||
if (candidates.length === 1) {
|
if (candidates.length === 1) {
|
||||||
const candidate = candidates[0];
|
const candidate = candidates[0];
|
||||||
logger.debug(
|
logger.debug(
|
||||||
`CodeQL tools version ${candidate.version} in toolcache overriding version ${requestedCliVersion}.`
|
`CodeQL tools version ${candidate.version} in toolcache overriding version ${humanReadableVersion}.`
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
codeqlFolder: candidate.folder,
|
codeqlFolder: candidate.folder,
|
||||||
@@ -351,7 +354,6 @@ async function findOverridingToolsInCache(
|
|||||||
|
|
||||||
export async function getCodeQLSource(
|
export async function getCodeQLSource(
|
||||||
toolsInput: string | undefined,
|
toolsInput: string | undefined,
|
||||||
bypassToolcache: boolean,
|
|
||||||
defaultCliVersion: CodeQLDefaultVersionInfo,
|
defaultCliVersion: CodeQLDefaultVersionInfo,
|
||||||
apiDetails: api.GitHubApiDetails,
|
apiDetails: api.GitHubApiDetails,
|
||||||
variant: util.GitHubVariant,
|
variant: util.GitHubVariant,
|
||||||
@@ -365,76 +367,73 @@ export async function getCodeQLSource(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const forceLatestReason =
|
|
||||||
// We use the special value of 'latest' to prioritize the version in the
|
|
||||||
// defaults over any pinned cached version.
|
|
||||||
toolsInput === "latest"
|
|
||||||
? '"tools: latest" was requested'
|
|
||||||
: // If the user hasn't requested a particular CodeQL version, then bypass
|
|
||||||
// the toolcache when the appropriate feature is enabled. This
|
|
||||||
// allows us to quickly rollback a broken bundle that has made its way
|
|
||||||
// into the toolcache.
|
|
||||||
toolsInput === undefined && bypassToolcache
|
|
||||||
? "a specific version of the CodeQL tools was not requested and the bypass toolcache feature is enabled"
|
|
||||||
: undefined;
|
|
||||||
const forceLatest = forceLatestReason !== undefined;
|
|
||||||
if (forceLatest) {
|
|
||||||
logger.debug(
|
|
||||||
`Forcing the latest version of the CodeQL tools since ${forceLatestReason}.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The requested version is:
|
* Whether the tools shipped with the Action, i.e. those in `defaults.json`, have been forced.
|
||||||
*
|
*
|
||||||
* 1. The one in `defaults.json`, if forceLatest is true.
|
* We use the special value of 'latest' to prioritize the version in `defaults.json` over the
|
||||||
* 2. The version specified by the tools input URL, if one was provided.
|
* version specified by the feature flags on Dotcom and over any pinned cached version on
|
||||||
* 3. The default CLI version, otherwise.
|
* Enterprise Server.
|
||||||
|
|
||||||
* We include a `variant` property to let us verify using the type system that
|
|
||||||
* `tagName` is only undefined when the variant is Dotcom. This lets us ensure
|
|
||||||
* that we can always compute `tagName`, either by using the existing tag name
|
|
||||||
* on enterprise instances, or calling `findCodeQLBundleTagDotcomOnly` on
|
|
||||||
* Dotcom.
|
|
||||||
*/
|
*/
|
||||||
const requestedVersion = forceLatest
|
const forceShippedTools = toolsInput === "latest";
|
||||||
? // case 1
|
if (forceShippedTools) {
|
||||||
{
|
logger.info(
|
||||||
cliVersion: defaults.cliVersion,
|
"Overriding the version of the CodeQL tools by the version shipped with the Action since " +
|
||||||
syntheticCliVersion: defaults.cliVersion,
|
`"tools: latest" was requested.`
|
||||||
tagName: defaults.bundleVersion,
|
|
||||||
variant,
|
|
||||||
}
|
|
||||||
: toolsInput !== undefined
|
|
||||||
? // case 2
|
|
||||||
{
|
|
||||||
syntheticCliVersion: convertToSemVer(
|
|
||||||
getBundleVersionFromUrl(toolsInput),
|
|
||||||
logger
|
|
||||||
),
|
|
||||||
tagName: `codeql-bundle-${getBundleVersionFromUrl(toolsInput)}`,
|
|
||||||
url: toolsInput,
|
|
||||||
variant,
|
|
||||||
}
|
|
||||||
: // case 3
|
|
||||||
{
|
|
||||||
...defaultCliVersion,
|
|
||||||
syntheticCliVersion: defaultCliVersion.cliVersion,
|
|
||||||
};
|
|
||||||
|
|
||||||
// If we find the specified version, we always use that.
|
|
||||||
let codeqlFolder = toolcache.find(
|
|
||||||
"CodeQL",
|
|
||||||
requestedVersion.syntheticCliVersion
|
|
||||||
);
|
);
|
||||||
let tagName: string | undefined = requestedVersion["tagName"];
|
}
|
||||||
|
|
||||||
|
/** CLI version number, for example 2.12.1. */
|
||||||
|
let cliVersion: string | undefined;
|
||||||
|
/** Tag name of the CodeQL bundle, for example `codeql-bundle-20230120`. */
|
||||||
|
let tagName: string | undefined;
|
||||||
|
/**
|
||||||
|
* URL of the CodeQL bundle.
|
||||||
|
*
|
||||||
|
* This does not always include a tag name.
|
||||||
|
*/
|
||||||
|
let url: string | undefined;
|
||||||
|
|
||||||
|
if (forceShippedTools) {
|
||||||
|
cliVersion = defaults.cliVersion;
|
||||||
|
tagName = defaults.bundleVersion;
|
||||||
|
} else if (toolsInput !== undefined) {
|
||||||
|
// If a tools URL was provided, then use that.
|
||||||
|
tagName = tryGetTagNameFromUrl(toolsInput, logger);
|
||||||
|
url = toolsInput;
|
||||||
|
} else {
|
||||||
|
// Otherwise, use the default CLI version passed in.
|
||||||
|
cliVersion = defaultCliVersion.cliVersion;
|
||||||
|
tagName = defaultCliVersion["tagName"];
|
||||||
|
}
|
||||||
|
|
||||||
|
const bundleVersion =
|
||||||
|
tagName && tryGetBundleVersionFromTagName(tagName, logger);
|
||||||
|
const humanReadableVersion =
|
||||||
|
cliVersion ??
|
||||||
|
(bundleVersion && convertToSemVer(bundleVersion, logger)) ??
|
||||||
|
tagName ??
|
||||||
|
url ??
|
||||||
|
"unknown";
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
"Attempting to obtain CodeQL tools. " +
|
||||||
|
`CLI version: ${cliVersion ?? "unknown"}, ` +
|
||||||
|
`bundle tag name: ${tagName ?? "unknown"}, ` +
|
||||||
|
`URL: ${url ?? "unspecified"}.`
|
||||||
|
);
|
||||||
|
|
||||||
|
let codeqlFolder;
|
||||||
|
|
||||||
|
if (cliVersion) {
|
||||||
|
// If we find the specified CLI version, we always use that.
|
||||||
|
codeqlFolder = toolcache.find("CodeQL", cliVersion);
|
||||||
|
|
||||||
|
// Fall back to matching `x.y.z-<tagName>`.
|
||||||
if (!codeqlFolder) {
|
if (!codeqlFolder) {
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Didn't find a version of the CodeQL tools in the toolcache with a version number " +
|
"Didn't find a version of the CodeQL tools in the toolcache with a version number " +
|
||||||
`exactly matching ${requestedVersion.syntheticCliVersion}.`
|
`exactly matching ${cliVersion}.`
|
||||||
);
|
);
|
||||||
if (requestedVersion.cliVersion) {
|
|
||||||
const allVersions = toolcache.findAllVersions("CodeQL");
|
const allVersions = toolcache.findAllVersions("CodeQL");
|
||||||
logger.debug(
|
logger.debug(
|
||||||
`Found the following versions of the CodeQL tools in the toolcache: ${JSON.stringify(
|
`Found the following versions of the CodeQL tools in the toolcache: ${JSON.stringify(
|
||||||
@@ -444,55 +443,82 @@ export async function getCodeQLSource(
|
|||||||
// If there is exactly one version of the CodeQL tools in the toolcache, and that version is
|
// If there is exactly one version of the CodeQL tools in the toolcache, and that version is
|
||||||
// the form `x.y.z-<tagName>`, then use it.
|
// the form `x.y.z-<tagName>`, then use it.
|
||||||
const candidateVersions = allVersions.filter((version) =>
|
const candidateVersions = allVersions.filter((version) =>
|
||||||
version.startsWith(`${requestedVersion.cliVersion}-`)
|
version.startsWith(`${cliVersion}-`)
|
||||||
);
|
);
|
||||||
if (candidateVersions.length === 1) {
|
if (candidateVersions.length === 1) {
|
||||||
logger.debug("Exactly one candidate version found, using that.");
|
|
||||||
codeqlFolder = toolcache.find("CodeQL", candidateVersions[0]);
|
|
||||||
} else {
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Did not find exactly one version of the CodeQL tools starting with the requested version."
|
`Exactly one version of the CodeQL tools starting with ${cliVersion} found in the ` +
|
||||||
|
"toolcache, using that."
|
||||||
);
|
);
|
||||||
|
codeqlFolder = toolcache.find("CodeQL", candidateVersions[0]);
|
||||||
|
} else if (candidateVersions.length === 0) {
|
||||||
|
logger.debug(
|
||||||
|
`Didn't find any versions of the CodeQL tools starting with ${cliVersion} ` +
|
||||||
|
`in the toolcache. Trying next fallback method.`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
logger.warning(
|
||||||
|
`Found ${candidateVersions.length} versions of the CodeQL tools starting with ` +
|
||||||
|
`${cliVersion} in the toolcache, but at most one was expected.`
|
||||||
|
);
|
||||||
|
logger.debug("Trying next fallback method.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!codeqlFolder && requestedVersion.cliVersion) {
|
// Fall back to matching `0.0.0-<bundleVersion>`.
|
||||||
// Fall back to accepting a `0.0.0-<bundleVersion>` version if we didn't find the
|
if (!codeqlFolder && (cliVersion || tagName)) {
|
||||||
// `x.y.z` version. This is to support old versions of the toolcache.
|
if (cliVersion || tagName) {
|
||||||
//
|
const fallbackVersion = await tryGetFallbackToolcacheVersion(
|
||||||
// If we are on Dotcom, we will make an HTTP request to the Releases API here
|
cliVersion,
|
||||||
// to find the tag name for the requested version.
|
tagName,
|
||||||
tagName =
|
variant,
|
||||||
tagName || (await getOrFindBundleTagName(requestedVersion, logger));
|
|
||||||
const fallbackVersion = convertToSemVer(
|
|
||||||
getBundleVersionFromTagName(tagName),
|
|
||||||
logger
|
logger
|
||||||
);
|
);
|
||||||
logger.debug(
|
if (fallbackVersion) {
|
||||||
`Computed a fallback toolcache version number of ${fallbackVersion} for CodeQL tools version ` +
|
|
||||||
`${requestedVersion.cliVersion}.`
|
|
||||||
);
|
|
||||||
codeqlFolder = toolcache.find("CodeQL", fallbackVersion);
|
codeqlFolder = toolcache.find("CodeQL", fallbackVersion);
|
||||||
|
} else {
|
||||||
|
logger.debug(
|
||||||
|
"Could not determine a fallback toolcache version number for CodeQL tools version " +
|
||||||
|
`${humanReadableVersion}.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.debug(
|
||||||
|
"Both the CLI version and the bundle version are unknown, so we will not be able to find " +
|
||||||
|
"the requested version of the CodeQL tools in the toolcache."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codeqlFolder) {
|
||||||
|
logger.info(
|
||||||
|
`Found CodeQL tools version ${humanReadableVersion} in the toolcache.`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
logger.info(
|
||||||
|
`Did not find CodeQL tools version ${humanReadableVersion} in the toolcache.`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codeqlFolder) {
|
if (codeqlFolder) {
|
||||||
return {
|
return {
|
||||||
codeqlFolder,
|
codeqlFolder,
|
||||||
sourceType: "toolcache",
|
sourceType: "toolcache",
|
||||||
toolsVersion: requestedVersion.syntheticCliVersion,
|
toolsVersion: cliVersion ?? humanReadableVersion,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
logger.debug(
|
|
||||||
`Did not find CodeQL tools version ${requestedVersion.syntheticCliVersion} in the toolcache.`
|
|
||||||
);
|
|
||||||
|
|
||||||
// If we don't find the requested version on Enterprise, we may allow a
|
// If we don't find the requested version on Enterprise, we may allow a
|
||||||
// different version to save download time if the version hasn't been
|
// different version to save download time if the version hasn't been
|
||||||
// specified explicitly (in which case we always honor it).
|
// specified explicitly (in which case we always honor it).
|
||||||
if (variant !== util.GitHubVariant.DOTCOM && !forceLatest && !toolsInput) {
|
if (
|
||||||
|
variant !== util.GitHubVariant.DOTCOM &&
|
||||||
|
!forceShippedTools &&
|
||||||
|
!toolsInput
|
||||||
|
) {
|
||||||
const result = await findOverridingToolsInCache(
|
const result = await findOverridingToolsInCache(
|
||||||
requestedVersion.syntheticCliVersion,
|
humanReadableVersion,
|
||||||
logger
|
logger
|
||||||
);
|
);
|
||||||
if (result !== undefined) {
|
if (result !== undefined) {
|
||||||
@@ -500,30 +526,66 @@ export async function getCodeQLSource(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
if (!url) {
|
||||||
cliVersion: requestedVersion.cliVersion || undefined,
|
if (!tagName && cliVersion && variant === util.GitHubVariant.DOTCOM) {
|
||||||
codeqlURL:
|
tagName = await findCodeQLBundleTagDotcomOnly(cliVersion, logger);
|
||||||
requestedVersion["url"] ||
|
} else if (!tagName) {
|
||||||
(await getCodeQLBundleDownloadURL(
|
throw new Error(
|
||||||
tagName ||
|
`Could not obtain the requested version (${humanReadableVersion}) of the CodeQL tools ` +
|
||||||
// The check on `requestedVersion.tagName` is redundant but lets us
|
"since we could not compute the tag name."
|
||||||
// use the property that if we don't know `requestedVersion.tagName`,
|
);
|
||||||
// then we must know `requestedVersion.cliVersion`. This property is
|
}
|
||||||
// required by the type of `getOrFindBundleTagName`.
|
url = await getCodeQLBundleDownloadURL(
|
||||||
(requestedVersion.tagName !== undefined
|
tagName,
|
||||||
? requestedVersion.tagName
|
|
||||||
: await getOrFindBundleTagName(requestedVersion, logger)),
|
|
||||||
apiDetails,
|
apiDetails,
|
||||||
variant,
|
variant,
|
||||||
logger
|
logger
|
||||||
)),
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
bundleVersion: tagName && tryGetBundleVersionFromTagName(tagName, logger),
|
||||||
|
cliVersion,
|
||||||
|
codeqlURL: url,
|
||||||
sourceType: "download",
|
sourceType: "download",
|
||||||
toolsVersion: requestedVersion.syntheticCliVersion,
|
toolsVersion: cliVersion ?? humanReadableVersion,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a fallback version number to use when looking for CodeQL in the toolcache if we didn't find
|
||||||
|
* the `x.y.z` version. This is to support old versions of the toolcache.
|
||||||
|
*/
|
||||||
|
export async function tryGetFallbackToolcacheVersion(
|
||||||
|
cliVersion: string | undefined,
|
||||||
|
tagName: string | undefined,
|
||||||
|
variant: util.GitHubVariant,
|
||||||
|
logger: Logger
|
||||||
|
): Promise<string | undefined> {
|
||||||
|
//
|
||||||
|
// If we are on Dotcom, we will make an HTTP request to the Releases API here
|
||||||
|
// to find the tag name for the requested version.
|
||||||
|
if (cliVersion && !tagName && variant === util.GitHubVariant.DOTCOM) {
|
||||||
|
tagName = await findCodeQLBundleTagDotcomOnly(cliVersion, logger);
|
||||||
|
}
|
||||||
|
if (!tagName) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const bundleVersion = tryGetBundleVersionFromTagName(tagName, logger);
|
||||||
|
if (!bundleVersion) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const fallbackVersion = convertToSemVer(bundleVersion, logger);
|
||||||
|
logger.debug(
|
||||||
|
`Computed a fallback toolcache version number of ${fallbackVersion} for CodeQL version ` +
|
||||||
|
`${cliVersion ?? tagName}.`
|
||||||
|
);
|
||||||
|
return fallbackVersion;
|
||||||
|
}
|
||||||
|
|
||||||
export async function downloadCodeQL(
|
export async function downloadCodeQL(
|
||||||
codeqlURL: string,
|
codeqlURL: string,
|
||||||
|
maybeBundleVersion: string | undefined,
|
||||||
maybeCliVersion: string | undefined,
|
maybeCliVersion: string | undefined,
|
||||||
apiDetails: api.GitHubApiDetails,
|
apiDetails: api.GitHubApiDetails,
|
||||||
variant: util.GitHubVariant,
|
variant: util.GitHubVariant,
|
||||||
@@ -543,11 +605,12 @@ export async function downloadCodeQL(
|
|||||||
// from the same GitHub instance the Action is running on.
|
// from the same GitHub instance the Action is running on.
|
||||||
// This avoids leaking Enterprise tokens to dotcom.
|
// This avoids leaking Enterprise tokens to dotcom.
|
||||||
// We also don't want to send an authorization header if there's already a token provided in the URL.
|
// We also don't want to send an authorization header if there's already a token provided in the URL.
|
||||||
|
let authorization: string | undefined = undefined;
|
||||||
if (searchParams.has("token")) {
|
if (searchParams.has("token")) {
|
||||||
logger.debug("CodeQL tools URL contains an authorization token.");
|
logger.debug("CodeQL tools URL contains an authorization token.");
|
||||||
} else if (codeqlURL.startsWith(`${apiDetails.url}/`)) {
|
} else if (codeqlURL.startsWith(`${apiDetails.url}/`)) {
|
||||||
logger.debug("Providing an authorization token to download CodeQL tools.");
|
logger.debug("Providing an authorization token to download CodeQL tools.");
|
||||||
headers.authorization = `token ${apiDetails.auth}`;
|
authorization = `token ${apiDetails.auth}`;
|
||||||
} else {
|
} else {
|
||||||
logger.debug("Downloading CodeQL tools without an authorization token.");
|
logger.debug("Downloading CodeQL tools without an authorization token.");
|
||||||
}
|
}
|
||||||
@@ -565,7 +628,7 @@ export async function downloadCodeQL(
|
|||||||
const codeqlPath = await toolcache.downloadTool(
|
const codeqlPath = await toolcache.downloadTool(
|
||||||
codeqlURL,
|
codeqlURL,
|
||||||
dest,
|
dest,
|
||||||
undefined,
|
authorization,
|
||||||
finalHeaders
|
finalHeaders
|
||||||
);
|
);
|
||||||
const toolsDownloadDurationMs = Math.round(
|
const toolsDownloadDurationMs = Math.round(
|
||||||
@@ -576,16 +639,33 @@ export async function downloadCodeQL(
|
|||||||
|
|
||||||
const codeqlExtracted = await toolcache.extractTar(codeqlPath);
|
const codeqlExtracted = await toolcache.extractTar(codeqlPath);
|
||||||
|
|
||||||
const bundleVersion = getBundleVersionFromUrl(codeqlURL);
|
const bundleVersion =
|
||||||
|
maybeBundleVersion ?? tryGetBundleVersionFromUrl(codeqlURL, logger);
|
||||||
|
|
||||||
|
if (bundleVersion === undefined) {
|
||||||
|
logger.debug(
|
||||||
|
"Could not cache CodeQL tools because we could not determine the bundle version from the " +
|
||||||
|
`URL ${codeqlURL}.`
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
toolsVersion: maybeCliVersion ?? "unknown",
|
||||||
|
codeqlFolder: codeqlExtracted,
|
||||||
|
toolsDownloadDurationMs,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Try to compute the CLI version for this bundle
|
// Try to compute the CLI version for this bundle
|
||||||
const cliVersion: string | undefined =
|
if (
|
||||||
maybeCliVersion ||
|
maybeCliVersion === undefined &&
|
||||||
(variant === util.GitHubVariant.DOTCOM &&
|
variant === util.GitHubVariant.DOTCOM &&
|
||||||
(await tryFindCliVersionDotcomOnly(
|
codeqlURL.includes(`/${CODEQL_DEFAULT_ACTION_REPOSITORY}/`)
|
||||||
|
) {
|
||||||
|
maybeCliVersion = await tryFindCliVersionDotcomOnly(
|
||||||
`codeql-bundle-${bundleVersion}`,
|
`codeql-bundle-${bundleVersion}`,
|
||||||
logger
|
logger
|
||||||
))) ||
|
);
|
||||||
undefined;
|
}
|
||||||
|
|
||||||
// Include both the CLI version and the bundle version in the toolcache version number. That way
|
// Include both the CLI version and the bundle version in the toolcache version number. That way
|
||||||
// if the user requests the same URL again, we can get it from the cache without having to call
|
// if the user requests the same URL again, we can get it from the cache without having to call
|
||||||
// any of the Releases API.
|
// any of the Releases API.
|
||||||
@@ -595,12 +675,11 @@ export async function downloadCodeQL(
|
|||||||
// CLI release. In principle, it should be enough to just check that the CLI version isn't a
|
// CLI release. In principle, it should be enough to just check that the CLI version isn't a
|
||||||
// pre-release, but the version numbers of CodeQL nightlies have the format `x.y.z+<timestamp>`,
|
// pre-release, but the version numbers of CodeQL nightlies have the format `x.y.z+<timestamp>`,
|
||||||
// and we don't want these nightlies to override stable CLI versions in the toolcache.
|
// and we don't want these nightlies to override stable CLI versions in the toolcache.
|
||||||
const toolcacheVersion =
|
const toolcacheVersion = maybeCliVersion?.match(/^[0-9]+\.[0-9]+\.[0-9]+$/)
|
||||||
cliVersion && cliVersion.match(/^[0-9]+\.[0-9]+\.[0-9]+$/)
|
? `${maybeCliVersion}-${bundleVersion}`
|
||||||
? `${cliVersion}-${bundleVersion}`
|
|
||||||
: convertToSemVer(bundleVersion, logger);
|
: convertToSemVer(bundleVersion, logger);
|
||||||
return {
|
return {
|
||||||
toolsVersion: cliVersion || toolcacheVersion,
|
toolsVersion: maybeCliVersion ?? toolcacheVersion,
|
||||||
codeqlFolder: await toolcache.cacheDir(
|
codeqlFolder: await toolcache.cacheDir(
|
||||||
codeqlExtracted,
|
codeqlExtracted,
|
||||||
"CodeQL",
|
"CodeQL",
|
||||||
@@ -627,7 +706,6 @@ export function getCodeQLURLVersion(url: string): string {
|
|||||||
* @param apiDetails
|
* @param apiDetails
|
||||||
* @param tempDir
|
* @param tempDir
|
||||||
* @param variant
|
* @param variant
|
||||||
* @param bypassToolcache
|
|
||||||
* @param defaultCliVersion
|
* @param defaultCliVersion
|
||||||
* @param logger
|
* @param logger
|
||||||
* @param checkVersion Whether to check that CodeQL CLI meets the minimum
|
* @param checkVersion Whether to check that CodeQL CLI meets the minimum
|
||||||
@@ -639,7 +717,6 @@ export async function setupCodeQLBundle(
|
|||||||
apiDetails: api.GitHubApiDetails,
|
apiDetails: api.GitHubApiDetails,
|
||||||
tempDir: string,
|
tempDir: string,
|
||||||
variant: util.GitHubVariant,
|
variant: util.GitHubVariant,
|
||||||
bypassToolcache: boolean,
|
|
||||||
defaultCliVersion: CodeQLDefaultVersionInfo,
|
defaultCliVersion: CodeQLDefaultVersionInfo,
|
||||||
logger: Logger
|
logger: Logger
|
||||||
): Promise<{
|
): Promise<{
|
||||||
@@ -650,7 +727,6 @@ export async function setupCodeQLBundle(
|
|||||||
}> {
|
}> {
|
||||||
const source = await getCodeQLSource(
|
const source = await getCodeQLSource(
|
||||||
toolsInput,
|
toolsInput,
|
||||||
bypassToolcache,
|
|
||||||
defaultCliVersion,
|
defaultCliVersion,
|
||||||
apiDetails,
|
apiDetails,
|
||||||
variant,
|
variant,
|
||||||
@@ -674,6 +750,7 @@ export async function setupCodeQLBundle(
|
|||||||
case "download": {
|
case "download": {
|
||||||
const result = await downloadCodeQL(
|
const result = await downloadCodeQL(
|
||||||
source.codeqlURL,
|
source.codeqlURL,
|
||||||
|
source.bundleVersion,
|
||||||
source.cliVersion,
|
source.cliVersion,
|
||||||
apiDetails,
|
apiDetails,
|
||||||
variant,
|
variant,
|
||||||
|
|||||||
@@ -416,7 +416,8 @@ export async function waitForProcessing(
|
|||||||
statusCheckingStarted + STATUS_CHECK_TIMEOUT_MILLISECONDS
|
statusCheckingStarted + STATUS_CHECK_TIMEOUT_MILLISECONDS
|
||||||
) {
|
) {
|
||||||
// If the analysis hasn't finished processing in the allotted time, we continue anyway rather than failing.
|
// If the analysis hasn't finished processing in the allotted time, we continue anyway rather than failing.
|
||||||
// It's possible the analysis will eventually finish processing, but it's not worth spending more Actions time waiting.
|
// It's possible the analysis will eventually finish processing, but it's not worth spending more
|
||||||
|
// Actions time waiting.
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"Timed out waiting for analysis to finish processing. Continuing."
|
"Timed out waiting for analysis to finish processing. Continuing."
|
||||||
);
|
);
|
||||||
@@ -462,7 +463,9 @@ export async function waitForProcessing(
|
|||||||
util.assertNever(status);
|
util.assertNever(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
await util.delay(STATUS_CHECK_FREQUENCY_MILLISECONDS);
|
await util.delay(STATUS_CHECK_FREQUENCY_MILLISECONDS, {
|
||||||
|
allowProcessExit: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
logger.endGroup();
|
logger.endGroup();
|
||||||
|
|||||||
128
src/util.test.ts
128
src/util.test.ts
@@ -8,14 +8,8 @@ import * as sinon from "sinon";
|
|||||||
|
|
||||||
import * as api from "./api-client";
|
import * as api from "./api-client";
|
||||||
import { Config } from "./config-utils";
|
import { Config } from "./config-utils";
|
||||||
import { Feature } from "./feature-flags";
|
|
||||||
import { getRunnerLogger } from "./logging";
|
import { getRunnerLogger } from "./logging";
|
||||||
import { parseRepositoryNwo } from "./repository";
|
import { setupTests } from "./testing-utils";
|
||||||
import {
|
|
||||||
createFeatures,
|
|
||||||
mockLanguagesInRepo,
|
|
||||||
setupTests,
|
|
||||||
} from "./testing-utils";
|
|
||||||
import * as util from "./util";
|
import * as util from "./util";
|
||||||
|
|
||||||
setupTests(test);
|
setupTests(test);
|
||||||
@@ -398,123 +392,3 @@ test("withTimeout doesn't call callback if promise resolves", async (t) => {
|
|||||||
t.deepEqual(shortTaskTimedOut, false);
|
t.deepEqual(shortTaskTimedOut, false);
|
||||||
t.deepEqual(result, 99);
|
t.deepEqual(result, 99);
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockRepositoryNwo = parseRepositoryNwo("owner/repo");
|
|
||||||
// eslint-disable-next-line github/array-foreach
|
|
||||||
[
|
|
||||||
{
|
|
||||||
name: "disabled",
|
|
||||||
features: [],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: undefined,
|
|
||||||
languagesInRepository: [],
|
|
||||||
expected: false,
|
|
||||||
expectedApiCall: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "disabled even though swift kotlin bypassed",
|
|
||||||
features: [Feature.BypassToolcacheKotlinSwiftEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: undefined,
|
|
||||||
languagesInRepository: [],
|
|
||||||
expected: false,
|
|
||||||
expectedApiCall: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "disabled even though swift kotlin analyzed",
|
|
||||||
features: [],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: " sWiFt , KoTlIn ",
|
|
||||||
languagesInRepository: [],
|
|
||||||
expected: false,
|
|
||||||
expectedApiCall: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "toolcache bypass all",
|
|
||||||
features: [Feature.BypassToolcacheEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: undefined,
|
|
||||||
languagesInRepository: [],
|
|
||||||
expected: true,
|
|
||||||
expectedApiCall: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "custom CodeQL",
|
|
||||||
features: [],
|
|
||||||
hasCustomCodeQL: true,
|
|
||||||
languagesInput: undefined,
|
|
||||||
languagesInRepository: [],
|
|
||||||
expected: true,
|
|
||||||
expectedApiCall: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "bypass swift",
|
|
||||||
features: [Feature.BypassToolcacheKotlinSwiftEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: " sWiFt ,other",
|
|
||||||
languagesInRepository: [],
|
|
||||||
expected: true,
|
|
||||||
expectedApiCall: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "bypass kotlin",
|
|
||||||
features: [Feature.BypassToolcacheKotlinSwiftEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: "other, KoTlIn ",
|
|
||||||
languagesInRepository: [],
|
|
||||||
expected: true,
|
|
||||||
expectedApiCall: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "bypass kotlin language from repository",
|
|
||||||
features: [Feature.BypassToolcacheKotlinSwiftEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: "",
|
|
||||||
languagesInRepository: ["KoTlIn", "other"],
|
|
||||||
expected: true,
|
|
||||||
expectedApiCall: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "bypass swift language from repository",
|
|
||||||
features: [Feature.BypassToolcacheKotlinSwiftEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: "",
|
|
||||||
languagesInRepository: ["SwiFt", "other"],
|
|
||||||
expected: true,
|
|
||||||
expectedApiCall: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "bypass java from input if there is kotlin in repository",
|
|
||||||
features: [Feature.BypassToolcacheKotlinSwiftEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: "java",
|
|
||||||
languagesInRepository: ["kotlin", "other"],
|
|
||||||
expected: true,
|
|
||||||
expectedApiCall: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "don't bypass java from input if there is no kotlin in repository",
|
|
||||||
features: [Feature.BypassToolcacheKotlinSwiftEnabled],
|
|
||||||
hasCustomCodeQL: false,
|
|
||||||
languagesInput: "java",
|
|
||||||
languagesInRepository: ["java", "other"],
|
|
||||||
expected: false,
|
|
||||||
expectedApiCall: true,
|
|
||||||
},
|
|
||||||
].forEach((args) => {
|
|
||||||
test(`shouldBypassToolcache: ${args.name}`, async (t) => {
|
|
||||||
const mockRequest = mockLanguagesInRepo(args.languagesInRepository);
|
|
||||||
const mockLogger = getRunnerLogger(true);
|
|
||||||
const featureEnablement = createFeatures(args.features);
|
|
||||||
const codeqlUrl = args.hasCustomCodeQL ? "custom-codeql-url" : undefined;
|
|
||||||
const actual = await util.shouldBypassToolcache(
|
|
||||||
featureEnablement,
|
|
||||||
codeqlUrl,
|
|
||||||
args.languagesInput,
|
|
||||||
mockRepositoryNwo,
|
|
||||||
mockLogger
|
|
||||||
);
|
|
||||||
t.deepEqual(actual, args.expected);
|
|
||||||
t.deepEqual(mockRequest.called, args.expectedApiCall);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|||||||
83
src/util.ts
83
src/util.ts
@@ -13,15 +13,12 @@ import * as apiCompatibility from "./api-compatibility.json";
|
|||||||
import { CodeQL, CODEQL_VERSION_NEW_TRACING } from "./codeql";
|
import { CodeQL, CODEQL_VERSION_NEW_TRACING } from "./codeql";
|
||||||
import {
|
import {
|
||||||
Config,
|
Config,
|
||||||
getLanguagesInRepo,
|
|
||||||
getRawLanguages,
|
|
||||||
parsePacksSpecification,
|
parsePacksSpecification,
|
||||||
prettyPrintPack,
|
prettyPrintPack,
|
||||||
} from "./config-utils";
|
} from "./config-utils";
|
||||||
import { Feature, FeatureEnablement } from "./feature-flags";
|
import { Feature, FeatureEnablement } from "./feature-flags";
|
||||||
import { KOTLIN_SWIFT_BYPASS, Language } from "./languages";
|
import { Language } from "./languages";
|
||||||
import { Logger } from "./logging";
|
import { Logger } from "./logging";
|
||||||
import { RepositoryNwo } from "./repository";
|
|
||||||
import { CODEQL_ACTION_TEST_MODE } from "./shared-environment";
|
import { CODEQL_ACTION_TEST_MODE } from "./shared-environment";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -551,10 +548,23 @@ export async function bundleDb(
|
|||||||
return databaseBundlePath;
|
return databaseBundlePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function delay(milliseconds: number) {
|
/**
|
||||||
|
* @param milliseconds time to delay
|
||||||
|
* @param opts options
|
||||||
|
* @param opts.allowProcessExit if true, the timer will not prevent the process from exiting
|
||||||
|
*/
|
||||||
|
export async function delay(
|
||||||
|
milliseconds: number,
|
||||||
|
{ allowProcessExit }: { allowProcessExit: boolean }
|
||||||
|
) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const timer = setTimeout(resolve, milliseconds);
|
||||||
|
if (allowProcessExit) {
|
||||||
// Immediately `unref` the timer such that it only prevents the process from exiting if the
|
// Immediately `unref` the timer such that it only prevents the process from exiting if the
|
||||||
// surrounding promise is being awaited.
|
// surrounding promise is being awaited.
|
||||||
return new Promise((resolve) => setTimeout(resolve, milliseconds).unref());
|
timer.unref();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isGoodVersion(versionSpec: string) {
|
export function isGoodVersion(versionSpec: string) {
|
||||||
@@ -751,7 +761,7 @@ export async function withTimeout<T>(
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
const timeoutTask = async () => {
|
const timeoutTask = async () => {
|
||||||
await delay(timeoutMs);
|
await delay(timeoutMs, { allowProcessExit: true });
|
||||||
if (!finished) {
|
if (!finished) {
|
||||||
// Workaround: While the promise racing below will allow the main code
|
// Workaround: While the promise racing below will allow the main code
|
||||||
// to continue, the process won't normally exit until the asynchronous
|
// to continue, the process won't normally exit until the asynchronous
|
||||||
@@ -776,7 +786,7 @@ export async function checkForTimeout() {
|
|||||||
core.info(
|
core.info(
|
||||||
"A timeout occurred, force exiting the process after 30 seconds to prevent hanging."
|
"A timeout occurred, force exiting the process after 30 seconds to prevent hanging."
|
||||||
);
|
);
|
||||||
await delay(30_000);
|
await delay(30_000, { allowProcessExit: true });
|
||||||
process.exit();
|
process.exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -802,63 +812,6 @@ export function isHostedRunner() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param featuresEnablement The features enabled for the current run
|
|
||||||
* @param languagesInput Languages input from the workflow
|
|
||||||
* @param repository The owner/name of the repository
|
|
||||||
* @param logger A logger
|
|
||||||
* @returns A boolean indicating whether or not the toolcache should be bypassed and the latest codeql should be downloaded.
|
|
||||||
*/
|
|
||||||
export async function shouldBypassToolcache(
|
|
||||||
featuresEnablement: FeatureEnablement,
|
|
||||||
codeqlUrl: string | undefined,
|
|
||||||
languagesInput: string | undefined,
|
|
||||||
repository: RepositoryNwo,
|
|
||||||
logger: Logger
|
|
||||||
): Promise<boolean> {
|
|
||||||
// An explicit codeql url is specified, that means the toolcache will not be used.
|
|
||||||
if (codeqlUrl) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the toolcache is disabled for all languages
|
|
||||||
if (await featuresEnablement.getValue(Feature.BypassToolcacheEnabled)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the toolcache is disabled for kotlin and swift.
|
|
||||||
if (
|
|
||||||
!(await featuresEnablement.getValue(
|
|
||||||
Feature.BypassToolcacheKotlinSwiftEnabled
|
|
||||||
))
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now check to see if kotlin or swift is one of the languages being analyzed.
|
|
||||||
const { rawLanguages, autodetected } = await getRawLanguages(
|
|
||||||
languagesInput,
|
|
||||||
repository,
|
|
||||||
logger
|
|
||||||
);
|
|
||||||
let bypass = rawLanguages.some((lang) => KOTLIN_SWIFT_BYPASS.includes(lang));
|
|
||||||
if (bypass) {
|
|
||||||
logger.info(
|
|
||||||
`Bypassing toolcache for kotlin or swift. Languages: ${rawLanguages}`
|
|
||||||
);
|
|
||||||
} else if (!autodetected && rawLanguages.includes(Language.java)) {
|
|
||||||
// special case: java was explicitly specified, but there might be
|
|
||||||
// some kotlin in the repository, so we need to make a request for that.
|
|
||||||
const langsInRepo = await getLanguagesInRepo(repository, logger);
|
|
||||||
if (langsInRepo.includes("kotlin")) {
|
|
||||||
logger.info(`Bypassing toolcache for kotlin.`);
|
|
||||||
bypass = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bypass;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function parseMatrixInput(
|
export function parseMatrixInput(
|
||||||
matrixInput: string | undefined
|
matrixInput: string | undefined
|
||||||
): { [key: string]: string } | undefined {
|
): { [key: string]: string } | undefined {
|
||||||
|
|||||||
Reference in New Issue
Block a user