mirror of
https://github.com/github/codeql-action.git
synced 2025-12-12 18:50:12 +08:00
Compare commits
19 Commits
v3.24.0
...
platform_l
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11e79a34aa | ||
|
|
8547a7593c | ||
|
|
f8e92620cb | ||
|
|
1157017557 | ||
|
|
c25320cfef | ||
|
|
7f2fa9ca20 | ||
|
|
b9f08d924a | ||
|
|
4d836f4b5a | ||
|
|
b9e8fa6371 | ||
|
|
0ca7a34758 | ||
|
|
d093fc0304 | ||
|
|
7b29d2e0a5 | ||
|
|
588a28d3b5 | ||
|
|
57b0b7fd1d | ||
|
|
d3d7dd4600 | ||
|
|
3f5bb98d7e | ||
|
|
7951f91d00 | ||
|
|
408e376177 | ||
|
|
e4c39c9b06 |
42
.github/workflows/integration-testing.yml
vendored
42
.github/workflows/integration-testing.yml
vendored
@@ -127,6 +127,48 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
TEST_MODE: true
|
TEST_MODE: true
|
||||||
|
|
||||||
|
single-language-bundles:
|
||||||
|
# These are 21 jobs, run them only if the earlier multi-language job suceeded
|
||||||
|
# needs: multi-language-repo_test-autodetect-languages
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
|
language: ["none", "cpp", "csharp", "go", "java", "javascript", "python"]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Move codeql-action
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir ../action
|
||||||
|
mv * .github ../action/
|
||||||
|
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||||
|
|
||||||
|
# The next 2 steps are mutually exclusive.
|
||||||
|
# In one case, we setup codeql for a single language.
|
||||||
|
# In the other, we setup codeql for a platform
|
||||||
|
- name: Test language-specific bundle
|
||||||
|
uses: ./../action/init
|
||||||
|
if: matrix.language != 'none'
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
- name: Test platform-secific bundle
|
||||||
|
uses: ./../action/init
|
||||||
|
if: matrix.language == 'none'
|
||||||
|
|
||||||
|
- name: Build code
|
||||||
|
shell: bash
|
||||||
|
run: ./build.sh
|
||||||
|
- uses: ./../action/analyze
|
||||||
|
env:
|
||||||
|
TEST_MODE: true
|
||||||
|
|
||||||
|
- name: Check ToolCache (language-specific bundle)
|
||||||
|
if: matrix.language != 'none'
|
||||||
|
shell: bash
|
||||||
|
run: test -n "$(find -maxdepth 1 -name "codeql-bundle-0.0.0-*.${OS}-${{matrix.language}}" -print -quit)"
|
||||||
|
|
||||||
test-proxy:
|
test-proxy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
|
|||||||
87
lib/codeql.js
generated
87
lib/codeql.js
generated
@@ -52,7 +52,7 @@ function getCodeQLActionRepository(mode) {
|
|||||||
const relativeScriptPathParts = relativeScriptPath.split(path.sep);
|
const relativeScriptPathParts = relativeScriptPath.split(path.sep);
|
||||||
return `${relativeScriptPathParts[0]}/${relativeScriptPathParts[1]}`;
|
return `${relativeScriptPathParts[0]}/${relativeScriptPathParts[1]}`;
|
||||||
}
|
}
|
||||||
async function getCodeQLBundleDownloadURL(githubAuth, githubUrl, mode, logger) {
|
async function getCodeQLBundleDownloadURL(bundleNames, githubAuth, githubUrl, mode, logger) {
|
||||||
const codeQLActionRepository = getCodeQLActionRepository(mode);
|
const codeQLActionRepository = getCodeQLActionRepository(mode);
|
||||||
const potentialDownloadSources = [
|
const potentialDownloadSources = [
|
||||||
// This GitHub instance, and this Action.
|
// This GitHub instance, and this Action.
|
||||||
@@ -67,10 +67,10 @@ async function getCodeQLBundleDownloadURL(githubAuth, githubUrl, mode, logger) {
|
|||||||
const uniqueDownloadSources = potentialDownloadSources.filter((url, index, self) => index === self.indexOf(url));
|
const uniqueDownloadSources = potentialDownloadSources.filter((url, index, self) => index === self.indexOf(url));
|
||||||
for (const downloadSource of uniqueDownloadSources) {
|
for (const downloadSource of uniqueDownloadSources) {
|
||||||
const [apiURL, repository] = downloadSource;
|
const [apiURL, repository] = downloadSource;
|
||||||
// If we've reached the final case, short-circuit the API check since we know the bundle exists and is public.
|
// If we've reached the final case, short-circuit the API check since we know the bundles exist and are public.
|
||||||
if (apiURL === util.GITHUB_DOTCOM_URL &&
|
if (apiURL === util.GITHUB_DOTCOM_URL &&
|
||||||
repository === CODEQL_DEFAULT_ACTION_REPOSITORY) {
|
repository === CODEQL_DEFAULT_ACTION_REPOSITORY) {
|
||||||
break;
|
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${CODEQL_BUNDLE_VERSION}/${bundleNames[0]}`;
|
||||||
}
|
}
|
||||||
const [repositoryOwner, repositoryName] = repository.split("/");
|
const [repositoryOwner, repositoryName] = repository.split("/");
|
||||||
try {
|
try {
|
||||||
@@ -81,8 +81,12 @@ async function getCodeQLBundleDownloadURL(githubAuth, githubUrl, mode, logger) {
|
|||||||
repo: repositoryName,
|
repo: repositoryName,
|
||||||
tag: CODEQL_BUNDLE_VERSION,
|
tag: CODEQL_BUNDLE_VERSION,
|
||||||
});
|
});
|
||||||
for (const asset of release.data.assets) {
|
// See if any of the bundles appears in the assets list
|
||||||
if (asset.name === CODEQL_BUNDLE_NAME) {
|
const assetMap = new Map(release.data.assets.map((x) => [x.name, x]));
|
||||||
|
for (const bundleName of bundleNames) {
|
||||||
|
logger.debug(`Looking for ${bundleName}`);
|
||||||
|
const asset = assetMap.get(bundleName);
|
||||||
|
if (asset) {
|
||||||
logger.info(`Found CodeQL bundle in ${downloadSource[1]} on ${downloadSource[0]} with URL ${asset.url}.`);
|
logger.info(`Found CodeQL bundle in ${downloadSource[1]} on ${downloadSource[0]} with URL ${asset.url}.`);
|
||||||
return asset.url;
|
return asset.url;
|
||||||
}
|
}
|
||||||
@@ -94,6 +98,7 @@ async function getCodeQLBundleDownloadURL(githubAuth, githubUrl, mode, logger) {
|
|||||||
}
|
}
|
||||||
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${CODEQL_BUNDLE_VERSION}/${CODEQL_BUNDLE_NAME}`;
|
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${CODEQL_BUNDLE_VERSION}/${CODEQL_BUNDLE_NAME}`;
|
||||||
}
|
}
|
||||||
|
exports.getCodeQLBundleDownloadURL = getCodeQLBundleDownloadURL;
|
||||||
// We have to download CodeQL manually because the toolcache doesn't support Accept headers.
|
// We have to download CodeQL manually because the toolcache doesn't support Accept headers.
|
||||||
// This can be removed once https://github.com/actions/toolkit/pull/530 is merged and released.
|
// This can be removed once https://github.com/actions/toolkit/pull/530 is merged and released.
|
||||||
async function toolcacheDownloadTool(url, headers, tempDir, logger) {
|
async function toolcacheDownloadTool(url, headers, tempDir, logger) {
|
||||||
@@ -109,22 +114,75 @@ async function toolcacheDownloadTool(url, headers, tempDir, logger) {
|
|||||||
await pipeline(response.message, fs.createWriteStream(dest));
|
await pipeline(response.message, fs.createWriteStream(dest));
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
async function setupCodeQL(codeqlURL, githubAuth, githubUrl, tempDir, toolsDir, mode, logger) {
|
async function setupCodeQL(codeqlURL, languages, githubAuth, githubUrl, tempDir, toolsDir, mode, logger) {
|
||||||
// Setting these two env vars makes the toolcache code safe to use outside,
|
// Setting these two env vars makes the toolcache code safe to use outside,
|
||||||
// of actions but this is obviously not a great thing we're doing and it would
|
// of actions but this is obviously not a great thing we're doing and it would
|
||||||
// be better to write our own implementation to use outside of actions.
|
// be better to write our own implementation to use outside of actions.
|
||||||
process.env["RUNNER_TEMP"] = tempDir;
|
process.env["RUNNER_TEMP"] = tempDir;
|
||||||
process.env["RUNNER_TOOL_CACHE"] = toolsDir;
|
process.env["RUNNER_TOOL_CACHE"] = toolsDir;
|
||||||
|
// The URL identifies the release version. E.g., codeql-20200901 .
|
||||||
|
// The plVersion identifies the platform-language combination of the package
|
||||||
|
// within the release. E.g., `linux64-cpp` in `codeql-linux64-cpp.tar.gz`.
|
||||||
|
// We expect the codeqlUrl (when given) to always point to the main bundle
|
||||||
|
// `codeql-bundle.tar.gz`
|
||||||
|
//
|
||||||
|
// The logic is as follows:
|
||||||
|
// - Always use the Toolcache if available.
|
||||||
|
// - If we would like a platform-language package, but have the
|
||||||
|
// full bundle in the cache, use that.
|
||||||
|
// - If codeqlURL is specified, use that.
|
||||||
|
// - If a single language is being analyzed, try to download the platform-language package.
|
||||||
|
// - If it is not available in the release assets, fallback to the full bundle
|
||||||
|
// - If multiple languages are being anlyzed, use the full bundle
|
||||||
|
let plVersion = undefined;
|
||||||
|
let platform;
|
||||||
|
if (process.platform === "win32") {
|
||||||
|
platform = "win64";
|
||||||
|
}
|
||||||
|
else if (process.platform === "linux") {
|
||||||
|
platform = "linux64";
|
||||||
|
}
|
||||||
|
else if (process.platform === "darwin") {
|
||||||
|
platform = "osx64";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new Error(`Unsupported platform: ${process.platform}`);
|
||||||
|
}
|
||||||
|
if (languages.length === 1) {
|
||||||
|
plVersion = `${platform}-${languages[0]}`;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const codeqlURLVersion = getCodeQLURLVersion(codeqlURL || `/${CODEQL_BUNDLE_VERSION}/`, logger);
|
const codeqlURLVersion = getCodeQLURLVersion(codeqlURL || `/${CODEQL_BUNDLE_VERSION}/`, logger);
|
||||||
let codeqlFolder = toolcache.find("CodeQL", codeqlURLVersion);
|
let codeqlFolder;
|
||||||
if (codeqlFolder) {
|
logger.debug(`PL Version ${plVersion}`);
|
||||||
logger.debug(`CodeQL found in cache ${codeqlFolder}`);
|
if (plVersion) {
|
||||||
}
|
codeqlFolder = toolcache.find("CodeQL", `${codeqlURLVersion}-${plVersion}`);
|
||||||
else {
|
if (codeqlFolder) {
|
||||||
if (!codeqlURL) {
|
logger.debug(`CodeQL found in cache ${codeqlFolder}`);
|
||||||
codeqlURL = await getCodeQLBundleDownloadURL(githubAuth, githubUrl, mode, logger);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!codeqlFolder) {
|
||||||
|
codeqlFolder = toolcache.find("CodeQL", codeqlURLVersion);
|
||||||
|
if (codeqlFolder) {
|
||||||
|
logger.debug(`CodeQL found in cache ${codeqlFolder}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!codeqlFolder) {
|
||||||
|
const codeqlToolcacheVersion = plVersion
|
||||||
|
? `${codeqlURLVersion}-${plVersion}`
|
||||||
|
: codeqlURLVersion;
|
||||||
|
logger.debug(`CodeQL not found in cache`);
|
||||||
|
if (!codeqlURL) {
|
||||||
|
// Provide a few options, from smaller to bigger
|
||||||
|
const bundles = [];
|
||||||
|
if (plVersion) {
|
||||||
|
bundles.push(CODEQL_BUNDLE_NAME.replace("-bundle", `-bundle-${plVersion}`));
|
||||||
|
}
|
||||||
|
bundles.push(CODEQL_BUNDLE_NAME.replace("-bundle", `-bundle-${platform}`));
|
||||||
|
bundles.push(CODEQL_BUNDLE_NAME);
|
||||||
|
codeqlURL = await getCodeQLBundleDownloadURL(bundles, githubAuth, githubUrl, mode, logger);
|
||||||
|
}
|
||||||
|
logger.debug(`Using CodeQL URL: ${codeqlURL}`);
|
||||||
const headers = { accept: "application/octet-stream" };
|
const headers = { accept: "application/octet-stream" };
|
||||||
// We only want to provide an authorization header if we are downloading
|
// We only want to provide an authorization header if we are downloading
|
||||||
// from the same GitHub instance the Action is running on.
|
// from the same GitHub instance the Action is running on.
|
||||||
@@ -140,7 +198,8 @@ async function setupCodeQL(codeqlURL, githubAuth, githubUrl, tempDir, toolsDir,
|
|||||||
const codeqlPath = await toolcacheDownloadTool(codeqlURL, headers, tempDir, logger);
|
const codeqlPath = await toolcacheDownloadTool(codeqlURL, headers, tempDir, logger);
|
||||||
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);
|
||||||
codeqlFolder = await toolcache.cacheDir(codeqlExtracted, "CodeQL", codeqlURLVersion);
|
logger.debug(`Caching ${codeqlToolcacheVersion}`);
|
||||||
|
codeqlFolder = await toolcache.cacheDir(codeqlExtracted, "CodeQL", codeqlToolcacheVersion);
|
||||||
}
|
}
|
||||||
let codeqlCmd = path.join(codeqlFolder, "codeql", "codeql");
|
let codeqlCmd = path.join(codeqlFolder, "codeql", "codeql");
|
||||||
if (process.platform === "win32") {
|
if (process.platform === "win32") {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
129
lib/codeql.test.js
generated
129
lib/codeql.test.js
generated
@@ -10,30 +10,146 @@ 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 });
|
||||||
|
const github = __importStar(require("@actions/github"));
|
||||||
const toolcache = __importStar(require("@actions/tool-cache"));
|
const toolcache = __importStar(require("@actions/tool-cache"));
|
||||||
const ava_1 = __importDefault(require("ava"));
|
const ava_1 = __importDefault(require("ava"));
|
||||||
const nock_1 = __importDefault(require("nock"));
|
const nock_1 = __importDefault(require("nock"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
|
const sinon_1 = __importDefault(require("sinon"));
|
||||||
|
const api = __importStar(require("./api-client"));
|
||||||
const codeql = __importStar(require("./codeql"));
|
const codeql = __importStar(require("./codeql"));
|
||||||
|
const defaults = __importStar(require("./defaults.json")); // Referenced from codeql-action-sync-tool!
|
||||||
|
const languages_1 = require("./languages");
|
||||||
const logging_1 = require("./logging");
|
const logging_1 = require("./logging");
|
||||||
const testing_utils_1 = require("./testing-utils");
|
const testing_utils_1 = require("./testing-utils");
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
testing_utils_1.setupTests(ava_1.default);
|
testing_utils_1.setupTests(ava_1.default);
|
||||||
ava_1.default("download codeql bundle cache", async (t) => {
|
ava_1.default("download and populate codeql bundle cache", async (t) => {
|
||||||
await util.withTmpDir(async (tmpDir) => {
|
await util.withTmpDir(async (tmpDir) => {
|
||||||
const versions = ["20200601", "20200610"];
|
const versions = ["20200601", "20200610"];
|
||||||
|
const languages = [
|
||||||
|
[languages_1.Language.cpp],
|
||||||
|
[languages_1.Language.cpp, languages_1.Language.python],
|
||||||
|
];
|
||||||
|
const platform = process.platform === "win32"
|
||||||
|
? "win64"
|
||||||
|
: process.platform === "linux"
|
||||||
|
? "linux64"
|
||||||
|
: process.platform === "darwin"
|
||||||
|
? "osx64"
|
||||||
|
: undefined;
|
||||||
for (let i = 0; i < versions.length; i++) {
|
for (let i = 0; i < versions.length; i++) {
|
||||||
const version = versions[i];
|
for (let j = 0; j < languages.length; j++) {
|
||||||
nock_1.default("https://example.com")
|
const version = versions[i];
|
||||||
.get(`/download/codeql-bundle-${version}/codeql-bundle.tar.gz`)
|
const plVersion = languages[j].length === 1
|
||||||
|
? `${platform}-${languages[j][0]}`
|
||||||
|
: undefined;
|
||||||
|
nock_1.default("https://example.com")
|
||||||
|
.get(`/download/codeql-bundle-${version}/codeql-bundle.tar.gz`)
|
||||||
|
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
|
||||||
|
await codeql.setupCodeQL(`https://example.com/download/codeql-bundle-${version}/codeql-bundle.tar.gz`, languages[j], "token", "https://github.example.com", tmpDir, tmpDir, "runner", logging_1.getRunnerLogger(true));
|
||||||
|
const toolcacheVersion = plVersion
|
||||||
|
? `0.0.0-${version}-${plVersion}`
|
||||||
|
: `0.0.0-${version}`;
|
||||||
|
t.assert(toolcache.find("CodeQL", toolcacheVersion), `Looking for ${toolcacheVersion}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
||||||
|
// We should now have 4 cached versions: e.g.,
|
||||||
|
// 20200601, 20200601-linux64-cpp, 20200610, 20200610-linux64-cpp
|
||||||
|
t.is(cachedVersions.length, 4);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
ava_1.default("download small codeql bundle if analyzing only one language", async (t) => {
|
||||||
|
// Note: We do not specify a codeqlURL in this test, thus testing that
|
||||||
|
// the logic for constructing the URL takes into account the
|
||||||
|
// language being analyzed
|
||||||
|
await util.withTmpDir(async (tmpDir) => {
|
||||||
|
const languages = [
|
||||||
|
[languages_1.Language.cpp],
|
||||||
|
[languages_1.Language.cpp, languages_1.Language.python],
|
||||||
|
];
|
||||||
|
const platform = process.platform === "win32"
|
||||||
|
? "win64"
|
||||||
|
: process.platform === "linux"
|
||||||
|
? "linux64"
|
||||||
|
: process.platform === "darwin"
|
||||||
|
? "osx64"
|
||||||
|
: undefined;
|
||||||
|
for (let i = 0; i < languages.length; i++) {
|
||||||
|
const plVersion = languages[i].length === 1
|
||||||
|
? `${platform}-${languages[i][0]}`
|
||||||
|
: undefined;
|
||||||
|
const pkg = plVersion
|
||||||
|
? `codeql-bundle-${plVersion}.tar.gz`
|
||||||
|
: "codeql-bundle.tar.gz";
|
||||||
|
// Mock the API client
|
||||||
|
const client = new github.GitHub("123");
|
||||||
|
const response = {
|
||||||
|
data: {
|
||||||
|
assets: [
|
||||||
|
{
|
||||||
|
name: `codeql-bundle-${platform}-cpp.tar.gz`,
|
||||||
|
url: `https://github.example.com/url/codeql-bundle-${platform}-cpp.tar.gz`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "codeql-bundle.tar.gz",
|
||||||
|
url: "https://github.example.com/url/codeql-bundle.tar.gz",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
sinon_1.default.stub(client.repos, "getReleaseByTag").resolves(response);
|
||||||
|
sinon_1.default.stub(api, "getApiClient").value(() => client);
|
||||||
|
nock_1.default("https://github.example.com")
|
||||||
|
.get(`/url/${pkg}`)
|
||||||
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
|
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
|
||||||
await codeql.setupCodeQL(`https://example.com/download/codeql-bundle-${version}/codeql-bundle.tar.gz`, "token", "https://github.example.com", tmpDir, tmpDir, "runner", logging_1.getRunnerLogger(true));
|
await codeql.setupCodeQL(undefined, languages[i], "token", "https://github.example.com", tmpDir, tmpDir, "runner", logging_1.getRunnerLogger(true));
|
||||||
t.assert(toolcache.find("CodeQL", `0.0.0-${version}`));
|
const parsedVersion = codeql.getCodeQLURLVersion(`/${defaults.bundleVersion}/`, logging_1.getRunnerLogger(true));
|
||||||
|
const toolcacheVersion = plVersion
|
||||||
|
? `${parsedVersion}-${plVersion}`
|
||||||
|
: parsedVersion;
|
||||||
|
t.assert(toolcache.find("CodeQL", toolcacheVersion), `Looking for ${toolcacheVersion} - ${plVersion}`);
|
||||||
}
|
}
|
||||||
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
||||||
t.is(cachedVersions.length, 2);
|
t.is(cachedVersions.length, 2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
ava_1.default("use full codeql bundle cache if smaller bundle is not available", async (t) => {
|
||||||
|
// If we look for a platform-language version but find the full bundle in the cache,
|
||||||
|
// we use the full bundle
|
||||||
|
await util.withTmpDir(async (tmpDir) => {
|
||||||
|
const version = "20200601";
|
||||||
|
nock_1.default("https://example.com")
|
||||||
|
.get(`/download/codeql-bundle-${version}/codeql-bundle.tar.gz`)
|
||||||
|
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
|
||||||
|
await codeql.setupCodeQL(`https://example.com/download/codeql-bundle-${version}/codeql-bundle.tar.gz`, [], "token", "https://github.example.com", tmpDir, tmpDir, "runner", logging_1.getRunnerLogger(true));
|
||||||
|
t.assert(toolcache.find("CodeQL", `0.0.0-${version}`));
|
||||||
|
t.is(toolcache.findAllVersions("CodeQL").length, 1);
|
||||||
|
// Now try to request the cpp version, and see that we do not change the cache
|
||||||
|
await codeql.setupCodeQL(`https://example.com/download/codeql-bundle-${version}/codeql-bundle.tar.gz`, [languages_1.Language.cpp], "token", "https://github.example.com", tmpDir, tmpDir, "runner", logging_1.getRunnerLogger(true));
|
||||||
|
t.assert(toolcache.find("CodeQL", `0.0.0-${version}`));
|
||||||
|
t.is(toolcache.findAllVersions("CodeQL").length, 1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
ava_1.default("use larger bundles if smaller ones are not released", async (t) => {
|
||||||
|
// Mock the API client
|
||||||
|
const client = new github.GitHub("123");
|
||||||
|
const response = {
|
||||||
|
data: {
|
||||||
|
assets: [{ name: "full-bundle", url: "url/file.gz" }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const getReleaseByTagMock = sinon_1.default
|
||||||
|
.stub(client.repos, "getReleaseByTag")
|
||||||
|
.resolves(response);
|
||||||
|
sinon_1.default.stub(api, "getApiClient").value(() => client);
|
||||||
|
// Setting this env is required by a dependency of getCodeQLBundleDownloadURL
|
||||||
|
process.env["RUNNER_TEMP"] = "abc";
|
||||||
|
const codeqlURL = await codeql.getCodeQLBundleDownloadURL(["small-bundle", "full-bundle"], "", "", "actions", logging_1.getRunnerLogger(true));
|
||||||
|
t.deepEqual(codeqlURL, "url/file.gz");
|
||||||
|
t.assert(getReleaseByTagMock.called);
|
||||||
|
});
|
||||||
ava_1.default("parse codeql bundle url version", (t) => {
|
ava_1.default("parse codeql bundle url version", (t) => {
|
||||||
const tests = {
|
const tests = {
|
||||||
"20200601": "0.0.0-20200601",
|
"20200601": "0.0.0-20200601",
|
||||||
@@ -42,6 +158,7 @@ ava_1.default("parse codeql bundle url version", (t) => {
|
|||||||
"1.2.3": "1.2.3",
|
"1.2.3": "1.2.3",
|
||||||
"1.2.3-alpha": "1.2.3-alpha",
|
"1.2.3-alpha": "1.2.3-alpha",
|
||||||
"1.2.3-beta.1": "1.2.3-beta.1",
|
"1.2.3-beta.1": "1.2.3-beta.1",
|
||||||
|
"20200601-linux64-python": "0.0.0-20200601-linux64-python",
|
||||||
};
|
};
|
||||||
for (const [version, expectedVersion] of Object.entries(tests)) {
|
for (const [version, expectedVersion] of Object.entries(tests)) {
|
||||||
const url = `https://github.com/.../codeql-bundle-${version}/...`;
|
const url = `https://github.com/.../codeql-bundle-${version}/...`;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
91
lib/config-utils.js
generated
91
lib/config-utils.js
generated
@@ -12,7 +12,6 @@ const yaml = __importStar(require("js-yaml"));
|
|||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
const api = __importStar(require("./api-client"));
|
const api = __importStar(require("./api-client"));
|
||||||
const externalQueries = __importStar(require("./external-queries"));
|
const externalQueries = __importStar(require("./external-queries"));
|
||||||
const languages_1 = require("./languages");
|
|
||||||
// Property names from the user-supplied config file.
|
// Property names from the user-supplied config file.
|
||||||
const NAME_PROPERTY = "name";
|
const NAME_PROPERTY = "name";
|
||||||
const DISABLE_DEFAULT_QUERIES_PROPERTY = "disable-default-queries";
|
const DISABLE_DEFAULT_QUERIES_PROPERTY = "disable-default-queries";
|
||||||
@@ -289,84 +288,6 @@ function getConfigFilePropertyError(configFile, property, error) {
|
|||||||
return `The configuration file "${configFile}" is invalid: property "${property}" ${error}`;
|
return `The configuration file "${configFile}" is invalid: property "${property}" ${error}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getNoLanguagesError() {
|
|
||||||
return ("Did not detect any languages to analyze. " +
|
|
||||||
"Please update input in workflow or check that GitHub detects the correct languages in your repository.");
|
|
||||||
}
|
|
||||||
exports.getNoLanguagesError = getNoLanguagesError;
|
|
||||||
function getUnknownLanguagesError(languages) {
|
|
||||||
return `Did not recognise the following languages: ${languages.join(", ")}`;
|
|
||||||
}
|
|
||||||
exports.getUnknownLanguagesError = getUnknownLanguagesError;
|
|
||||||
/**
|
|
||||||
* Gets the set of languages in the current repository
|
|
||||||
*/
|
|
||||||
async function getLanguagesInRepo(repository, githubAuth, githubUrl, logger) {
|
|
||||||
logger.debug(`GitHub repo ${repository.owner} ${repository.repo}`);
|
|
||||||
const response = await api
|
|
||||||
.getApiClient(githubAuth, githubUrl, true)
|
|
||||||
.repos.listLanguages({
|
|
||||||
owner: repository.owner,
|
|
||||||
repo: repository.repo,
|
|
||||||
});
|
|
||||||
logger.debug(`Languages API response: ${JSON.stringify(response)}`);
|
|
||||||
// The GitHub API is going to return languages in order of popularity,
|
|
||||||
// When we pick a language to autobuild we want to pick the most popular traced language
|
|
||||||
// Since sets in javascript maintain insertion order, using a set here and then splatting it
|
|
||||||
// into an array gives us an array of languages ordered by popularity
|
|
||||||
const languages = new Set();
|
|
||||||
for (const lang of Object.keys(response.data)) {
|
|
||||||
const parsedLang = languages_1.parseLanguage(lang);
|
|
||||||
if (parsedLang !== undefined) {
|
|
||||||
languages.add(parsedLang);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [...languages];
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Get the languages to analyse.
|
|
||||||
*
|
|
||||||
* The result is obtained from the action input parameter 'languages' if that
|
|
||||||
* has been set, otherwise it is deduced as all languages in the repo that
|
|
||||||
* can be analysed.
|
|
||||||
*
|
|
||||||
* If no languages could be detected from either the workflow or the repository
|
|
||||||
* then throw an error.
|
|
||||||
*/
|
|
||||||
async function getLanguages(languagesInput, repository, githubAuth, githubUrl, logger) {
|
|
||||||
// Obtain from action input 'languages' if set
|
|
||||||
let languages = (languagesInput || "")
|
|
||||||
.split(",")
|
|
||||||
.map((x) => x.trim())
|
|
||||||
.filter((x) => x.length > 0);
|
|
||||||
logger.info(`Languages from configuration: ${JSON.stringify(languages)}`);
|
|
||||||
if (languages.length === 0) {
|
|
||||||
// Obtain languages as all languages in the repo that can be analysed
|
|
||||||
languages = await getLanguagesInRepo(repository, githubAuth, githubUrl, logger);
|
|
||||||
logger.info(`Automatically detected languages: ${JSON.stringify(languages)}`);
|
|
||||||
}
|
|
||||||
// If the languages parameter was not given and no languages were
|
|
||||||
// detected then fail here as this is a workflow configuration error.
|
|
||||||
if (languages.length === 0) {
|
|
||||||
throw new Error(getNoLanguagesError());
|
|
||||||
}
|
|
||||||
// Make sure they are supported
|
|
||||||
const parsedLanguages = [];
|
|
||||||
const unknownLanguages = [];
|
|
||||||
for (const language of languages) {
|
|
||||||
const parsedLanguage = languages_1.parseLanguage(language);
|
|
||||||
if (parsedLanguage === undefined) {
|
|
||||||
unknownLanguages.push(language);
|
|
||||||
}
|
|
||||||
else if (parsedLanguages.indexOf(parsedLanguage) === -1) {
|
|
||||||
parsedLanguages.push(parsedLanguage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (unknownLanguages.length > 0) {
|
|
||||||
throw new Error(getUnknownLanguagesError(unknownLanguages));
|
|
||||||
}
|
|
||||||
return parsedLanguages;
|
|
||||||
}
|
|
||||||
async function addQueriesFromWorkflow(codeQL, queriesInput, languages, resultMap, tempDir, checkoutPath, githubUrl, logger) {
|
async function addQueriesFromWorkflow(codeQL, queriesInput, languages, resultMap, tempDir, checkoutPath, githubUrl, logger) {
|
||||||
queriesInput = queriesInput.trim();
|
queriesInput = queriesInput.trim();
|
||||||
// "+" means "don't override config file" - see shouldAddConfigFileQueries
|
// "+" means "don't override config file" - see shouldAddConfigFileQueries
|
||||||
@@ -388,8 +309,7 @@ function shouldAddConfigFileQueries(queriesInput) {
|
|||||||
/**
|
/**
|
||||||
* Get the default config for when the user has not supplied one.
|
* Get the default config for when the user has not supplied one.
|
||||||
*/
|
*/
|
||||||
async function getDefaultConfig(languagesInput, queriesInput, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
|
async function getDefaultConfig(languages, queriesInput, tempDir, toolCacheDir, codeQL, checkoutPath, githubUrl, logger) {
|
||||||
const languages = await getLanguages(languagesInput, repository, githubAuth, githubUrl, logger);
|
|
||||||
const queries = {};
|
const queries = {};
|
||||||
await addDefaultQueries(codeQL, languages, queries);
|
await addDefaultQueries(codeQL, languages, queries);
|
||||||
if (queriesInput) {
|
if (queriesInput) {
|
||||||
@@ -410,7 +330,7 @@ exports.getDefaultConfig = getDefaultConfig;
|
|||||||
/**
|
/**
|
||||||
* Load the config from the given file.
|
* Load the config from the given file.
|
||||||
*/
|
*/
|
||||||
async function loadConfig(languagesInput, queriesInput, configFile, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
|
async function loadConfig(languages, queriesInput, configFile, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
|
||||||
let parsedYAML;
|
let parsedYAML;
|
||||||
if (isLocal(configFile)) {
|
if (isLocal(configFile)) {
|
||||||
// Treat the config file as relative to the workspace
|
// Treat the config file as relative to the workspace
|
||||||
@@ -430,7 +350,6 @@ async function loadConfig(languagesInput, queriesInput, configFile, repository,
|
|||||||
throw new Error(getNameInvalid(configFile));
|
throw new Error(getNameInvalid(configFile));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const languages = await getLanguages(languagesInput, repository, githubAuth, githubUrl, logger);
|
|
||||||
const queries = {};
|
const queries = {};
|
||||||
const pathsIgnore = [];
|
const pathsIgnore = [];
|
||||||
const paths = [];
|
const paths = [];
|
||||||
@@ -513,15 +432,15 @@ async function loadConfig(languagesInput, queriesInput, configFile, repository,
|
|||||||
* This will parse the config from the user input if present, or generate
|
* This will parse the config from the user input if present, or generate
|
||||||
* a default config. The parsed config is then stored to a known location.
|
* a default config. The parsed config is then stored to a known location.
|
||||||
*/
|
*/
|
||||||
async function initConfig(languagesInput, queriesInput, configFile, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
|
async function initConfig(languages, queriesInput, configFile, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
|
||||||
let config;
|
let config;
|
||||||
// If no config file was provided create an empty one
|
// If no config file was provided create an empty one
|
||||||
if (!configFile) {
|
if (!configFile) {
|
||||||
logger.debug("No configuration file was provided");
|
logger.debug("No configuration file was provided");
|
||||||
config = await getDefaultConfig(languagesInput, queriesInput, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger);
|
config = await getDefaultConfig(languages, queriesInput, tempDir, toolCacheDir, codeQL, checkoutPath, githubUrl, logger);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
config = await loadConfig(languagesInput, queriesInput, configFile, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger);
|
config = await loadConfig(languages, queriesInput, configFile, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger);
|
||||||
}
|
}
|
||||||
// Save the config so we can easily access it again in the future
|
// Save the config so we can easily access it again in the future
|
||||||
await saveConfig(config, logger);
|
await saveConfig(config, logger);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
96
lib/config-utils.test.js
generated
96
lib/config-utils.test.js
generated
@@ -56,7 +56,7 @@ function mockListLanguages(languages) {
|
|||||||
ava_1.default("load empty config", async (t) => {
|
ava_1.default("load empty config", async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
const logger = logging_1.getRunnerLogger(true);
|
const logger = logging_1.getRunnerLogger(true);
|
||||||
const languages = "javascript,python";
|
const languages = [languages_1.Language.javascript, languages_1.Language.python];
|
||||||
const codeQL = codeql_1.setCodeQL({
|
const codeQL = codeql_1.setCodeQL({
|
||||||
async resolveQueries() {
|
async resolveQueries() {
|
||||||
return {
|
return {
|
||||||
@@ -66,8 +66,8 @@ ava_1.default("load empty config", async (t) => {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const config = await configUtils.initConfig(languages, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logger);
|
const config = await configUtils.initConfig(languages, undefined, undefined, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logger);
|
||||||
t.deepEqual(config, await configUtils.getDefaultConfig(languages, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logger));
|
t.deepEqual(config, await configUtils.getDefaultConfig(languages, undefined, tmpDir, tmpDir, codeQL, tmpDir, "https://github.example.com", logger));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
ava_1.default("loading config saves config", async (t) => {
|
ava_1.default("loading config saves config", async (t) => {
|
||||||
@@ -86,7 +86,7 @@ ava_1.default("loading config saves config", async (t) => {
|
|||||||
t.false(fs.existsSync(configUtils.getPathToParsedConfigFile(tmpDir)));
|
t.false(fs.existsSync(configUtils.getPathToParsedConfigFile(tmpDir)));
|
||||||
// Sanity check that getConfig returns undefined before we have called initConfig
|
// Sanity check that getConfig returns undefined before we have called initConfig
|
||||||
t.deepEqual(await configUtils.getConfig(tmpDir, logger), undefined);
|
t.deepEqual(await configUtils.getConfig(tmpDir, logger), undefined);
|
||||||
const config1 = await configUtils.initConfig("javascript,python", undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logger);
|
const config1 = await configUtils.initConfig([languages_1.Language.javascript, languages_1.Language.python], undefined, undefined, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logger);
|
||||||
// The saved config file should now exist
|
// The saved config file should now exist
|
||||||
t.true(fs.existsSync(configUtils.getPathToParsedConfigFile(tmpDir)));
|
t.true(fs.existsSync(configUtils.getPathToParsedConfigFile(tmpDir)));
|
||||||
// And that same newly-initialised config should now be returned by getConfig
|
// And that same newly-initialised config should now be returned by getConfig
|
||||||
@@ -97,7 +97,7 @@ ava_1.default("loading config saves config", async (t) => {
|
|||||||
ava_1.default("load input outside of workspace", async (t) => {
|
ava_1.default("load input outside of workspace", async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
try {
|
try {
|
||||||
await configUtils.initConfig(undefined, undefined, "../input", { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
await configUtils.initConfig([], undefined, "../input", tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
throw new Error("initConfig did not throw error");
|
throw new Error("initConfig did not throw error");
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
@@ -110,7 +110,7 @@ ava_1.default("load non-local input with invalid repo syntax", async (t) => {
|
|||||||
// no filename given, just a repo
|
// no filename given, just a repo
|
||||||
const configFile = "octo-org/codeql-config@main";
|
const configFile = "octo-org/codeql-config@main";
|
||||||
try {
|
try {
|
||||||
await configUtils.initConfig(undefined, undefined, configFile, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
await configUtils.initConfig([], undefined, configFile, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
throw new Error("initConfig did not throw error");
|
throw new Error("initConfig did not throw error");
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
@@ -120,11 +120,11 @@ ava_1.default("load non-local input with invalid repo syntax", async (t) => {
|
|||||||
});
|
});
|
||||||
ava_1.default("load non-existent input", async (t) => {
|
ava_1.default("load non-existent input", async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
const languages = "javascript";
|
const languages = [languages_1.Language.javascript];
|
||||||
const configFile = "input";
|
const configFile = "input";
|
||||||
t.false(fs.existsSync(path.join(tmpDir, configFile)));
|
t.false(fs.existsSync(path.join(tmpDir, configFile)));
|
||||||
try {
|
try {
|
||||||
await configUtils.initConfig(languages, undefined, configFile, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
await configUtils.initConfig(languages, undefined, configFile, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
throw new Error("initConfig did not throw error");
|
throw new Error("initConfig did not throw error");
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
@@ -182,9 +182,9 @@ ava_1.default("load non-empty input", async (t) => {
|
|||||||
toolCacheDir: tmpDir,
|
toolCacheDir: tmpDir,
|
||||||
codeQLCmd: codeQL.getPath(),
|
codeQLCmd: codeQL.getPath(),
|
||||||
};
|
};
|
||||||
const languages = "javascript";
|
const languages = [languages_1.Language.javascript];
|
||||||
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
||||||
const actualConfig = await configUtils.initConfig(languages, undefined, configFilePath, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
const actualConfig = await configUtils.initConfig(languages, undefined, configFilePath, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
// Should exactly equal the object we constructed earlier
|
// Should exactly equal the object we constructed earlier
|
||||||
t.deepEqual(actualConfig, expectedConfig);
|
t.deepEqual(actualConfig, expectedConfig);
|
||||||
});
|
});
|
||||||
@@ -218,9 +218,9 @@ ava_1.default("Default queries are used", async (t) => {
|
|||||||
paths:
|
paths:
|
||||||
- foo`;
|
- foo`;
|
||||||
fs.mkdirSync(path.join(tmpDir, "foo"));
|
fs.mkdirSync(path.join(tmpDir, "foo"));
|
||||||
const languages = "javascript";
|
const languages = [languages_1.Language.javascript];
|
||||||
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
||||||
await configUtils.initConfig(languages, undefined, configFilePath, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
await configUtils.initConfig(languages, undefined, configFilePath, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
// Check resolve queries was called correctly
|
// Check resolve queries was called correctly
|
||||||
t.deepEqual(resolveQueriesArgs.length, 1);
|
t.deepEqual(resolveQueriesArgs.length, 1);
|
||||||
t.deepEqual(resolveQueriesArgs[0].queries, [
|
t.deepEqual(resolveQueriesArgs[0].queries, [
|
||||||
@@ -262,8 +262,8 @@ ava_1.default("Queries can be specified in config file", async (t) => {
|
|||||||
return queriesToResolvedQueryForm(queries);
|
return queriesToResolvedQueryForm(queries);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const languages = "javascript";
|
const languages = [languages_1.Language.javascript];
|
||||||
const config = await configUtils.initConfig(languages, undefined, configFilePath, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
const config = await configUtils.initConfig(languages, undefined, configFilePath, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
// Check resolveQueries was called correctly
|
// Check resolveQueries was called correctly
|
||||||
// It'll be called once for the default queries
|
// It'll be called once for the default queries
|
||||||
// and once for `./foo` from the config file.
|
// and once for `./foo` from the config file.
|
||||||
@@ -295,8 +295,8 @@ ava_1.default("Queries from config file can be overridden in workflow file", asy
|
|||||||
return queriesToResolvedQueryForm(queries);
|
return queriesToResolvedQueryForm(queries);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const languages = "javascript";
|
const languages = [languages_1.Language.javascript];
|
||||||
const config = await configUtils.initConfig(languages, queries, configFilePath, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
const config = await configUtils.initConfig(languages, queries, configFilePath, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
// Check resolveQueries was called correctly
|
// Check resolveQueries was called correctly
|
||||||
// It'll be called once for the default queries and once for `./override`,
|
// It'll be called once for the default queries and once for `./override`,
|
||||||
// but won't be called for './foo' from the config file.
|
// but won't be called for './foo' from the config file.
|
||||||
@@ -327,8 +327,8 @@ ava_1.default("Queries in workflow file can be used in tandem with the 'disable
|
|||||||
return queriesToResolvedQueryForm(queries);
|
return queriesToResolvedQueryForm(queries);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const languages = "javascript";
|
const languages = [languages_1.Language.javascript];
|
||||||
const config = await configUtils.initConfig(languages, queries, configFilePath, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
const config = await configUtils.initConfig(languages, queries, configFilePath, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
// Check resolveQueries was called correctly
|
// Check resolveQueries was called correctly
|
||||||
// It'll be called once for `./workflow-query`,
|
// It'll be called once for `./workflow-query`,
|
||||||
// but won't be called for the default one since that was disabled
|
// but won't be called for the default one since that was disabled
|
||||||
@@ -353,8 +353,8 @@ ava_1.default("Multiple queries can be specified in workflow file, no config fil
|
|||||||
return queriesToResolvedQueryForm(queries);
|
return queriesToResolvedQueryForm(queries);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const languages = "javascript";
|
const languages = [languages_1.Language.javascript];
|
||||||
const config = await configUtils.initConfig(languages, queries, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
const config = await configUtils.initConfig(languages, queries, undefined, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
// Check resolveQueries was called correctly:
|
// Check resolveQueries was called correctly:
|
||||||
// It'll be called once for the default queries,
|
// It'll be called once for the default queries,
|
||||||
// and then once for each of the two queries from the workflow
|
// and then once for each of the two queries from the workflow
|
||||||
@@ -392,8 +392,8 @@ ava_1.default("Queries in workflow file can be added to the set of queries witho
|
|||||||
return queriesToResolvedQueryForm(queries);
|
return queriesToResolvedQueryForm(queries);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const languages = "javascript";
|
const languages = [languages_1.Language.javascript];
|
||||||
const config = await configUtils.initConfig(languages, queries, configFilePath, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
const config = await configUtils.initConfig(languages, queries, configFilePath, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
// Check resolveQueries was called correctly
|
// Check resolveQueries was called correctly
|
||||||
// It'll be called once for the default queries,
|
// It'll be called once for the default queries,
|
||||||
// once for each of additional1 and additional2,
|
// once for each of additional1 and additional2,
|
||||||
@@ -417,7 +417,7 @@ ava_1.default("Queries in workflow file can be added to the set of queries witho
|
|||||||
ava_1.default("Invalid queries in workflow file handled correctly", async (t) => {
|
ava_1.default("Invalid queries in workflow file handled correctly", async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
const queries = "foo/bar@v1@v3";
|
const queries = "foo/bar@v1@v3";
|
||||||
const languages = "javascript";
|
const languages = [languages_1.Language.javascript];
|
||||||
// This function just needs to be type-correct; it doesn't need to do anything,
|
// This function just needs to be type-correct; it doesn't need to do anything,
|
||||||
// since we're deliberately passing in invalid data
|
// since we're deliberately passing in invalid data
|
||||||
const codeQL = codeql_1.setCodeQL({
|
const codeQL = codeql_1.setCodeQL({
|
||||||
@@ -432,7 +432,7 @@ ava_1.default("Invalid queries in workflow file handled correctly", async (t) =>
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
await configUtils.initConfig(languages, queries, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
await configUtils.initConfig(languages, queries, undefined, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
t.fail("initConfig did not throw error");
|
t.fail("initConfig did not throw error");
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
@@ -474,8 +474,8 @@ ava_1.default("API client used when reading remote config", async (t) => {
|
|||||||
// Create checkout directory for remote queries repository
|
// Create checkout directory for remote queries repository
|
||||||
fs.mkdirSync(path.join(tmpDir, "foo/bar/dev"), { recursive: true });
|
fs.mkdirSync(path.join(tmpDir, "foo/bar/dev"), { recursive: true });
|
||||||
const configFile = "octo-org/codeql-config/config.yaml@main";
|
const configFile = "octo-org/codeql-config/config.yaml@main";
|
||||||
const languages = "javascript";
|
const languages = [languages_1.Language.javascript];
|
||||||
await configUtils.initConfig(languages, undefined, configFile, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
await configUtils.initConfig(languages, undefined, configFile, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
t.assert(spyGetContents.called);
|
t.assert(spyGetContents.called);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -485,7 +485,7 @@ ava_1.default("Remote config handles the case where a directory is provided", as
|
|||||||
mockGetContents(dummyResponse);
|
mockGetContents(dummyResponse);
|
||||||
const repoReference = "octo-org/codeql-config/config.yaml@main";
|
const repoReference = "octo-org/codeql-config/config.yaml@main";
|
||||||
try {
|
try {
|
||||||
await configUtils.initConfig(undefined, undefined, repoReference, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
await configUtils.initConfig([], undefined, repoReference, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
throw new Error("initConfig did not throw error");
|
throw new Error("initConfig did not throw error");
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
@@ -501,7 +501,7 @@ ava_1.default("Invalid format of remote config handled correctly", async (t) =>
|
|||||||
mockGetContents(dummyResponse);
|
mockGetContents(dummyResponse);
|
||||||
const repoReference = "octo-org/codeql-config/config.yaml@main";
|
const repoReference = "octo-org/codeql-config/config.yaml@main";
|
||||||
try {
|
try {
|
||||||
await configUtils.initConfig(undefined, undefined, repoReference, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
await configUtils.initConfig([], undefined, repoReference, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
throw new Error("initConfig did not throw error");
|
throw new Error("initConfig did not throw error");
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
@@ -510,28 +510,24 @@ ava_1.default("Invalid format of remote config handled correctly", async (t) =>
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
ava_1.default("No detected languages", async (t) => {
|
ava_1.default("No detected languages", async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
mockListLanguages([]);
|
||||||
mockListLanguages([]);
|
try {
|
||||||
try {
|
await languages_1.getLanguages(undefined, { owner: "github", repo: "example " }, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
await configUtils.initConfig(undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
throw new Error("initConfig did not throw error");
|
||||||
throw new Error("initConfig did not throw error");
|
}
|
||||||
}
|
catch (err) {
|
||||||
catch (err) {
|
t.deepEqual(err, new Error(languages_1.getNoLanguagesError()));
|
||||||
t.deepEqual(err, new Error(configUtils.getNoLanguagesError()));
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
ava_1.default("Unknown languages", async (t) => {
|
ava_1.default("Unknown languages", async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
const languages = "ruby,english";
|
||||||
const languages = "ruby,english";
|
try {
|
||||||
try {
|
await languages_1.getLanguages(languages, { owner: "github", repo: "example " }, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
await configUtils.initConfig(languages, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
throw new Error("initConfig did not throw error");
|
||||||
throw new Error("initConfig did not throw error");
|
}
|
||||||
}
|
catch (err) {
|
||||||
catch (err) {
|
t.deepEqual(err, new Error(languages_1.getUnknownLanguagesError(["ruby", "english"])));
|
||||||
t.deepEqual(err, new Error(configUtils.getUnknownLanguagesError(["ruby", "english"])));
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGenerator) {
|
function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGenerator) {
|
||||||
ava_1.default(`load invalid input - ${testName}`, async (t) => {
|
ava_1.default(`load invalid input - ${testName}`, async (t) => {
|
||||||
@@ -545,12 +541,12 @@ function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGen
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const languages = "javascript";
|
const languages = [languages_1.Language.javascript];
|
||||||
const configFile = "input";
|
const configFile = "input";
|
||||||
const inputFile = path.join(tmpDir, configFile);
|
const inputFile = path.join(tmpDir, configFile);
|
||||||
fs.writeFileSync(inputFile, inputFileContents, "utf8");
|
fs.writeFileSync(inputFile, inputFileContents, "utf8");
|
||||||
try {
|
try {
|
||||||
await configUtils.initConfig(languages, undefined, configFile, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
await configUtils.initConfig(languages, undefined, configFile, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||||
throw new Error("initConfig did not throw error");
|
throw new Error("initConfig did not throw error");
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
7
lib/init-action.js
generated
7
lib/init-action.js
generated
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||||||
const core = __importStar(require("@actions/core"));
|
const core = __importStar(require("@actions/core"));
|
||||||
const actionsUtil = __importStar(require("./actions-util"));
|
const actionsUtil = __importStar(require("./actions-util"));
|
||||||
const init_1 = require("./init");
|
const init_1 = require("./init");
|
||||||
|
const languages_1 = require("./languages");
|
||||||
const logging_1 = require("./logging");
|
const logging_1 = require("./logging");
|
||||||
const repository_1 = require("./repository");
|
const repository_1 = require("./repository");
|
||||||
async function sendSuccessStatusReport(startedAt, config) {
|
async function sendSuccessStatusReport(startedAt, config) {
|
||||||
@@ -54,8 +55,10 @@ async function run() {
|
|||||||
if (!(await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("init", "starting", startedAt), true))) {
|
if (!(await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("init", "starting", startedAt), true))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
codeql = await init_1.initCodeQL(actionsUtil.getOptionalInput("tools"), actionsUtil.getRequiredInput("token"), actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"), actionsUtil.getRequiredEnvParam("RUNNER_TEMP"), actionsUtil.getRequiredEnvParam("RUNNER_TOOL_CACHE"), "actions", logger);
|
const repositoryNWO = repository_1.parseRepositoryNwo(actionsUtil.getRequiredEnvParam("GITHUB_REPOSITORY"));
|
||||||
config = await init_1.initConfig(actionsUtil.getOptionalInput("languages"), actionsUtil.getOptionalInput("queries"), actionsUtil.getOptionalInput("config-file"), repository_1.parseRepositoryNwo(actionsUtil.getRequiredEnvParam("GITHUB_REPOSITORY")), actionsUtil.getRequiredEnvParam("RUNNER_TEMP"), actionsUtil.getRequiredEnvParam("RUNNER_TOOL_CACHE"), codeql, actionsUtil.getRequiredEnvParam("GITHUB_WORKSPACE"), actionsUtil.getRequiredInput("token"), actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"), logger);
|
const languages = await languages_1.getLanguages(actionsUtil.getOptionalInput("languages"), repositoryNWO, actionsUtil.getRequiredInput("token"), actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"), logger);
|
||||||
|
codeql = await init_1.initCodeQL(actionsUtil.getOptionalInput("tools"), languages, actionsUtil.getRequiredInput("token"), actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"), actionsUtil.getRequiredEnvParam("RUNNER_TEMP"), actionsUtil.getRequiredEnvParam("RUNNER_TOOL_CACHE"), "actions", logger);
|
||||||
|
config = await init_1.initConfig(languages, actionsUtil.getOptionalInput("queries"), actionsUtil.getOptionalInput("config-file"), actionsUtil.getRequiredEnvParam("RUNNER_TEMP"), actionsUtil.getRequiredEnvParam("RUNNER_TOOL_CACHE"), codeql, actionsUtil.getRequiredEnvParam("GITHUB_WORKSPACE"), actionsUtil.getRequiredInput("token"), actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"), logger);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
core.setFailed(e.message);
|
core.setFailed(e.message);
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"init-action.js","sourceRoot":"","sources":["../src/init-action.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"init-action.js","sourceRoot":"","sources":["../src/init-action.ts"],"names":[],"mappings":"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"}
|
||||||
8
lib/init.js
generated
8
lib/init.js
generated
@@ -15,17 +15,17 @@ const codeql_1 = require("./codeql");
|
|||||||
const configUtils = __importStar(require("./config-utils"));
|
const configUtils = __importStar(require("./config-utils"));
|
||||||
const tracer_config_1 = require("./tracer-config");
|
const tracer_config_1 = require("./tracer-config");
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
async function initCodeQL(codeqlURL, githubAuth, githubUrl, tempDir, toolsDir, mode, logger) {
|
async function initCodeQL(codeqlURL, languages, githubAuth, githubUrl, tempDir, toolsDir, mode, logger) {
|
||||||
logger.startGroup("Setup CodeQL tools");
|
logger.startGroup("Setup CodeQL tools");
|
||||||
const codeql = await codeql_1.setupCodeQL(codeqlURL, githubAuth, githubUrl, tempDir, toolsDir, mode, logger);
|
const codeql = await codeql_1.setupCodeQL(codeqlURL, languages, githubAuth, githubUrl, tempDir, toolsDir, mode, logger);
|
||||||
await codeql.printVersion();
|
await codeql.printVersion();
|
||||||
logger.endGroup();
|
logger.endGroup();
|
||||||
return codeql;
|
return codeql;
|
||||||
}
|
}
|
||||||
exports.initCodeQL = initCodeQL;
|
exports.initCodeQL = initCodeQL;
|
||||||
async function initConfig(languagesInput, queriesInput, configFile, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
|
async function initConfig(languages, queriesInput, configFile, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
|
||||||
logger.startGroup("Load language configuration");
|
logger.startGroup("Load language configuration");
|
||||||
const config = await configUtils.initConfig(languagesInput, queriesInput, configFile, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger);
|
const config = await configUtils.initConfig(languages, queriesInput, configFile, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger);
|
||||||
analysisPaths.printPathFiltersWarning(config, logger);
|
analysisPaths.printPathFiltersWarning(config, logger);
|
||||||
logger.endGroup();
|
logger.endGroup();
|
||||||
return config;
|
return config;
|
||||||
|
|||||||
@@ -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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"}
|
||||||
87
lib/languages.js
generated
87
lib/languages.js
generated
@@ -1,5 +1,13 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||||
|
result["default"] = mod;
|
||||||
|
return result;
|
||||||
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
const api = __importStar(require("./api-client"));
|
||||||
// All the languages supported by CodeQL
|
// All the languages supported by CodeQL
|
||||||
var Language;
|
var Language;
|
||||||
(function (Language) {
|
(function (Language) {
|
||||||
@@ -40,4 +48,83 @@ function isScannedLanguage(language) {
|
|||||||
return !isTracedLanguage(language);
|
return !isTracedLanguage(language);
|
||||||
}
|
}
|
||||||
exports.isScannedLanguage = isScannedLanguage;
|
exports.isScannedLanguage = isScannedLanguage;
|
||||||
|
function getNoLanguagesError() {
|
||||||
|
return ("Did not detect any languages to analyze. " +
|
||||||
|
"Please update input in workflow or check that GitHub detects the correct languages in your repository.");
|
||||||
|
}
|
||||||
|
exports.getNoLanguagesError = getNoLanguagesError;
|
||||||
|
function getUnknownLanguagesError(languages) {
|
||||||
|
return `Did not recognise the following languages: ${languages.join(", ")}`;
|
||||||
|
}
|
||||||
|
exports.getUnknownLanguagesError = getUnknownLanguagesError;
|
||||||
|
/**
|
||||||
|
* Get the languages to analyse.
|
||||||
|
*
|
||||||
|
* The result is obtained from the action input parameter 'languages' if that
|
||||||
|
* has been set, otherwise it is deduced as all languages in the repo that
|
||||||
|
* can be analysed.
|
||||||
|
*
|
||||||
|
* If no languages could be detected from either the workflow or the repository
|
||||||
|
* then throw an error.
|
||||||
|
*/
|
||||||
|
async function getLanguages(languagesInput, repository, githubAuth, githubUrl, logger) {
|
||||||
|
// Obtain from action input 'languages' if set
|
||||||
|
let languages = (languagesInput || "")
|
||||||
|
.split(",")
|
||||||
|
.map((x) => x.trim())
|
||||||
|
.filter((x) => x.length > 0);
|
||||||
|
logger.info(`Languages from configuration: ${JSON.stringify(languages)}`);
|
||||||
|
if (languages.length === 0) {
|
||||||
|
// Obtain languages as all languages in the repo that can be analysed
|
||||||
|
languages = await getLanguagesInRepo(repository, githubAuth, githubUrl, logger);
|
||||||
|
logger.info(`Automatically detected languages: ${JSON.stringify(languages)}`);
|
||||||
|
}
|
||||||
|
// If the languages parameter was not given and no languages were
|
||||||
|
// detected then fail here as this is a workflow configuration error.
|
||||||
|
if (languages.length === 0) {
|
||||||
|
throw new Error(getNoLanguagesError());
|
||||||
|
}
|
||||||
|
// Make sure they are supported
|
||||||
|
const parsedLanguages = [];
|
||||||
|
const unknownLanguages = [];
|
||||||
|
for (const language of languages) {
|
||||||
|
const parsedLanguage = parseLanguage(language);
|
||||||
|
if (parsedLanguage === undefined) {
|
||||||
|
unknownLanguages.push(language);
|
||||||
|
}
|
||||||
|
else if (parsedLanguages.indexOf(parsedLanguage) === -1) {
|
||||||
|
parsedLanguages.push(parsedLanguage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (unknownLanguages.length > 0) {
|
||||||
|
throw new Error(getUnknownLanguagesError(unknownLanguages));
|
||||||
|
}
|
||||||
|
return parsedLanguages;
|
||||||
|
}
|
||||||
|
exports.getLanguages = getLanguages;
|
||||||
|
/**
|
||||||
|
* Gets the set of languages in the current repository
|
||||||
|
*/
|
||||||
|
async function getLanguagesInRepo(repository, githubAuth, githubUrl, logger) {
|
||||||
|
logger.debug(`GitHub repo ${repository.owner} ${repository.repo}`);
|
||||||
|
const response = await api
|
||||||
|
.getApiClient(githubAuth, githubUrl, true)
|
||||||
|
.repos.listLanguages({
|
||||||
|
owner: repository.owner,
|
||||||
|
repo: repository.repo,
|
||||||
|
});
|
||||||
|
logger.debug(`Languages API response: ${JSON.stringify(response)}`);
|
||||||
|
// The GitHub API is going to return languages in order of popularity,
|
||||||
|
// When we pick a language to autobuild we want to pick the most popular traced language
|
||||||
|
// Since sets in javascript maintain insertion order, using a set here and then splatting it
|
||||||
|
// into an array gives us an array of languages ordered by popularity
|
||||||
|
const languages = new Set();
|
||||||
|
for (const lang of Object.keys(response.data)) {
|
||||||
|
const parsedLang = parseLanguage(lang);
|
||||||
|
if (parsedLang !== undefined) {
|
||||||
|
languages.add(parsedLang);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [...languages];
|
||||||
|
}
|
||||||
//# sourceMappingURL=languages.js.map
|
//# sourceMappingURL=languages.js.map
|
||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"languages.js","sourceRoot":"","sources":["../src/languages.ts"],"names":[],"mappings":";;AAAA,wCAAwC;AACxC,IAAY,QAOX;AAPD,WAAY,QAAQ;IAClB,6BAAiB,CAAA;IACjB,uBAAW,CAAA;IACX,qBAAS,CAAA;IACT,yBAAa,CAAA;IACb,qCAAyB,CAAA;IACzB,6BAAiB,CAAA;AACnB,CAAC,EAPW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QAOnB;AAED,iCAAiC;AACjC,MAAM,gBAAgB,GAAiC;IACrD,CAAC,EAAE,QAAQ,CAAC,GAAG;IACf,KAAK,EAAE,QAAQ,CAAC,GAAG;IACnB,IAAI,EAAE,QAAQ,CAAC,MAAM;IACrB,UAAU,EAAE,QAAQ,CAAC,UAAU;CAChC,CAAC;AAEF,gGAAgG;AAChG,SAAgB,aAAa,CAAC,QAAgB;IAC5C,0BAA0B;IAC1B,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAElC,6BAA6B;IAC7B,IAAI,QAAQ,IAAI,QAAQ,EAAE;QACxB,OAAO,QAAoB,CAAC;KAC7B;IAED,yBAAyB;IACzB,IAAI,QAAQ,IAAI,gBAAgB,EAAE;QAChC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,CAAC;KACnC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAfD,sCAeC;AAED,SAAgB,gBAAgB,CAAC,QAAkB;IACjD,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACtD,CAAC;AAFD,4CAEC;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":"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"}
|
||||||
7
lib/runner.js
generated
7
lib/runner.js
generated
@@ -119,14 +119,17 @@ program
|
|||||||
logger.info(`Cleaning temp directory ${tempDir}`);
|
logger.info(`Cleaning temp directory ${tempDir}`);
|
||||||
fs.rmdirSync(tempDir, { recursive: true });
|
fs.rmdirSync(tempDir, { recursive: true });
|
||||||
fs.mkdirSync(tempDir, { recursive: true });
|
fs.mkdirSync(tempDir, { recursive: true });
|
||||||
|
const githubUrl = parseGithubUrl(cmd.githubUrl);
|
||||||
|
const repositoryNWO = repository_1.parseRepositoryNwo(cmd.repository);
|
||||||
|
const languages = await languages_1.getLanguages(cmd.languages, repositoryNWO, cmd.githubAuth, githubUrl, logger);
|
||||||
let codeql;
|
let codeql;
|
||||||
if (cmd.codeqlPath !== undefined) {
|
if (cmd.codeqlPath !== undefined) {
|
||||||
codeql = codeql_1.getCodeQL(cmd.codeqlPath);
|
codeql = codeql_1.getCodeQL(cmd.codeqlPath);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
codeql = await init_1.initCodeQL(undefined, cmd.githubAuth, parseGithubUrl(cmd.githubUrl), tempDir, toolsDir, "runner", logger);
|
codeql = await init_1.initCodeQL(undefined, languages, cmd.githubAuth, githubUrl, tempDir, toolsDir, "runner", logger);
|
||||||
}
|
}
|
||||||
const config = await init_1.initConfig(cmd.languages, cmd.queries, cmd.configFile, repository_1.parseRepositoryNwo(cmd.repository), tempDir, toolsDir, codeql, cmd.checkoutPath || process.cwd(), cmd.githubAuth, parseGithubUrl(cmd.githubUrl), logger);
|
const config = await init_1.initConfig(languages, cmd.queries, cmd.configFile, tempDir, toolsDir, codeql, cmd.checkoutPath || process.cwd(), cmd.githubAuth, parseGithubUrl(cmd.githubUrl), logger);
|
||||||
const tracerConfig = await init_1.runInit(codeql, config);
|
const tracerConfig = await init_1.runInit(codeql, config);
|
||||||
if (tracerConfig === undefined) {
|
if (tracerConfig === undefined) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,31 +1,137 @@
|
|||||||
|
import * as github from "@actions/github";
|
||||||
import * as toolcache from "@actions/tool-cache";
|
import * as toolcache from "@actions/tool-cache";
|
||||||
import test from "ava";
|
import test from "ava";
|
||||||
import nock from "nock";
|
import nock from "nock";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
|
import sinon from "sinon";
|
||||||
|
|
||||||
|
import * as api from "./api-client";
|
||||||
import * as codeql from "./codeql";
|
import * as codeql from "./codeql";
|
||||||
|
import * as defaults from "./defaults.json"; // Referenced from codeql-action-sync-tool!
|
||||||
|
import { Language } from "./languages";
|
||||||
import { getRunnerLogger } from "./logging";
|
import { getRunnerLogger } from "./logging";
|
||||||
import { setupTests } from "./testing-utils";
|
import { setupTests } from "./testing-utils";
|
||||||
import * as util from "./util";
|
import * as util from "./util";
|
||||||
|
|
||||||
setupTests(test);
|
setupTests(test);
|
||||||
|
|
||||||
test("download codeql bundle cache", async (t) => {
|
test("download and populate codeql bundle cache", async (t) => {
|
||||||
await util.withTmpDir(async (tmpDir) => {
|
await util.withTmpDir(async (tmpDir) => {
|
||||||
const versions = ["20200601", "20200610"];
|
const versions = ["20200601", "20200610"];
|
||||||
|
const languages: Language[][] = [
|
||||||
|
[Language.cpp],
|
||||||
|
[Language.cpp, Language.python], // Multi-language requires the full bundle
|
||||||
|
];
|
||||||
|
|
||||||
|
const platform =
|
||||||
|
process.platform === "win32"
|
||||||
|
? "win64"
|
||||||
|
: process.platform === "linux"
|
||||||
|
? "linux64"
|
||||||
|
: process.platform === "darwin"
|
||||||
|
? "osx64"
|
||||||
|
: undefined;
|
||||||
|
|
||||||
for (let i = 0; i < versions.length; i++) {
|
for (let i = 0; i < versions.length; i++) {
|
||||||
const version = versions[i];
|
for (let j = 0; j < languages.length; j++) {
|
||||||
|
const version = versions[i];
|
||||||
|
const plVersion =
|
||||||
|
languages[j].length === 1
|
||||||
|
? `${platform}-${languages[j][0]}`
|
||||||
|
: undefined;
|
||||||
|
|
||||||
nock("https://example.com")
|
nock("https://example.com")
|
||||||
.get(`/download/codeql-bundle-${version}/codeql-bundle.tar.gz`)
|
.get(`/download/codeql-bundle-${version}/codeql-bundle.tar.gz`)
|
||||||
|
.replyWithFile(
|
||||||
|
200,
|
||||||
|
path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`)
|
||||||
|
);
|
||||||
|
|
||||||
|
await codeql.setupCodeQL(
|
||||||
|
`https://example.com/download/codeql-bundle-${version}/codeql-bundle.tar.gz`,
|
||||||
|
languages[j],
|
||||||
|
"token",
|
||||||
|
"https://github.example.com",
|
||||||
|
tmpDir,
|
||||||
|
tmpDir,
|
||||||
|
"runner",
|
||||||
|
getRunnerLogger(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
const toolcacheVersion = plVersion
|
||||||
|
? `0.0.0-${version}-${plVersion}`
|
||||||
|
: `0.0.0-${version}`;
|
||||||
|
t.assert(
|
||||||
|
toolcache.find("CodeQL", toolcacheVersion),
|
||||||
|
`Looking for ${toolcacheVersion}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
||||||
|
// We should now have 4 cached versions: e.g.,
|
||||||
|
// 20200601, 20200601-linux64-cpp, 20200610, 20200610-linux64-cpp
|
||||||
|
t.is(cachedVersions.length, 4);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("download small codeql bundle if analyzing only one language", async (t) => {
|
||||||
|
// Note: We do not specify a codeqlURL in this test, thus testing that
|
||||||
|
// the logic for constructing the URL takes into account the
|
||||||
|
// language being analyzed
|
||||||
|
await util.withTmpDir(async (tmpDir) => {
|
||||||
|
const languages: Language[][] = [
|
||||||
|
[Language.cpp],
|
||||||
|
[Language.cpp, Language.python], // Multi-language requires the full bundle
|
||||||
|
];
|
||||||
|
|
||||||
|
const platform =
|
||||||
|
process.platform === "win32"
|
||||||
|
? "win64"
|
||||||
|
: process.platform === "linux"
|
||||||
|
? "linux64"
|
||||||
|
: process.platform === "darwin"
|
||||||
|
? "osx64"
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
for (let i = 0; i < languages.length; i++) {
|
||||||
|
const plVersion =
|
||||||
|
languages[i].length === 1
|
||||||
|
? `${platform}-${languages[i][0]}`
|
||||||
|
: undefined;
|
||||||
|
const pkg = plVersion
|
||||||
|
? `codeql-bundle-${plVersion}.tar.gz`
|
||||||
|
: "codeql-bundle.tar.gz";
|
||||||
|
|
||||||
|
// Mock the API client
|
||||||
|
const client = new github.GitHub("123");
|
||||||
|
const response = {
|
||||||
|
data: {
|
||||||
|
assets: [
|
||||||
|
{
|
||||||
|
name: `codeql-bundle-${platform}-cpp.tar.gz`,
|
||||||
|
url: `https://github.example.com/url/codeql-bundle-${platform}-cpp.tar.gz`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "codeql-bundle.tar.gz",
|
||||||
|
url: "https://github.example.com/url/codeql-bundle.tar.gz",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
sinon.stub(client.repos, "getReleaseByTag").resolves(response as any);
|
||||||
|
sinon.stub(api, "getApiClient").value(() => client);
|
||||||
|
|
||||||
|
nock("https://github.example.com")
|
||||||
|
.get(`/url/${pkg}`)
|
||||||
.replyWithFile(
|
.replyWithFile(
|
||||||
200,
|
200,
|
||||||
path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`)
|
path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`)
|
||||||
);
|
);
|
||||||
|
|
||||||
await codeql.setupCodeQL(
|
await codeql.setupCodeQL(
|
||||||
`https://example.com/download/codeql-bundle-${version}/codeql-bundle.tar.gz`,
|
undefined,
|
||||||
|
languages[i],
|
||||||
"token",
|
"token",
|
||||||
"https://github.example.com",
|
"https://github.example.com",
|
||||||
tmpDir,
|
tmpDir,
|
||||||
@@ -34,15 +140,96 @@ test("download codeql bundle cache", async (t) => {
|
|||||||
getRunnerLogger(true)
|
getRunnerLogger(true)
|
||||||
);
|
);
|
||||||
|
|
||||||
t.assert(toolcache.find("CodeQL", `0.0.0-${version}`));
|
const parsedVersion = codeql.getCodeQLURLVersion(
|
||||||
|
`/${defaults.bundleVersion}/`,
|
||||||
|
getRunnerLogger(true)
|
||||||
|
);
|
||||||
|
const toolcacheVersion = plVersion
|
||||||
|
? `${parsedVersion}-${plVersion}`
|
||||||
|
: parsedVersion;
|
||||||
|
t.assert(
|
||||||
|
toolcache.find("CodeQL", toolcacheVersion),
|
||||||
|
`Looking for ${toolcacheVersion} - ${plVersion}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
||||||
|
|
||||||
t.is(cachedVersions.length, 2);
|
t.is(cachedVersions.length, 2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("use full codeql bundle cache if smaller bundle is not available", async (t) => {
|
||||||
|
// If we look for a platform-language version but find the full bundle in the cache,
|
||||||
|
// we use the full bundle
|
||||||
|
await util.withTmpDir(async (tmpDir) => {
|
||||||
|
const version = "20200601";
|
||||||
|
|
||||||
|
nock("https://example.com")
|
||||||
|
.get(`/download/codeql-bundle-${version}/codeql-bundle.tar.gz`)
|
||||||
|
.replyWithFile(
|
||||||
|
200,
|
||||||
|
path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`)
|
||||||
|
);
|
||||||
|
|
||||||
|
await codeql.setupCodeQL(
|
||||||
|
`https://example.com/download/codeql-bundle-${version}/codeql-bundle.tar.gz`,
|
||||||
|
[],
|
||||||
|
"token",
|
||||||
|
"https://github.example.com",
|
||||||
|
tmpDir,
|
||||||
|
tmpDir,
|
||||||
|
"runner",
|
||||||
|
getRunnerLogger(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
t.assert(toolcache.find("CodeQL", `0.0.0-${version}`));
|
||||||
|
t.is(toolcache.findAllVersions("CodeQL").length, 1);
|
||||||
|
|
||||||
|
// Now try to request the cpp version, and see that we do not change the cache
|
||||||
|
await codeql.setupCodeQL(
|
||||||
|
`https://example.com/download/codeql-bundle-${version}/codeql-bundle.tar.gz`,
|
||||||
|
[Language.cpp],
|
||||||
|
"token",
|
||||||
|
"https://github.example.com",
|
||||||
|
tmpDir,
|
||||||
|
tmpDir,
|
||||||
|
"runner",
|
||||||
|
getRunnerLogger(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
t.assert(toolcache.find("CodeQL", `0.0.0-${version}`));
|
||||||
|
t.is(toolcache.findAllVersions("CodeQL").length, 1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("use larger bundles if smaller ones are not released", async (t) => {
|
||||||
|
// Mock the API client
|
||||||
|
const client = new github.GitHub("123");
|
||||||
|
const response = {
|
||||||
|
data: {
|
||||||
|
assets: [{ name: "full-bundle", url: "url/file.gz" }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const getReleaseByTagMock = sinon
|
||||||
|
.stub(client.repos, "getReleaseByTag")
|
||||||
|
.resolves(response as any);
|
||||||
|
sinon.stub(api, "getApiClient").value(() => client);
|
||||||
|
|
||||||
|
// Setting this env is required by a dependency of getCodeQLBundleDownloadURL
|
||||||
|
process.env["RUNNER_TEMP"] = "abc";
|
||||||
|
|
||||||
|
const codeqlURL = await codeql.getCodeQLBundleDownloadURL(
|
||||||
|
["small-bundle", "full-bundle"],
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"actions",
|
||||||
|
getRunnerLogger(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
t.deepEqual(codeqlURL, "url/file.gz");
|
||||||
|
t.assert(getReleaseByTagMock.called);
|
||||||
|
});
|
||||||
|
|
||||||
test("parse codeql bundle url version", (t) => {
|
test("parse codeql bundle url version", (t) => {
|
||||||
const tests = {
|
const tests = {
|
||||||
"20200601": "0.0.0-20200601",
|
"20200601": "0.0.0-20200601",
|
||||||
@@ -51,6 +238,7 @@ test("parse codeql bundle url version", (t) => {
|
|||||||
"1.2.3": "1.2.3",
|
"1.2.3": "1.2.3",
|
||||||
"1.2.3-alpha": "1.2.3-alpha",
|
"1.2.3-alpha": "1.2.3-alpha",
|
||||||
"1.2.3-beta.1": "1.2.3-beta.1",
|
"1.2.3-beta.1": "1.2.3-beta.1",
|
||||||
|
"20200601-linux64-python": "0.0.0-20200601-linux64-python",
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const [version, expectedVersion] of Object.entries(tests)) {
|
for (const [version, expectedVersion] of Object.entries(tests)) {
|
||||||
|
|||||||
@@ -141,7 +141,8 @@ function getCodeQLActionRepository(mode: util.Mode): string {
|
|||||||
return `${relativeScriptPathParts[0]}/${relativeScriptPathParts[1]}`;
|
return `${relativeScriptPathParts[0]}/${relativeScriptPathParts[1]}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getCodeQLBundleDownloadURL(
|
export async function getCodeQLBundleDownloadURL(
|
||||||
|
bundleNames: string[],
|
||||||
githubAuth: string,
|
githubAuth: string,
|
||||||
githubUrl: string,
|
githubUrl: string,
|
||||||
mode: util.Mode,
|
mode: util.Mode,
|
||||||
@@ -163,12 +164,12 @@ async function getCodeQLBundleDownloadURL(
|
|||||||
);
|
);
|
||||||
for (const downloadSource of uniqueDownloadSources) {
|
for (const downloadSource of uniqueDownloadSources) {
|
||||||
const [apiURL, repository] = downloadSource;
|
const [apiURL, repository] = downloadSource;
|
||||||
// If we've reached the final case, short-circuit the API check since we know the bundle exists and is public.
|
// If we've reached the final case, short-circuit the API check since we know the bundles exist and are public.
|
||||||
if (
|
if (
|
||||||
apiURL === util.GITHUB_DOTCOM_URL &&
|
apiURL === util.GITHUB_DOTCOM_URL &&
|
||||||
repository === CODEQL_DEFAULT_ACTION_REPOSITORY
|
repository === CODEQL_DEFAULT_ACTION_REPOSITORY
|
||||||
) {
|
) {
|
||||||
break;
|
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${CODEQL_BUNDLE_VERSION}/${bundleNames[0]}`;
|
||||||
}
|
}
|
||||||
const [repositoryOwner, repositoryName] = repository.split("/");
|
const [repositoryOwner, repositoryName] = repository.split("/");
|
||||||
try {
|
try {
|
||||||
@@ -179,8 +180,13 @@ async function getCodeQLBundleDownloadURL(
|
|||||||
repo: repositoryName,
|
repo: repositoryName,
|
||||||
tag: CODEQL_BUNDLE_VERSION,
|
tag: CODEQL_BUNDLE_VERSION,
|
||||||
});
|
});
|
||||||
for (const asset of release.data.assets) {
|
|
||||||
if (asset.name === CODEQL_BUNDLE_NAME) {
|
// See if any of the bundles appears in the assets list
|
||||||
|
const assetMap = new Map(release.data.assets.map((x) => [x.name, x]));
|
||||||
|
for (const bundleName of bundleNames) {
|
||||||
|
logger.debug(`Looking for ${bundleName}`);
|
||||||
|
const asset = assetMap.get(bundleName);
|
||||||
|
if (asset) {
|
||||||
logger.info(
|
logger.info(
|
||||||
`Found CodeQL bundle in ${downloadSource[1]} on ${downloadSource[0]} with URL ${asset.url}.`
|
`Found CodeQL bundle in ${downloadSource[1]} on ${downloadSource[0]} with URL ${asset.url}.`
|
||||||
);
|
);
|
||||||
@@ -221,6 +227,7 @@ async function toolcacheDownloadTool(
|
|||||||
|
|
||||||
export async function setupCodeQL(
|
export async function setupCodeQL(
|
||||||
codeqlURL: string | undefined,
|
codeqlURL: string | undefined,
|
||||||
|
languages: Language[],
|
||||||
githubAuth: string,
|
githubAuth: string,
|
||||||
githubUrl: string,
|
githubUrl: string,
|
||||||
tempDir: string,
|
tempDir: string,
|
||||||
@@ -234,24 +241,88 @@ export async function setupCodeQL(
|
|||||||
process.env["RUNNER_TEMP"] = tempDir;
|
process.env["RUNNER_TEMP"] = tempDir;
|
||||||
process.env["RUNNER_TOOL_CACHE"] = toolsDir;
|
process.env["RUNNER_TOOL_CACHE"] = toolsDir;
|
||||||
|
|
||||||
|
// The URL identifies the release version. E.g., codeql-20200901 .
|
||||||
|
// The plVersion identifies the platform-language combination of the package
|
||||||
|
// within the release. E.g., `linux64-cpp` in `codeql-linux64-cpp.tar.gz`.
|
||||||
|
// We expect the codeqlUrl (when given) to always point to the main bundle
|
||||||
|
// `codeql-bundle.tar.gz`
|
||||||
|
//
|
||||||
|
// The logic is as follows:
|
||||||
|
// - Always use the Toolcache if available.
|
||||||
|
// - If we would like a platform-language package, but have the
|
||||||
|
// full bundle in the cache, use that.
|
||||||
|
// - If codeqlURL is specified, use that.
|
||||||
|
// - If a single language is being analyzed, try to download the platform-language package.
|
||||||
|
// - If it is not available in the release assets, fallback to the full bundle
|
||||||
|
// - If multiple languages are being anlyzed, use the full bundle
|
||||||
|
let plVersion: string | undefined = undefined;
|
||||||
|
let platform: string;
|
||||||
|
if (process.platform === "win32") {
|
||||||
|
platform = "win64";
|
||||||
|
} else if (process.platform === "linux") {
|
||||||
|
platform = "linux64";
|
||||||
|
} else if (process.platform === "darwin") {
|
||||||
|
platform = "osx64";
|
||||||
|
} else {
|
||||||
|
throw new Error(`Unsupported platform: ${process.platform}`);
|
||||||
|
}
|
||||||
|
if (languages.length === 1) {
|
||||||
|
plVersion = `${platform}-${languages[0]}`;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const codeqlURLVersion = getCodeQLURLVersion(
|
const codeqlURLVersion = getCodeQLURLVersion(
|
||||||
codeqlURL || `/${CODEQL_BUNDLE_VERSION}/`,
|
codeqlURL || `/${CODEQL_BUNDLE_VERSION}/`,
|
||||||
logger
|
logger
|
||||||
);
|
);
|
||||||
|
|
||||||
let codeqlFolder = toolcache.find("CodeQL", codeqlURLVersion);
|
let codeqlFolder;
|
||||||
if (codeqlFolder) {
|
|
||||||
logger.debug(`CodeQL found in cache ${codeqlFolder}`);
|
logger.debug(`PL Version ${plVersion}`);
|
||||||
} else {
|
if (plVersion) {
|
||||||
|
codeqlFolder = toolcache.find(
|
||||||
|
"CodeQL",
|
||||||
|
`${codeqlURLVersion}-${plVersion}`
|
||||||
|
);
|
||||||
|
if (codeqlFolder) {
|
||||||
|
logger.debug(`CodeQL found in cache ${codeqlFolder}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!codeqlFolder) {
|
||||||
|
codeqlFolder = toolcache.find("CodeQL", codeqlURLVersion);
|
||||||
|
if (codeqlFolder) {
|
||||||
|
logger.debug(`CodeQL found in cache ${codeqlFolder}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!codeqlFolder) {
|
||||||
|
const codeqlToolcacheVersion = plVersion
|
||||||
|
? `${codeqlURLVersion}-${plVersion}`
|
||||||
|
: codeqlURLVersion;
|
||||||
|
logger.debug(`CodeQL not found in cache`);
|
||||||
if (!codeqlURL) {
|
if (!codeqlURL) {
|
||||||
|
// Provide a few options, from smaller to bigger
|
||||||
|
const bundles: string[] = [];
|
||||||
|
if (plVersion) {
|
||||||
|
bundles.push(
|
||||||
|
CODEQL_BUNDLE_NAME.replace("-bundle", `-bundle-${plVersion}`)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
bundles.push(
|
||||||
|
CODEQL_BUNDLE_NAME.replace("-bundle", `-bundle-${platform}`)
|
||||||
|
);
|
||||||
|
bundles.push(CODEQL_BUNDLE_NAME);
|
||||||
|
|
||||||
codeqlURL = await getCodeQLBundleDownloadURL(
|
codeqlURL = await getCodeQLBundleDownloadURL(
|
||||||
|
bundles,
|
||||||
githubAuth,
|
githubAuth,
|
||||||
githubUrl,
|
githubUrl,
|
||||||
mode,
|
mode,
|
||||||
logger
|
logger
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
logger.debug(`Using CodeQL URL: ${codeqlURL}`);
|
||||||
|
|
||||||
const headers: IHeaders = { accept: "application/octet-stream" };
|
const headers: IHeaders = { accept: "application/octet-stream" };
|
||||||
// We only want to provide an authorization header if we are downloading
|
// We only want to provide an authorization header if we are downloading
|
||||||
@@ -275,10 +346,11 @@ export async function setupCodeQL(
|
|||||||
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);
|
||||||
|
logger.debug(`Caching ${codeqlToolcacheVersion}`);
|
||||||
codeqlFolder = await toolcache.cacheDir(
|
codeqlFolder = await toolcache.cacheDir(
|
||||||
codeqlExtracted,
|
codeqlExtracted,
|
||||||
"CodeQL",
|
"CodeQL",
|
||||||
codeqlURLVersion
|
codeqlToolcacheVersion
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,12 @@ import sinon from "sinon";
|
|||||||
import * as api from "./api-client";
|
import * as api from "./api-client";
|
||||||
import { getCachedCodeQL, setCodeQL } from "./codeql";
|
import { getCachedCodeQL, setCodeQL } from "./codeql";
|
||||||
import * as configUtils from "./config-utils";
|
import * as configUtils from "./config-utils";
|
||||||
import { Language } from "./languages";
|
import {
|
||||||
|
getLanguages,
|
||||||
|
getNoLanguagesError,
|
||||||
|
getUnknownLanguagesError,
|
||||||
|
Language,
|
||||||
|
} from "./languages";
|
||||||
import { getRunnerLogger } from "./logging";
|
import { getRunnerLogger } from "./logging";
|
||||||
import { setupTests } from "./testing-utils";
|
import { setupTests } from "./testing-utils";
|
||||||
import * as util from "./util";
|
import * as util from "./util";
|
||||||
@@ -54,7 +59,7 @@ function mockListLanguages(languages: string[]) {
|
|||||||
test("load empty config", async (t) => {
|
test("load empty config", async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
const logger = getRunnerLogger(true);
|
const logger = getRunnerLogger(true);
|
||||||
const languages = "javascript,python";
|
const languages = [Language.javascript, Language.python];
|
||||||
|
|
||||||
const codeQL = setCodeQL({
|
const codeQL = setCodeQL({
|
||||||
async resolveQueries() {
|
async resolveQueries() {
|
||||||
@@ -70,7 +75,6 @@ test("load empty config", async (t) => {
|
|||||||
languages,
|
languages,
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
@@ -85,12 +89,10 @@ test("load empty config", async (t) => {
|
|||||||
await configUtils.getDefaultConfig(
|
await configUtils.getDefaultConfig(
|
||||||
languages,
|
languages,
|
||||||
undefined,
|
undefined,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
"token",
|
|
||||||
"https://github.example.com",
|
"https://github.example.com",
|
||||||
logger
|
logger
|
||||||
)
|
)
|
||||||
@@ -119,10 +121,9 @@ test("loading config saves config", async (t) => {
|
|||||||
t.deepEqual(await configUtils.getConfig(tmpDir, logger), undefined);
|
t.deepEqual(await configUtils.getConfig(tmpDir, logger), undefined);
|
||||||
|
|
||||||
const config1 = await configUtils.initConfig(
|
const config1 = await configUtils.initConfig(
|
||||||
"javascript,python",
|
[Language.javascript, Language.python],
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
@@ -145,10 +146,9 @@ test("load input outside of workspace", async (t) => {
|
|||||||
return await util.withTmpDir(async (tmpDir) => {
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
try {
|
try {
|
||||||
await configUtils.initConfig(
|
await configUtils.initConfig(
|
||||||
undefined,
|
[],
|
||||||
undefined,
|
undefined,
|
||||||
"../input",
|
"../input",
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
getCachedCodeQL(),
|
getCachedCodeQL(),
|
||||||
@@ -178,10 +178,9 @@ test("load non-local input with invalid repo syntax", async (t) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await configUtils.initConfig(
|
await configUtils.initConfig(
|
||||||
undefined,
|
[],
|
||||||
undefined,
|
undefined,
|
||||||
configFile,
|
configFile,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
getCachedCodeQL(),
|
getCachedCodeQL(),
|
||||||
@@ -206,7 +205,7 @@ test("load non-local input with invalid repo syntax", async (t) => {
|
|||||||
|
|
||||||
test("load non-existent input", async (t) => {
|
test("load non-existent input", async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
const languages = "javascript";
|
const languages = [Language.javascript];
|
||||||
const configFile = "input";
|
const configFile = "input";
|
||||||
t.false(fs.existsSync(path.join(tmpDir, configFile)));
|
t.false(fs.existsSync(path.join(tmpDir, configFile)));
|
||||||
|
|
||||||
@@ -215,7 +214,6 @@ test("load non-existent input", async (t) => {
|
|||||||
languages,
|
languages,
|
||||||
undefined,
|
undefined,
|
||||||
configFile,
|
configFile,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
getCachedCodeQL(),
|
getCachedCodeQL(),
|
||||||
@@ -292,14 +290,13 @@ test("load non-empty input", async (t) => {
|
|||||||
codeQLCmd: codeQL.getPath(),
|
codeQLCmd: codeQL.getPath(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const languages = "javascript";
|
const languages = [Language.javascript];
|
||||||
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
||||||
|
|
||||||
const actualConfig = await configUtils.initConfig(
|
const actualConfig = await configUtils.initConfig(
|
||||||
languages,
|
languages,
|
||||||
undefined,
|
undefined,
|
||||||
configFilePath,
|
configFilePath,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
@@ -353,14 +350,13 @@ test("Default queries are used", async (t) => {
|
|||||||
|
|
||||||
fs.mkdirSync(path.join(tmpDir, "foo"));
|
fs.mkdirSync(path.join(tmpDir, "foo"));
|
||||||
|
|
||||||
const languages = "javascript";
|
const languages = [Language.javascript];
|
||||||
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
||||||
|
|
||||||
await configUtils.initConfig(
|
await configUtils.initConfig(
|
||||||
languages,
|
languages,
|
||||||
undefined,
|
undefined,
|
||||||
configFilePath,
|
configFilePath,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
@@ -423,13 +419,12 @@ test("Queries can be specified in config file", async (t) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const languages = "javascript";
|
const languages = [Language.javascript];
|
||||||
|
|
||||||
const config = await configUtils.initConfig(
|
const config = await configUtils.initConfig(
|
||||||
languages,
|
languages,
|
||||||
undefined,
|
undefined,
|
||||||
configFilePath,
|
configFilePath,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
@@ -486,13 +481,12 @@ test("Queries from config file can be overridden in workflow file", async (t) =>
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const languages = "javascript";
|
const languages = [Language.javascript];
|
||||||
|
|
||||||
const config = await configUtils.initConfig(
|
const config = await configUtils.initConfig(
|
||||||
languages,
|
languages,
|
||||||
queries,
|
queries,
|
||||||
configFilePath,
|
configFilePath,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
@@ -547,13 +541,12 @@ test("Queries in workflow file can be used in tandem with the 'disable default q
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const languages = "javascript";
|
const languages = [Language.javascript];
|
||||||
|
|
||||||
const config = await configUtils.initConfig(
|
const config = await configUtils.initConfig(
|
||||||
languages,
|
languages,
|
||||||
queries,
|
queries,
|
||||||
configFilePath,
|
configFilePath,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
@@ -598,13 +591,12 @@ test("Multiple queries can be specified in workflow file, no config file require
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const languages = "javascript";
|
const languages = [Language.javascript];
|
||||||
|
|
||||||
const config = await configUtils.initConfig(
|
const config = await configUtils.initConfig(
|
||||||
languages,
|
languages,
|
||||||
queries,
|
queries,
|
||||||
undefined,
|
undefined,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
@@ -667,13 +659,12 @@ test("Queries in workflow file can be added to the set of queries without overri
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const languages = "javascript";
|
const languages = [Language.javascript];
|
||||||
|
|
||||||
const config = await configUtils.initConfig(
|
const config = await configUtils.initConfig(
|
||||||
languages,
|
languages,
|
||||||
queries,
|
queries,
|
||||||
configFilePath,
|
configFilePath,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
@@ -711,7 +702,7 @@ test("Queries in workflow file can be added to the set of queries without overri
|
|||||||
test("Invalid queries in workflow file handled correctly", async (t) => {
|
test("Invalid queries in workflow file handled correctly", async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
const queries = "foo/bar@v1@v3";
|
const queries = "foo/bar@v1@v3";
|
||||||
const languages = "javascript";
|
const languages = [Language.javascript];
|
||||||
|
|
||||||
// This function just needs to be type-correct; it doesn't need to do anything,
|
// This function just needs to be type-correct; it doesn't need to do anything,
|
||||||
// since we're deliberately passing in invalid data
|
// since we're deliberately passing in invalid data
|
||||||
@@ -735,7 +726,6 @@ test("Invalid queries in workflow file handled correctly", async (t) => {
|
|||||||
languages,
|
languages,
|
||||||
queries,
|
queries,
|
||||||
undefined,
|
undefined,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
@@ -791,13 +781,12 @@ test("API client used when reading remote config", async (t) => {
|
|||||||
fs.mkdirSync(path.join(tmpDir, "foo/bar/dev"), { recursive: true });
|
fs.mkdirSync(path.join(tmpDir, "foo/bar/dev"), { recursive: true });
|
||||||
|
|
||||||
const configFile = "octo-org/codeql-config/config.yaml@main";
|
const configFile = "octo-org/codeql-config/config.yaml@main";
|
||||||
const languages = "javascript";
|
const languages = [Language.javascript];
|
||||||
|
|
||||||
await configUtils.initConfig(
|
await configUtils.initConfig(
|
||||||
languages,
|
languages,
|
||||||
undefined,
|
undefined,
|
||||||
configFile,
|
configFile,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
@@ -818,10 +807,9 @@ test("Remote config handles the case where a directory is provided", async (t) =
|
|||||||
const repoReference = "octo-org/codeql-config/config.yaml@main";
|
const repoReference = "octo-org/codeql-config/config.yaml@main";
|
||||||
try {
|
try {
|
||||||
await configUtils.initConfig(
|
await configUtils.initConfig(
|
||||||
undefined,
|
[],
|
||||||
undefined,
|
undefined,
|
||||||
repoReference,
|
repoReference,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
getCachedCodeQL(),
|
getCachedCodeQL(),
|
||||||
@@ -850,10 +838,9 @@ test("Invalid format of remote config handled correctly", async (t) => {
|
|||||||
const repoReference = "octo-org/codeql-config/config.yaml@main";
|
const repoReference = "octo-org/codeql-config/config.yaml@main";
|
||||||
try {
|
try {
|
||||||
await configUtils.initConfig(
|
await configUtils.initConfig(
|
||||||
undefined,
|
[],
|
||||||
undefined,
|
undefined,
|
||||||
repoReference,
|
repoReference,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
getCachedCodeQL(),
|
getCachedCodeQL(),
|
||||||
@@ -873,56 +860,36 @@ test("Invalid format of remote config handled correctly", async (t) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("No detected languages", async (t) => {
|
test("No detected languages", async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
mockListLanguages([]);
|
||||||
mockListLanguages([]);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await configUtils.initConfig(
|
await getLanguages(
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
{ owner: "github", repo: "example " },
|
||||||
undefined,
|
"token",
|
||||||
{ owner: "github", repo: "example " },
|
"https://github.example.com",
|
||||||
tmpDir,
|
getRunnerLogger(true)
|
||||||
tmpDir,
|
);
|
||||||
getCachedCodeQL(),
|
throw new Error("initConfig did not throw error");
|
||||||
tmpDir,
|
} catch (err) {
|
||||||
"token",
|
t.deepEqual(err, new Error(getNoLanguagesError()));
|
||||||
"https://github.example.com",
|
}
|
||||||
getRunnerLogger(true)
|
|
||||||
);
|
|
||||||
throw new Error("initConfig did not throw error");
|
|
||||||
} catch (err) {
|
|
||||||
t.deepEqual(err, new Error(configUtils.getNoLanguagesError()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Unknown languages", async (t) => {
|
test("Unknown languages", async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
const languages = "ruby,english";
|
||||||
const languages = "ruby,english";
|
try {
|
||||||
|
await getLanguages(
|
||||||
try {
|
languages,
|
||||||
await configUtils.initConfig(
|
{ owner: "github", repo: "example " },
|
||||||
languages,
|
"token",
|
||||||
undefined,
|
"https://github.example.com",
|
||||||
undefined,
|
getRunnerLogger(true)
|
||||||
{ owner: "github", repo: "example " },
|
);
|
||||||
tmpDir,
|
throw new Error("initConfig did not throw error");
|
||||||
tmpDir,
|
} catch (err) {
|
||||||
getCachedCodeQL(),
|
t.deepEqual(err, new Error(getUnknownLanguagesError(["ruby", "english"])));
|
||||||
tmpDir,
|
}
|
||||||
"token",
|
|
||||||
"https://github.example.com",
|
|
||||||
getRunnerLogger(true)
|
|
||||||
);
|
|
||||||
throw new Error("initConfig did not throw error");
|
|
||||||
} catch (err) {
|
|
||||||
t.deepEqual(
|
|
||||||
err,
|
|
||||||
new Error(configUtils.getUnknownLanguagesError(["ruby", "english"]))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function doInvalidInputTest(
|
function doInvalidInputTest(
|
||||||
@@ -942,7 +909,7 @@ function doInvalidInputTest(
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const languages = "javascript";
|
const languages = [Language.javascript];
|
||||||
const configFile = "input";
|
const configFile = "input";
|
||||||
const inputFile = path.join(tmpDir, configFile);
|
const inputFile = path.join(tmpDir, configFile);
|
||||||
fs.writeFileSync(inputFile, inputFileContents, "utf8");
|
fs.writeFileSync(inputFile, inputFileContents, "utf8");
|
||||||
@@ -952,7 +919,6 @@ function doInvalidInputTest(
|
|||||||
languages,
|
languages,
|
||||||
undefined,
|
undefined,
|
||||||
configFile,
|
configFile,
|
||||||
{ owner: "github", repo: "example " },
|
|
||||||
tmpDir,
|
tmpDir,
|
||||||
tmpDir,
|
tmpDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
|
|||||||
@@ -5,9 +5,8 @@ import * as path from "path";
|
|||||||
import * as api from "./api-client";
|
import * as api from "./api-client";
|
||||||
import { CodeQL, ResolveQueriesOutput } from "./codeql";
|
import { CodeQL, ResolveQueriesOutput } from "./codeql";
|
||||||
import * as externalQueries from "./external-queries";
|
import * as externalQueries from "./external-queries";
|
||||||
import { Language, parseLanguage } from "./languages";
|
import { Language } from "./languages";
|
||||||
import { Logger } from "./logging";
|
import { Logger } from "./logging";
|
||||||
import { RepositoryNwo } from "./repository";
|
|
||||||
|
|
||||||
// Property names from the user-supplied config file.
|
// Property names from the user-supplied config file.
|
||||||
const NAME_PROPERTY = "name";
|
const NAME_PROPERTY = "name";
|
||||||
@@ -573,111 +572,6 @@ function getConfigFilePropertyError(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNoLanguagesError(): string {
|
|
||||||
return (
|
|
||||||
"Did not detect any languages to analyze. " +
|
|
||||||
"Please update input in workflow or check that GitHub detects the correct languages in your repository."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getUnknownLanguagesError(languages: string[]): string {
|
|
||||||
return `Did not recognise the following languages: ${languages.join(", ")}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the set of languages in the current repository
|
|
||||||
*/
|
|
||||||
async function getLanguagesInRepo(
|
|
||||||
repository: RepositoryNwo,
|
|
||||||
githubAuth: string,
|
|
||||||
githubUrl: string,
|
|
||||||
logger: Logger
|
|
||||||
): Promise<Language[]> {
|
|
||||||
logger.debug(`GitHub repo ${repository.owner} ${repository.repo}`);
|
|
||||||
const response = await api
|
|
||||||
.getApiClient(githubAuth, githubUrl, true)
|
|
||||||
.repos.listLanguages({
|
|
||||||
owner: repository.owner,
|
|
||||||
repo: repository.repo,
|
|
||||||
});
|
|
||||||
|
|
||||||
logger.debug(`Languages API response: ${JSON.stringify(response)}`);
|
|
||||||
|
|
||||||
// The GitHub API is going to return languages in order of popularity,
|
|
||||||
// When we pick a language to autobuild we want to pick the most popular traced language
|
|
||||||
// Since sets in javascript maintain insertion order, using a set here and then splatting it
|
|
||||||
// into an array gives us an array of languages ordered by popularity
|
|
||||||
const languages: Set<Language> = new Set();
|
|
||||||
for (const lang of Object.keys(response.data)) {
|
|
||||||
const parsedLang = parseLanguage(lang);
|
|
||||||
if (parsedLang !== undefined) {
|
|
||||||
languages.add(parsedLang);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [...languages];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the languages to analyse.
|
|
||||||
*
|
|
||||||
* The result is obtained from the action input parameter 'languages' if that
|
|
||||||
* has been set, otherwise it is deduced as all languages in the repo that
|
|
||||||
* can be analysed.
|
|
||||||
*
|
|
||||||
* If no languages could be detected from either the workflow or the repository
|
|
||||||
* then throw an error.
|
|
||||||
*/
|
|
||||||
async function getLanguages(
|
|
||||||
languagesInput: string | undefined,
|
|
||||||
repository: RepositoryNwo,
|
|
||||||
githubAuth: string,
|
|
||||||
githubUrl: string,
|
|
||||||
logger: Logger
|
|
||||||
): Promise<Language[]> {
|
|
||||||
// Obtain from action input 'languages' if set
|
|
||||||
let languages = (languagesInput || "")
|
|
||||||
.split(",")
|
|
||||||
.map((x) => x.trim())
|
|
||||||
.filter((x) => x.length > 0);
|
|
||||||
logger.info(`Languages from configuration: ${JSON.stringify(languages)}`);
|
|
||||||
|
|
||||||
if (languages.length === 0) {
|
|
||||||
// Obtain languages as all languages in the repo that can be analysed
|
|
||||||
languages = await getLanguagesInRepo(
|
|
||||||
repository,
|
|
||||||
githubAuth,
|
|
||||||
githubUrl,
|
|
||||||
logger
|
|
||||||
);
|
|
||||||
logger.info(
|
|
||||||
`Automatically detected languages: ${JSON.stringify(languages)}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the languages parameter was not given and no languages were
|
|
||||||
// detected then fail here as this is a workflow configuration error.
|
|
||||||
if (languages.length === 0) {
|
|
||||||
throw new Error(getNoLanguagesError());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure they are supported
|
|
||||||
const parsedLanguages: Language[] = [];
|
|
||||||
const unknownLanguages: string[] = [];
|
|
||||||
for (const language of languages) {
|
|
||||||
const parsedLanguage = parseLanguage(language);
|
|
||||||
if (parsedLanguage === undefined) {
|
|
||||||
unknownLanguages.push(language);
|
|
||||||
} else if (parsedLanguages.indexOf(parsedLanguage) === -1) {
|
|
||||||
parsedLanguages.push(parsedLanguage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (unknownLanguages.length > 0) {
|
|
||||||
throw new Error(getUnknownLanguagesError(unknownLanguages));
|
|
||||||
}
|
|
||||||
|
|
||||||
return parsedLanguages;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function addQueriesFromWorkflow(
|
async function addQueriesFromWorkflow(
|
||||||
codeQL: CodeQL,
|
codeQL: CodeQL,
|
||||||
queriesInput: string,
|
queriesInput: string,
|
||||||
@@ -722,24 +616,15 @@ function shouldAddConfigFileQueries(queriesInput: string | undefined): boolean {
|
|||||||
* Get the default config for when the user has not supplied one.
|
* Get the default config for when the user has not supplied one.
|
||||||
*/
|
*/
|
||||||
export async function getDefaultConfig(
|
export async function getDefaultConfig(
|
||||||
languagesInput: string | undefined,
|
languages: Language[],
|
||||||
queriesInput: string | undefined,
|
queriesInput: string | undefined,
|
||||||
repository: RepositoryNwo,
|
|
||||||
tempDir: string,
|
tempDir: string,
|
||||||
toolCacheDir: string,
|
toolCacheDir: string,
|
||||||
codeQL: CodeQL,
|
codeQL: CodeQL,
|
||||||
checkoutPath: string,
|
checkoutPath: string,
|
||||||
githubAuth: string,
|
|
||||||
githubUrl: string,
|
githubUrl: string,
|
||||||
logger: Logger
|
logger: Logger
|
||||||
): Promise<Config> {
|
): Promise<Config> {
|
||||||
const languages = await getLanguages(
|
|
||||||
languagesInput,
|
|
||||||
repository,
|
|
||||||
githubAuth,
|
|
||||||
githubUrl,
|
|
||||||
logger
|
|
||||||
);
|
|
||||||
const queries: Queries = {};
|
const queries: Queries = {};
|
||||||
await addDefaultQueries(codeQL, languages, queries);
|
await addDefaultQueries(codeQL, languages, queries);
|
||||||
if (queriesInput) {
|
if (queriesInput) {
|
||||||
@@ -771,10 +656,9 @@ export async function getDefaultConfig(
|
|||||||
* Load the config from the given file.
|
* Load the config from the given file.
|
||||||
*/
|
*/
|
||||||
async function loadConfig(
|
async function loadConfig(
|
||||||
languagesInput: string | undefined,
|
languages: Language[],
|
||||||
queriesInput: string | undefined,
|
queriesInput: string | undefined,
|
||||||
configFile: string,
|
configFile: string,
|
||||||
repository: RepositoryNwo,
|
|
||||||
tempDir: string,
|
tempDir: string,
|
||||||
toolCacheDir: string,
|
toolCacheDir: string,
|
||||||
codeQL: CodeQL,
|
codeQL: CodeQL,
|
||||||
@@ -804,14 +688,6 @@ async function loadConfig(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const languages = await getLanguages(
|
|
||||||
languagesInput,
|
|
||||||
repository,
|
|
||||||
githubAuth,
|
|
||||||
githubUrl,
|
|
||||||
logger
|
|
||||||
);
|
|
||||||
|
|
||||||
const queries: Queries = {};
|
const queries: Queries = {};
|
||||||
const pathsIgnore: string[] = [];
|
const pathsIgnore: string[] = [];
|
||||||
const paths: string[] = [];
|
const paths: string[] = [];
|
||||||
@@ -933,10 +809,9 @@ async function loadConfig(
|
|||||||
* a default config. The parsed config is then stored to a known location.
|
* a default config. The parsed config is then stored to a known location.
|
||||||
*/
|
*/
|
||||||
export async function initConfig(
|
export async function initConfig(
|
||||||
languagesInput: string | undefined,
|
languages: Language[],
|
||||||
queriesInput: string | undefined,
|
queriesInput: string | undefined,
|
||||||
configFile: string | undefined,
|
configFile: string | undefined,
|
||||||
repository: RepositoryNwo,
|
|
||||||
tempDir: string,
|
tempDir: string,
|
||||||
toolCacheDir: string,
|
toolCacheDir: string,
|
||||||
codeQL: CodeQL,
|
codeQL: CodeQL,
|
||||||
@@ -951,23 +826,20 @@ export async function initConfig(
|
|||||||
if (!configFile) {
|
if (!configFile) {
|
||||||
logger.debug("No configuration file was provided");
|
logger.debug("No configuration file was provided");
|
||||||
config = await getDefaultConfig(
|
config = await getDefaultConfig(
|
||||||
languagesInput,
|
languages,
|
||||||
queriesInput,
|
queriesInput,
|
||||||
repository,
|
|
||||||
tempDir,
|
tempDir,
|
||||||
toolCacheDir,
|
toolCacheDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
checkoutPath,
|
checkoutPath,
|
||||||
githubAuth,
|
|
||||||
githubUrl,
|
githubUrl,
|
||||||
logger
|
logger
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
config = await loadConfig(
|
config = await loadConfig(
|
||||||
languagesInput,
|
languages,
|
||||||
queriesInput,
|
queriesInput,
|
||||||
configFile,
|
configFile,
|
||||||
repository,
|
|
||||||
tempDir,
|
tempDir,
|
||||||
toolCacheDir,
|
toolCacheDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import * as actionsUtil from "./actions-util";
|
|||||||
import { CodeQL } from "./codeql";
|
import { CodeQL } from "./codeql";
|
||||||
import * as configUtils from "./config-utils";
|
import * as configUtils from "./config-utils";
|
||||||
import { initCodeQL, initConfig, injectWindowsTracer, runInit } from "./init";
|
import { initCodeQL, initConfig, injectWindowsTracer, runInit } from "./init";
|
||||||
|
import { getLanguages } from "./languages";
|
||||||
import { getActionsLogger } from "./logging";
|
import { getActionsLogger } from "./logging";
|
||||||
import { parseRepositoryNwo } from "./repository";
|
import { parseRepositoryNwo } from "./repository";
|
||||||
|
|
||||||
@@ -88,9 +89,21 @@ async function run() {
|
|||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const repositoryNWO = parseRepositoryNwo(
|
||||||
|
actionsUtil.getRequiredEnvParam("GITHUB_REPOSITORY")
|
||||||
|
);
|
||||||
|
|
||||||
|
const languages = await getLanguages(
|
||||||
|
actionsUtil.getOptionalInput("languages"),
|
||||||
|
repositoryNWO,
|
||||||
|
actionsUtil.getRequiredInput("token"),
|
||||||
|
actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"),
|
||||||
|
logger
|
||||||
|
);
|
||||||
|
|
||||||
codeql = await initCodeQL(
|
codeql = await initCodeQL(
|
||||||
actionsUtil.getOptionalInput("tools"),
|
actionsUtil.getOptionalInput("tools"),
|
||||||
|
languages,
|
||||||
actionsUtil.getRequiredInput("token"),
|
actionsUtil.getRequiredInput("token"),
|
||||||
actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"),
|
actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"),
|
||||||
actionsUtil.getRequiredEnvParam("RUNNER_TEMP"),
|
actionsUtil.getRequiredEnvParam("RUNNER_TEMP"),
|
||||||
@@ -98,11 +111,11 @@ async function run() {
|
|||||||
"actions",
|
"actions",
|
||||||
logger
|
logger
|
||||||
);
|
);
|
||||||
|
|
||||||
config = await initConfig(
|
config = await initConfig(
|
||||||
actionsUtil.getOptionalInput("languages"),
|
languages,
|
||||||
actionsUtil.getOptionalInput("queries"),
|
actionsUtil.getOptionalInput("queries"),
|
||||||
actionsUtil.getOptionalInput("config-file"),
|
actionsUtil.getOptionalInput("config-file"),
|
||||||
parseRepositoryNwo(actionsUtil.getRequiredEnvParam("GITHUB_REPOSITORY")),
|
|
||||||
actionsUtil.getRequiredEnvParam("RUNNER_TEMP"),
|
actionsUtil.getRequiredEnvParam("RUNNER_TEMP"),
|
||||||
actionsUtil.getRequiredEnvParam("RUNNER_TOOL_CACHE"),
|
actionsUtil.getRequiredEnvParam("RUNNER_TOOL_CACHE"),
|
||||||
codeql,
|
codeql,
|
||||||
|
|||||||
13
src/init.ts
13
src/init.ts
@@ -5,13 +5,14 @@ import * as path from "path";
|
|||||||
import * as analysisPaths from "./analysis-paths";
|
import * as analysisPaths from "./analysis-paths";
|
||||||
import { CodeQL, setupCodeQL } from "./codeql";
|
import { CodeQL, setupCodeQL } from "./codeql";
|
||||||
import * as configUtils from "./config-utils";
|
import * as configUtils from "./config-utils";
|
||||||
|
import { Language } from "./languages";
|
||||||
import { Logger } from "./logging";
|
import { Logger } from "./logging";
|
||||||
import { RepositoryNwo } from "./repository";
|
import { getCombinedTracerConfig, TracerConfig } from "./tracer-config";
|
||||||
import { TracerConfig, getCombinedTracerConfig } from "./tracer-config";
|
|
||||||
import * as util from "./util";
|
import * as util from "./util";
|
||||||
|
|
||||||
export async function initCodeQL(
|
export async function initCodeQL(
|
||||||
codeqlURL: string | undefined,
|
codeqlURL: string | undefined,
|
||||||
|
languages: Language[],
|
||||||
githubAuth: string,
|
githubAuth: string,
|
||||||
githubUrl: string,
|
githubUrl: string,
|
||||||
tempDir: string,
|
tempDir: string,
|
||||||
@@ -20,8 +21,10 @@ export async function initCodeQL(
|
|||||||
logger: Logger
|
logger: Logger
|
||||||
): Promise<CodeQL> {
|
): Promise<CodeQL> {
|
||||||
logger.startGroup("Setup CodeQL tools");
|
logger.startGroup("Setup CodeQL tools");
|
||||||
|
|
||||||
const codeql = await setupCodeQL(
|
const codeql = await setupCodeQL(
|
||||||
codeqlURL,
|
codeqlURL,
|
||||||
|
languages,
|
||||||
githubAuth,
|
githubAuth,
|
||||||
githubUrl,
|
githubUrl,
|
||||||
tempDir,
|
tempDir,
|
||||||
@@ -35,10 +38,9 @@ export async function initCodeQL(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function initConfig(
|
export async function initConfig(
|
||||||
languagesInput: string | undefined,
|
languages: Language[],
|
||||||
queriesInput: string | undefined,
|
queriesInput: string | undefined,
|
||||||
configFile: string | undefined,
|
configFile: string | undefined,
|
||||||
repository: RepositoryNwo,
|
|
||||||
tempDir: string,
|
tempDir: string,
|
||||||
toolCacheDir: string,
|
toolCacheDir: string,
|
||||||
codeQL: CodeQL,
|
codeQL: CodeQL,
|
||||||
@@ -49,10 +51,9 @@ export async function initConfig(
|
|||||||
): Promise<configUtils.Config> {
|
): Promise<configUtils.Config> {
|
||||||
logger.startGroup("Load language configuration");
|
logger.startGroup("Load language configuration");
|
||||||
const config = await configUtils.initConfig(
|
const config = await configUtils.initConfig(
|
||||||
languagesInput,
|
languages,
|
||||||
queriesInput,
|
queriesInput,
|
||||||
configFile,
|
configFile,
|
||||||
repository,
|
|
||||||
tempDir,
|
tempDir,
|
||||||
toolCacheDir,
|
toolCacheDir,
|
||||||
codeQL,
|
codeQL,
|
||||||
|
|||||||
109
src/languages.ts
109
src/languages.ts
@@ -1,3 +1,7 @@
|
|||||||
|
import * as api from "./api-client";
|
||||||
|
import { Logger } from "./logging";
|
||||||
|
import { RepositoryNwo } from "./repository";
|
||||||
|
|
||||||
// All the languages supported by CodeQL
|
// All the languages supported by CodeQL
|
||||||
export enum Language {
|
export enum Language {
|
||||||
csharp = "csharp",
|
csharp = "csharp",
|
||||||
@@ -41,3 +45,108 @@ export function isTracedLanguage(language: Language): boolean {
|
|||||||
export function isScannedLanguage(language: Language): boolean {
|
export function isScannedLanguage(language: Language): boolean {
|
||||||
return !isTracedLanguage(language);
|
return !isTracedLanguage(language);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getNoLanguagesError(): string {
|
||||||
|
return (
|
||||||
|
"Did not detect any languages to analyze. " +
|
||||||
|
"Please update input in workflow or check that GitHub detects the correct languages in your repository."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getUnknownLanguagesError(languages: string[]): string {
|
||||||
|
return `Did not recognise the following languages: ${languages.join(", ")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the languages to analyse.
|
||||||
|
*
|
||||||
|
* The result is obtained from the action input parameter 'languages' if that
|
||||||
|
* has been set, otherwise it is deduced as all languages in the repo that
|
||||||
|
* can be analysed.
|
||||||
|
*
|
||||||
|
* If no languages could be detected from either the workflow or the repository
|
||||||
|
* then throw an error.
|
||||||
|
*/
|
||||||
|
export async function getLanguages(
|
||||||
|
languagesInput: string | undefined,
|
||||||
|
repository: RepositoryNwo,
|
||||||
|
githubAuth: string,
|
||||||
|
githubUrl: string,
|
||||||
|
logger: Logger
|
||||||
|
): Promise<Language[]> {
|
||||||
|
// Obtain from action input 'languages' if set
|
||||||
|
let languages = (languagesInput || "")
|
||||||
|
.split(",")
|
||||||
|
.map((x) => x.trim())
|
||||||
|
.filter((x) => x.length > 0);
|
||||||
|
logger.info(`Languages from configuration: ${JSON.stringify(languages)}`);
|
||||||
|
|
||||||
|
if (languages.length === 0) {
|
||||||
|
// Obtain languages as all languages in the repo that can be analysed
|
||||||
|
languages = await getLanguagesInRepo(
|
||||||
|
repository,
|
||||||
|
githubAuth,
|
||||||
|
githubUrl,
|
||||||
|
logger
|
||||||
|
);
|
||||||
|
logger.info(
|
||||||
|
`Automatically detected languages: ${JSON.stringify(languages)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the languages parameter was not given and no languages were
|
||||||
|
// detected then fail here as this is a workflow configuration error.
|
||||||
|
if (languages.length === 0) {
|
||||||
|
throw new Error(getNoLanguagesError());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure they are supported
|
||||||
|
const parsedLanguages: Language[] = [];
|
||||||
|
const unknownLanguages: string[] = [];
|
||||||
|
for (const language of languages) {
|
||||||
|
const parsedLanguage = parseLanguage(language);
|
||||||
|
if (parsedLanguage === undefined) {
|
||||||
|
unknownLanguages.push(language);
|
||||||
|
} else if (parsedLanguages.indexOf(parsedLanguage) === -1) {
|
||||||
|
parsedLanguages.push(parsedLanguage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (unknownLanguages.length > 0) {
|
||||||
|
throw new Error(getUnknownLanguagesError(unknownLanguages));
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsedLanguages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the set of languages in the current repository
|
||||||
|
*/
|
||||||
|
async function getLanguagesInRepo(
|
||||||
|
repository: RepositoryNwo,
|
||||||
|
githubAuth: string,
|
||||||
|
githubUrl: string,
|
||||||
|
logger: Logger
|
||||||
|
): Promise<Language[]> {
|
||||||
|
logger.debug(`GitHub repo ${repository.owner} ${repository.repo}`);
|
||||||
|
const response = await api
|
||||||
|
.getApiClient(githubAuth, githubUrl, true)
|
||||||
|
.repos.listLanguages({
|
||||||
|
owner: repository.owner,
|
||||||
|
repo: repository.repo,
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.debug(`Languages API response: ${JSON.stringify(response)}`);
|
||||||
|
|
||||||
|
// The GitHub API is going to return languages in order of popularity,
|
||||||
|
// When we pick a language to autobuild we want to pick the most popular traced language
|
||||||
|
// Since sets in javascript maintain insertion order, using a set here and then splatting it
|
||||||
|
// into an array gives us an array of languages ordered by popularity
|
||||||
|
const languages: Set<Language> = new Set();
|
||||||
|
for (const lang of Object.keys(response.data)) {
|
||||||
|
const parsedLang = parseLanguage(lang);
|
||||||
|
if (parsedLang !== undefined) {
|
||||||
|
languages.add(parsedLang);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [...languages];
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import { determineAutobuildLanguage, runAutobuild } from "./autobuild";
|
|||||||
import { CodeQL, getCodeQL } from "./codeql";
|
import { CodeQL, getCodeQL } from "./codeql";
|
||||||
import { Config, getConfig } from "./config-utils";
|
import { Config, getConfig } from "./config-utils";
|
||||||
import { initCodeQL, initConfig, injectWindowsTracer, runInit } from "./init";
|
import { initCodeQL, initConfig, injectWindowsTracer, runInit } from "./init";
|
||||||
import { Language, parseLanguage } from "./languages";
|
import { getLanguages, Language, parseLanguage } from "./languages";
|
||||||
import { getRunnerLogger } from "./logging";
|
import { getRunnerLogger } from "./logging";
|
||||||
import { parseRepositoryNwo } from "./repository";
|
import { parseRepositoryNwo } from "./repository";
|
||||||
import * as upload_lib from "./upload-lib";
|
import * as upload_lib from "./upload-lib";
|
||||||
import { getAddSnippetsFlag, getMemoryFlag, getThreadsFlag } from "./util";
|
import { getMemoryFlag, getThreadsFlag, getAddSnippetsFlag } from "./util";
|
||||||
|
|
||||||
const program = new Command();
|
const program = new Command();
|
||||||
program.version("0.0.1");
|
program.version("0.0.1");
|
||||||
@@ -159,14 +159,26 @@ program
|
|||||||
fs.rmdirSync(tempDir, { recursive: true });
|
fs.rmdirSync(tempDir, { recursive: true });
|
||||||
fs.mkdirSync(tempDir, { recursive: true });
|
fs.mkdirSync(tempDir, { recursive: true });
|
||||||
|
|
||||||
|
const githubUrl = parseGithubUrl(cmd.githubUrl);
|
||||||
|
const repositoryNWO = parseRepositoryNwo(cmd.repository);
|
||||||
|
|
||||||
|
const languages = await getLanguages(
|
||||||
|
cmd.languages,
|
||||||
|
repositoryNWO,
|
||||||
|
cmd.githubAuth,
|
||||||
|
githubUrl,
|
||||||
|
logger
|
||||||
|
);
|
||||||
|
|
||||||
let codeql: CodeQL;
|
let codeql: CodeQL;
|
||||||
if (cmd.codeqlPath !== undefined) {
|
if (cmd.codeqlPath !== undefined) {
|
||||||
codeql = getCodeQL(cmd.codeqlPath);
|
codeql = getCodeQL(cmd.codeqlPath);
|
||||||
} else {
|
} else {
|
||||||
codeql = await initCodeQL(
|
codeql = await initCodeQL(
|
||||||
undefined,
|
undefined,
|
||||||
|
languages,
|
||||||
cmd.githubAuth,
|
cmd.githubAuth,
|
||||||
parseGithubUrl(cmd.githubUrl),
|
githubUrl,
|
||||||
tempDir,
|
tempDir,
|
||||||
toolsDir,
|
toolsDir,
|
||||||
"runner",
|
"runner",
|
||||||
@@ -175,10 +187,9 @@ program
|
|||||||
}
|
}
|
||||||
|
|
||||||
const config = await initConfig(
|
const config = await initConfig(
|
||||||
cmd.languages,
|
languages,
|
||||||
cmd.queries,
|
cmd.queries,
|
||||||
cmd.configFile,
|
cmd.configFile,
|
||||||
parseRepositoryNwo(cmd.repository),
|
|
||||||
tempDir,
|
tempDir,
|
||||||
toolsDir,
|
toolsDir,
|
||||||
codeql,
|
codeql,
|
||||||
|
|||||||
Reference in New Issue
Block a user