Merge pull request #1221 from github/aeisenberg/ghes-pack-download
Add support for downloading packs from GHES
This commit is contained in:
commit
9ba4d500aa
26 changed files with 861 additions and 125 deletions
83
.github/workflows/__init-with-registries.yml
generated
vendored
Normal file
83
.github/workflows/__init-with-registries.yml
generated
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
# Warning: This file is generated automatically, and should not be modified.
|
||||
# Instead, please modify the template in the pr-checks directory and run:
|
||||
# pip install ruamel.yaml && python3 sync.py
|
||||
# to regenerate this file.
|
||||
|
||||
name: 'PR Check - Packaging: Download using registries'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GO111MODULE: auto
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- releases/v1
|
||||
- releases/v2
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- ready_for_review
|
||||
workflow_dispatch: {}
|
||||
jobs:
|
||||
init-with-registries:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
version: nightly-latest
|
||||
- os: macos-latest
|
||||
version: nightly-latest
|
||||
- os: windows-2019
|
||||
version: nightly-latest
|
||||
- os: windows-2022
|
||||
version: nightly-latest
|
||||
name: 'Packaging: Download using registries'
|
||||
timeout-minutes: 45
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Prepare test
|
||||
id: prepare-test
|
||||
uses: ./.github/prepare-test
|
||||
with:
|
||||
version: ${{ matrix.version }}
|
||||
- name: Init with registries
|
||||
uses: ./../action/init
|
||||
with:
|
||||
db-location: ${{ runner.temp }}/customDbLocation
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
config-file: ./.github/codeql/codeql-config-registries.yml
|
||||
languages: javascript
|
||||
registries: |
|
||||
- url: "https://ghcr.io/v2/"
|
||||
packages: "*/*"
|
||||
token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
env:
|
||||
TEST_MODE: true
|
||||
- name: Verify packages installed
|
||||
shell: bash
|
||||
run: |
|
||||
PRIVATE_PACK="$HOME/.codeql/packages/dsp-testing/private-pack"
|
||||
CODEQL_PACK1="$HOME/.codeql/packages/dsp-testing/codeql-pack1"
|
||||
|
||||
if [[ -d $PRIVATE_PACK ]]
|
||||
then
|
||||
echo "$PRIVATE_PACK was installed."
|
||||
else
|
||||
echo "::error $PRIVATE_PACK pack was not installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -d $CODEQL_PACK1 ]]
|
||||
then
|
||||
echo "$CODEQL_PACK1 was installed."
|
||||
else
|
||||
echo "::error $CODEQL_PACK1 pack was not installed."
|
||||
exit 1
|
||||
fi
|
||||
env:
|
||||
INTERNAL_CODEQL_ACTION_DEBUG_LOC: true
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## [UNRELEASED]
|
||||
|
||||
No user facing changes.
|
||||
- Allow CodeQL packs to be downloaded from GitHub Enterprise Server instances, using the new `registries` input for the `init` action. [#1221](https://github.com/github/codeql-action/pull/1221)
|
||||
|
||||
## 2.1.22 - 01 Sep 2022
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ No user facing changes.
|
|||
## 2.1.15 - 28 Jun 2022
|
||||
|
||||
- CodeQL query packs listed in the `packs` configuration field will be skipped if their target language is not being analyzed in the current Actions job. Previously, this would throw an error. [#1116](https://github.com/github/codeql-action/pull/1116)
|
||||
- The combination of python2 and poetry is no longer supported. See https://github.com/actions/setup-python/issues/374 for more details. [#1124](https://github.com/github/codeql-action/pull/1124)
|
||||
- The combination of python2 and poetry is no longer supported. See <https://github.com/actions/setup-python/issues/374> for more details. [#1124](https://github.com/github/codeql-action/pull/1124)
|
||||
- Update default CodeQL bundle version to 2.10.0. [#1123](https://github.com/github/codeql-action/pull/1123)
|
||||
|
||||
## 2.1.14 - 22 Jun 2022
|
||||
|
|
|
|||
|
|
@ -10,9 +10,34 @@ inputs:
|
|||
description: The languages to be analysed
|
||||
required: false
|
||||
token:
|
||||
description: GitHub token to use for authenticating with this instance of GitHub. To download custom packs from multiple registries, use the registries input.
|
||||
default: ${{ github.token }}
|
||||
required: false
|
||||
registries:
|
||||
description: |
|
||||
Use this input only when you need to download CodeQL packages from another instance of GitHub. If you only need to download packages from this GitHub instance, use the token input instead.
|
||||
|
||||
A YAML string that defines the list of GitHub container registries to use for downloading packs. The string is in the following form (the | is required on the first line):
|
||||
|
||||
registries: |
|
||||
- url: https://containers.GHEHOSTNAME1/v2/
|
||||
packages:
|
||||
- my-company/*
|
||||
- my-company2/*
|
||||
token: \$\{{ secrets.GHEHOSTNAME1_TOKEN }}
|
||||
|
||||
- url: https://ghcr.io/v2/
|
||||
packages: */*
|
||||
token: \$\{{ secrets.GHCR_TOKEN }}
|
||||
|
||||
The `url` property contains the URL to the container registry you want to connect to.
|
||||
|
||||
The `packages` property contains a single glob string or a list of glob strings, specifying which packages should be retrieved from this particular container registry. Order is important. Earlier entries will match before later entries.
|
||||
|
||||
The `token` property contains a connection token for this registry. required: false
|
||||
matrix:
|
||||
default: ${{ toJson(matrix) }}
|
||||
required: false
|
||||
config-file:
|
||||
description: Path of the config file to use
|
||||
required: false
|
||||
|
|
@ -32,7 +57,7 @@ inputs:
|
|||
analyses, you must specify packs in the codeql-config.yml file.
|
||||
required: false
|
||||
external-repository-token:
|
||||
description: A token for fetching external config files and queries if they reside in a private repository.
|
||||
description: A token for fetching external config files and queries if they reside in a private repository in the same GitHub instance that is running this action.
|
||||
required: false
|
||||
setup-python-dependencies:
|
||||
description: Try to auto-install your python dependencies
|
||||
|
|
@ -82,4 +107,4 @@ outputs:
|
|||
runs:
|
||||
using: 'node16'
|
||||
main: '../lib/init-action.js'
|
||||
post: '../lib/init-action-post.js'
|
||||
post: '../lib/init-action-post.js'
|
||||
|
|
|
|||
12
lib/codeql.js
generated
12
lib/codeql.js
generated
|
|
@ -22,7 +22,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getExtraOptions = exports.getCodeQLForTesting = exports.getCachedCodeQL = exports.setCodeQL = exports.getCodeQL = exports.convertToSemVer = exports.getCodeQLURLVersion = exports.setupCodeQL = exports.getCodeQLActionRepository = exports.CODEQL_VERSION_BETTER_RESOLVE_LANGUAGES = exports.CODEQL_VERSION_ML_POWERED_QUERIES_WINDOWS = exports.CODEQL_VERSION_NEW_TRACING = exports.CODEQL_VERSION_CONFIG_FILES = exports.CODEQL_VERSION_ML_POWERED_QUERIES = exports.CODEQL_VERSION_COUNTS_LINES = exports.CODEQL_DEFAULT_ACTION_REPOSITORY = exports.CommandInvocationError = void 0;
|
||||
exports.getExtraOptions = exports.getCodeQLForTesting = exports.getCachedCodeQL = exports.setCodeQL = exports.getCodeQL = exports.convertToSemVer = exports.getCodeQLURLVersion = exports.setupCodeQL = exports.getCodeQLActionRepository = exports.CODEQL_VERSION_BETTER_RESOLVE_LANGUAGES = exports.CODEQL_VERSION_ML_POWERED_QUERIES_WINDOWS = exports.CODEQL_VERSION_NEW_TRACING = exports.CODEQL_VERSION_GHES_PACK_DOWNLOAD = exports.CODEQL_VERSION_CONFIG_FILES = exports.CODEQL_VERSION_ML_POWERED_QUERIES = exports.CODEQL_VERSION_COUNTS_LINES = exports.CODEQL_DEFAULT_ACTION_REPOSITORY = exports.CommandInvocationError = void 0;
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||
|
|
@ -83,6 +83,7 @@ exports.CODEQL_VERSION_ML_POWERED_QUERIES = "2.7.5";
|
|||
const CODEQL_VERSION_LUA_TRACER_CONFIG = "2.10.0";
|
||||
exports.CODEQL_VERSION_CONFIG_FILES = "2.10.1";
|
||||
const CODEQL_VERSION_LUA_TRACING_GO_WINDOWS_FIXED = "2.10.4";
|
||||
exports.CODEQL_VERSION_GHES_PACK_DOWNLOAD = "2.10.4";
|
||||
/**
|
||||
* This variable controls using the new style of tracing from the CodeQL
|
||||
* CLI. In particular, with versions above this we will use both indirect
|
||||
|
|
@ -736,11 +737,18 @@ async function getCodeQLForCmd(cmd, checkVersion) {
|
|||
* If no version is specified, then the latest version is
|
||||
* downloaded. The check to determine what the latest version is is done
|
||||
* each time this package is requested.
|
||||
*
|
||||
* Optionally, a `qlconfigFile` is included. If used, then this file
|
||||
* is used to determine which registry each pack is downloaded from.
|
||||
*/
|
||||
async packDownload(packs) {
|
||||
async packDownload(packs, qlconfigFile) {
|
||||
const qlconfigArg = qlconfigFile
|
||||
? [`--qlconfig-file=${qlconfigFile}`]
|
||||
: [];
|
||||
const codeqlArgs = [
|
||||
"pack",
|
||||
"download",
|
||||
...qlconfigArg,
|
||||
"--format=json",
|
||||
"--resolve-query-specs",
|
||||
...getExtraOptionsFromEnv(["pack", "download"]),
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
2
lib/codeql.test.js
generated
2
lib/codeql.test.js
generated
|
|
@ -45,11 +45,13 @@ const sampleApiDetails = {
|
|||
auth: "token",
|
||||
url: "https://github.com",
|
||||
apiURL: undefined,
|
||||
registriesAuthTokens: undefined,
|
||||
};
|
||||
const sampleGHAEApiDetails = {
|
||||
auth: "token",
|
||||
url: "https://example.githubenterprise.com",
|
||||
apiURL: undefined,
|
||||
registriesAuthTokens: undefined,
|
||||
};
|
||||
let stubConfig;
|
||||
ava_1.default.beforeEach(() => {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
121
lib/config-utils.js
generated
121
lib/config-utils.js
generated
|
|
@ -883,7 +883,7 @@ function dbLocationOrDefault(dbLocation, tempDir) {
|
|||
* 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.
|
||||
*/
|
||||
async function initConfig(languagesInput, queriesInput, packsInput, configFile, dbLocation, trapCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeQL, workspacePath, gitHubVersion, apiDetails, featureFlags, logger) {
|
||||
async function initConfig(languagesInput, queriesInput, packsInput, registriesInput, configFile, dbLocation, trapCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeQL, workspacePath, gitHubVersion, apiDetails, featureFlags, logger) {
|
||||
var _a, _b, _c;
|
||||
let config;
|
||||
// If no config file was provided create an empty one
|
||||
|
|
@ -909,13 +909,24 @@ async function initConfig(languagesInput, queriesInput, packsInput, configFile,
|
|||
// happen in the CLI during the `database init` command, so no need
|
||||
// to download them here.
|
||||
if (!(await (0, util_1.useCodeScanningConfigInCli)(codeQL))) {
|
||||
await downloadPacks(codeQL, config.languages, config.packs, logger);
|
||||
const registries = parseRegistries(registriesInput);
|
||||
await downloadPacks(codeQL, config.languages, config.packs, registries, apiDetails, config.tempDir, logger);
|
||||
}
|
||||
// Save the config so we can easily access it again in the future
|
||||
await saveConfig(config, logger);
|
||||
return config;
|
||||
}
|
||||
exports.initConfig = initConfig;
|
||||
function parseRegistries(registriesInput) {
|
||||
try {
|
||||
return registriesInput
|
||||
? yaml.load(registriesInput)
|
||||
: undefined;
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error("Invalid registries input. Must be a YAML string.");
|
||||
}
|
||||
}
|
||||
function isLocal(configPath) {
|
||||
// If the path starts with ./, look locally
|
||||
if (configPath.indexOf("./") === 0) {
|
||||
|
|
@ -995,27 +1006,95 @@ async function getConfig(tempDir, logger) {
|
|||
return JSON.parse(configString);
|
||||
}
|
||||
exports.getConfig = getConfig;
|
||||
async function downloadPacks(codeQL, languages, packs, logger) {
|
||||
let numPacksDownloaded = 0;
|
||||
logger.startGroup("Downloading packs");
|
||||
for (const language of languages) {
|
||||
const packsWithVersion = packs[language];
|
||||
if (packsWithVersion === null || packsWithVersion === void 0 ? void 0 : packsWithVersion.length) {
|
||||
logger.info(`Downloading custom packs for ${language}`);
|
||||
const results = await codeQL.packDownload(packsWithVersion);
|
||||
numPacksDownloaded += results.packs.length;
|
||||
logger.info(`Downloaded packs: ${results.packs
|
||||
.map((r) => `${r.name}@${r.version || "latest"}`)
|
||||
.join(", ")}`);
|
||||
async function downloadPacks(codeQL, languages, packs, registries, apiDetails, tmpDir, logger) {
|
||||
let qlconfigFile;
|
||||
let registriesAuthTokens;
|
||||
if (registries) {
|
||||
if (!(await (0, util_1.codeQlVersionAbove)(codeQL, codeql_1.CODEQL_VERSION_GHES_PACK_DOWNLOAD))) {
|
||||
throw new Error(`'registries' input is not supported on CodeQL versions less than ${codeql_1.CODEQL_VERSION_GHES_PACK_DOWNLOAD}.`);
|
||||
}
|
||||
// generate a qlconfig.yml file to hold the registry configs.
|
||||
const qlconfig = createRegistriesBlock(registries);
|
||||
qlconfigFile = path.join(tmpDir, "qlconfig.yml");
|
||||
fs.writeFileSync(qlconfigFile, yaml.dump(qlconfig), "utf8");
|
||||
registriesAuthTokens = registries
|
||||
.map((registry) => `${registry.url}=${registry.token}`)
|
||||
.join(",");
|
||||
}
|
||||
if (numPacksDownloaded > 0) {
|
||||
logger.info(`Downloaded ${numPacksDownloaded} ${packs === 1 ? "pack" : "packs"}`);
|
||||
}
|
||||
else {
|
||||
logger.info("No packs to download");
|
||||
}
|
||||
logger.endGroup();
|
||||
await wrapEnvironment({
|
||||
GITHUB_TOKEN: apiDetails.auth,
|
||||
CODEQL_REGISTRIES_AUTH: registriesAuthTokens,
|
||||
}, async () => {
|
||||
let numPacksDownloaded = 0;
|
||||
logger.startGroup("Downloading packs");
|
||||
for (const language of languages) {
|
||||
const packsWithVersion = packs[language];
|
||||
if (packsWithVersion === null || packsWithVersion === void 0 ? void 0 : packsWithVersion.length) {
|
||||
logger.info(`Downloading custom packs for ${language}`);
|
||||
const results = await codeQL.packDownload(packsWithVersion, qlconfigFile);
|
||||
numPacksDownloaded += results.packs.length;
|
||||
logger.info(`Downloaded: ${results.packs
|
||||
.map((r) => `${r.name}@${r.version || "latest"}`)
|
||||
.join(", ")}`);
|
||||
}
|
||||
}
|
||||
if (numPacksDownloaded > 0) {
|
||||
logger.info(`Downloaded ${numPacksDownloaded} ${packs === 1 ? "pack" : "packs"}`);
|
||||
}
|
||||
else {
|
||||
logger.info("No packs to download");
|
||||
}
|
||||
logger.endGroup();
|
||||
});
|
||||
}
|
||||
exports.downloadPacks = downloadPacks;
|
||||
function createRegistriesBlock(registries) {
|
||||
if (!Array.isArray(registries) ||
|
||||
registries.some((r) => !r.url || !r.packages)) {
|
||||
throw new Error("Invalid 'registries' input. Must be an array of objects with 'url' and 'packages' properties.");
|
||||
}
|
||||
// be sure to remove the `token` field from the registry before writing it to disk.
|
||||
const safeRegistries = registries.map((registry) => ({
|
||||
// ensure the url ends with a slash to avoid a bug in the CLI 2.10.4
|
||||
url: !(registry === null || registry === void 0 ? void 0 : registry.url.endsWith("/")) ? `${registry.url}/` : registry.url,
|
||||
packages: registry.packages,
|
||||
}));
|
||||
const qlconfig = {
|
||||
registries: safeRegistries,
|
||||
};
|
||||
return qlconfig;
|
||||
}
|
||||
/**
|
||||
* Create a temporary environment based on the existing environment and overridden
|
||||
* by the given environment variables that are passed in as arguments.
|
||||
*
|
||||
* Use this new environment in the context of the given operation. After completing
|
||||
* the operation, restore the original environment.
|
||||
*
|
||||
* This function does not support un-setting environment variables.
|
||||
*
|
||||
* @param env
|
||||
* @param operation
|
||||
*/
|
||||
async function wrapEnvironment(env, operation) {
|
||||
// Remember the original env
|
||||
const oldEnv = { ...process.env };
|
||||
// Set the new env
|
||||
for (const [key, value] of Object.entries(env)) {
|
||||
// Ignore undefined keys
|
||||
if (value !== undefined) {
|
||||
process.env[key] = value;
|
||||
}
|
||||
}
|
||||
try {
|
||||
// Run the operation
|
||||
await operation();
|
||||
}
|
||||
finally {
|
||||
// Restore the old env
|
||||
for (const [key, value] of Object.entries(oldEnv)) {
|
||||
process.env[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=config-utils.js.map
|
||||
File diff suppressed because one or more lines are too long
207
lib/config-utils.test.js
generated
207
lib/config-utils.test.js
generated
|
|
@ -26,6 +26,7 @@ const fs = __importStar(require("fs"));
|
|||
const path = __importStar(require("path"));
|
||||
const github = __importStar(require("@actions/github"));
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const yaml = __importStar(require("js-yaml"));
|
||||
const sinon = __importStar(require("sinon"));
|
||||
const api = __importStar(require("./api-client"));
|
||||
const codeql_1 = require("./codeql");
|
||||
|
|
@ -41,6 +42,7 @@ const sampleApiDetails = {
|
|||
externalRepoAuth: "token",
|
||||
url: "https://github.example.com",
|
||||
apiURL: undefined,
|
||||
registriesAuthTokens: undefined,
|
||||
};
|
||||
const gitHubVersion = { type: util.GitHubVariant.DOTCOM };
|
||||
// Returns the filepath of the newly-created file
|
||||
|
|
@ -92,7 +94,7 @@ function mockListLanguages(languages) {
|
|||
return { packs: [] };
|
||||
},
|
||||
});
|
||||
const config = await configUtils.initConfig(languages, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), logger);
|
||||
const config = await configUtils.initConfig(languages, undefined, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), logger);
|
||||
t.deepEqual(config, await configUtils.getDefaultConfig(languages, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), logger));
|
||||
});
|
||||
});
|
||||
|
|
@ -118,7 +120,7 @@ function mockListLanguages(languages) {
|
|||
t.false(fs.existsSync(configUtils.getPathToParsedConfigFile(tmpDir)));
|
||||
// Sanity check that getConfig returns undefined before we have called initConfig
|
||||
t.deepEqual(await configUtils.getConfig(tmpDir, logger), undefined);
|
||||
const config1 = await configUtils.initConfig("javascript,python", undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), logger);
|
||||
const config1 = await configUtils.initConfig("javascript,python", undefined, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), logger);
|
||||
// The saved config file should now exist
|
||||
t.true(fs.existsSync(configUtils.getPathToParsedConfigFile(tmpDir)));
|
||||
// And that same newly-initialised config should now be returned by getConfig
|
||||
|
|
@ -134,7 +136,7 @@ function mockListLanguages(languages) {
|
|||
(0, ava_1.default)("load input outside of workspace", async (t) => {
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
try {
|
||||
await configUtils.initConfig(undefined, undefined, undefined, "../input", undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
await configUtils.initConfig(undefined, undefined, undefined, undefined, "../input", undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
throw new Error("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
|
|
@ -147,7 +149,7 @@ function mockListLanguages(languages) {
|
|||
// no filename given, just a repo
|
||||
const configFile = "octo-org/codeql-config@main";
|
||||
try {
|
||||
await configUtils.initConfig(undefined, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
await configUtils.initConfig(undefined, undefined, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
throw new Error("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
|
|
@ -161,7 +163,7 @@ function mockListLanguages(languages) {
|
|||
const configFile = "input";
|
||||
t.false(fs.existsSync(path.join(tmpDir, configFile)));
|
||||
try {
|
||||
await configUtils.initConfig(languages, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
await configUtils.initConfig(languages, undefined, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
throw new Error("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
|
|
@ -237,7 +239,7 @@ function mockListLanguages(languages) {
|
|||
};
|
||||
const languages = "javascript";
|
||||
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
||||
const actualConfig = await configUtils.initConfig(languages, undefined, undefined, configFilePath, undefined, false, false, "my-artifact", "my-db", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
const actualConfig = await configUtils.initConfig(languages, undefined, undefined, undefined, configFilePath, undefined, false, false, "my-artifact", "my-db", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
// Should exactly equal the object we constructed earlier
|
||||
t.deepEqual(actualConfig, expectedConfig);
|
||||
});
|
||||
|
|
@ -276,7 +278,7 @@ function mockListLanguages(languages) {
|
|||
fs.mkdirSync(path.join(tmpDir, "foo"));
|
||||
const languages = "javascript";
|
||||
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
||||
await configUtils.initConfig(languages, undefined, undefined, configFilePath, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
await configUtils.initConfig(languages, undefined, undefined, undefined, configFilePath, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
// Check resolve queries was called correctly
|
||||
t.deepEqual(resolveQueriesArgs.length, 1);
|
||||
t.deepEqual(resolveQueriesArgs[0].queries, [
|
||||
|
|
@ -322,7 +324,7 @@ function queriesToResolvedQueryForm(queries) {
|
|||
},
|
||||
});
|
||||
const languages = "javascript";
|
||||
const config = await configUtils.initConfig(languages, undefined, undefined, configFilePath, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
const config = await configUtils.initConfig(languages, undefined, undefined, undefined, configFilePath, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
// Check resolveQueries was called correctly
|
||||
// It'll be called once for the default queries
|
||||
// and once for `./foo` from the config file.
|
||||
|
|
@ -358,7 +360,7 @@ function queriesToResolvedQueryForm(queries) {
|
|||
},
|
||||
});
|
||||
const languages = "javascript";
|
||||
const config = await configUtils.initConfig(languages, testQueries, undefined, configFilePath, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, configFilePath, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
// Check resolveQueries was called correctly
|
||||
// It'll be called once for the default queries and once for `./override`,
|
||||
// but won't be called for './foo' from the config file.
|
||||
|
|
@ -393,7 +395,7 @@ function queriesToResolvedQueryForm(queries) {
|
|||
},
|
||||
});
|
||||
const languages = "javascript";
|
||||
const config = await configUtils.initConfig(languages, testQueries, undefined, configFilePath, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, configFilePath, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
// Check resolveQueries was called correctly
|
||||
// It'll be called once for `./workflow-query`,
|
||||
// but won't be called for the default one since that was disabled
|
||||
|
|
@ -422,7 +424,7 @@ function queriesToResolvedQueryForm(queries) {
|
|||
},
|
||||
});
|
||||
const languages = "javascript";
|
||||
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
// Check resolveQueries was called correctly:
|
||||
// It'll be called once for the default queries,
|
||||
// and then once for each of the two queries from the workflow
|
||||
|
|
@ -464,7 +466,7 @@ function queriesToResolvedQueryForm(queries) {
|
|||
},
|
||||
});
|
||||
const languages = "javascript";
|
||||
const config = await configUtils.initConfig(languages, testQueries, undefined, configFilePath, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, configFilePath, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
// Check resolveQueries was called correctly
|
||||
// It'll be called once for the default queries,
|
||||
// once for each of additional1 and additional2,
|
||||
|
|
@ -506,7 +508,7 @@ function queriesToResolvedQueryForm(queries) {
|
|||
},
|
||||
});
|
||||
try {
|
||||
await configUtils.initConfig(languages, queries, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
await configUtils.initConfig(languages, queries, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
t.fail("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
|
|
@ -552,7 +554,7 @@ function queriesToResolvedQueryForm(queries) {
|
|||
fs.mkdirSync(path.join(tmpDir, "foo/bar/dev"), { recursive: true });
|
||||
const configFile = "octo-org/codeql-config/config.yaml@main";
|
||||
const languages = "javascript";
|
||||
await configUtils.initConfig(languages, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
await configUtils.initConfig(languages, undefined, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
t.assert(spyGetContents.called);
|
||||
});
|
||||
});
|
||||
|
|
@ -562,7 +564,7 @@ function queriesToResolvedQueryForm(queries) {
|
|||
mockGetContents(dummyResponse);
|
||||
const repoReference = "octo-org/codeql-config/config.yaml@main";
|
||||
try {
|
||||
await configUtils.initConfig(undefined, undefined, undefined, repoReference, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
await configUtils.initConfig(undefined, undefined, undefined, undefined, repoReference, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
throw new Error("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
|
|
@ -578,7 +580,7 @@ function queriesToResolvedQueryForm(queries) {
|
|||
mockGetContents(dummyResponse);
|
||||
const repoReference = "octo-org/codeql-config/config.yaml@main";
|
||||
try {
|
||||
await configUtils.initConfig(undefined, undefined, undefined, repoReference, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
await configUtils.initConfig(undefined, undefined, undefined, undefined, repoReference, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
throw new Error("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
|
|
@ -598,7 +600,7 @@ function queriesToResolvedQueryForm(queries) {
|
|||
},
|
||||
});
|
||||
try {
|
||||
await configUtils.initConfig(undefined, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
await configUtils.initConfig(undefined, undefined, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
throw new Error("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
|
|
@ -610,7 +612,7 @@ function queriesToResolvedQueryForm(queries) {
|
|||
return await util.withTmpDir(async (tmpDir) => {
|
||||
const languages = "rubbish,english";
|
||||
try {
|
||||
await configUtils.initConfig(languages, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
await configUtils.initConfig(languages, undefined, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
throw new Error("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
|
|
@ -641,7 +643,7 @@ function queriesToResolvedQueryForm(queries) {
|
|||
const configFile = path.join(tmpDir, "codeql-config.yaml");
|
||||
fs.writeFileSync(configFile, inputFileContents);
|
||||
const languages = "javascript";
|
||||
const { packs } = await configUtils.initConfig(languages, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
const { packs } = await configUtils.initConfig(languages, undefined, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
t.deepEqual(packs, {
|
||||
[languages_1.Language.javascript]: ["a/b@1.2.3"],
|
||||
});
|
||||
|
|
@ -678,7 +680,7 @@ function queriesToResolvedQueryForm(queries) {
|
|||
fs.writeFileSync(configFile, inputFileContents);
|
||||
fs.mkdirSync(path.join(tmpDir, "foo"));
|
||||
const languages = "javascript,python,cpp";
|
||||
const { packs, queries } = await configUtils.initConfig(languages, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example" }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
const { packs, queries } = await configUtils.initConfig(languages, undefined, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example" }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
t.deepEqual(packs, {
|
||||
[languages_1.Language.javascript]: ["a/b@1.2.3"],
|
||||
[languages_1.Language.python]: ["c/d@1.2.3"],
|
||||
|
|
@ -724,7 +726,7 @@ function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGen
|
|||
const inputFile = path.join(tmpDir, configFile);
|
||||
fs.writeFileSync(inputFile, inputFileContents, "utf8");
|
||||
try {
|
||||
await configUtils.initConfig(languages, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
await configUtils.initConfig(languages, undefined, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)([]), (0, logging_1.getRunnerLogger)(true));
|
||||
throw new Error("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
|
|
@ -985,7 +987,7 @@ const mlPoweredQueriesMacro = ava_1.default.macro({
|
|||
return { packs: [] };
|
||||
},
|
||||
});
|
||||
const { packs } = await configUtils.initConfig("javascript", queriesInput, packsInput, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)(isMlPoweredQueriesFlagEnabled
|
||||
const { packs } = await configUtils.initConfig("javascript", queriesInput, packsInput, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, feature_flags_1.createFeatureFlags)(isMlPoweredQueriesFlagEnabled
|
||||
? [feature_flags_1.FeatureFlag.MlPoweredQueriesEnabled]
|
||||
: []), (0, logging_1.getRunnerLogger)(true));
|
||||
if (expectedVersionString !== undefined) {
|
||||
|
|
@ -1087,24 +1089,149 @@ const calculateAugmentationErrorMacro = ava_1.default.macro({
|
|||
(0, ava_1.default)(calculateAugmentationErrorMacro, "Packs input with multiple languages", " + a/b, c/d ", undefined, [languages_1.Language.javascript, languages_1.Language.java], /Cannot specify a 'packs' input in a multi-language analysis/);
|
||||
(0, ava_1.default)(calculateAugmentationErrorMacro, "Packs input with no languages", " + a/b, c/d ", undefined, [], /No languages specified/);
|
||||
(0, ava_1.default)(calculateAugmentationErrorMacro, "Invalid packs", " a-pack-without-a-scope ", undefined, [languages_1.Language.javascript], /"a-pack-without-a-scope" is not a valid pack/);
|
||||
(0, ava_1.default)("downloadPacks", async (t) => {
|
||||
const packDownloadStub = sinon.stub();
|
||||
packDownloadStub.callsFake((packs) => ({
|
||||
packs,
|
||||
}));
|
||||
const codeQL = (0, codeql_1.setCodeQL)({
|
||||
packDownload: packDownloadStub,
|
||||
(0, ava_1.default)("downloadPacks-no-registries", async (t) => {
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
const packDownloadStub = sinon.stub();
|
||||
packDownloadStub.callsFake((packs) => ({
|
||||
packs,
|
||||
}));
|
||||
const codeQL = (0, codeql_1.setCodeQL)({
|
||||
packDownload: packDownloadStub,
|
||||
});
|
||||
const logger = (0, logging_1.getRunnerLogger)(true);
|
||||
// packs are supplied for go, java, and python
|
||||
// analyzed languages are java, javascript, and python
|
||||
await configUtils.downloadPacks(codeQL, [languages_1.Language.javascript, languages_1.Language.java, languages_1.Language.python], {
|
||||
java: ["a", "b"],
|
||||
go: ["c", "d"],
|
||||
python: ["e", "f"],
|
||||
}, undefined, // registries
|
||||
sampleApiDetails, tmpDir, logger);
|
||||
// Expecting packs to be downloaded once for java and once for python
|
||||
t.deepEqual(packDownloadStub.callCount, 2);
|
||||
// no config file was created, so pass `undefined` as the config file path
|
||||
t.deepEqual(packDownloadStub.firstCall.args, [["a", "b"], undefined]);
|
||||
t.deepEqual(packDownloadStub.secondCall.args, [["e", "f"], undefined]);
|
||||
});
|
||||
});
|
||||
(0, ava_1.default)("downloadPacks-with-registries", async (t) => {
|
||||
// same thing, but this time include a registries block and
|
||||
// associated env vars
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
process.env.GITHUB_TOKEN = "not-a-token";
|
||||
process.env.CODEQL_REGISTRIES_AUTH = "not-a-registries-auth";
|
||||
const logger = (0, logging_1.getRunnerLogger)(true);
|
||||
const registries = [
|
||||
{
|
||||
// no slash
|
||||
url: "http://ghcr.io",
|
||||
packages: ["codeql/*", "dsp-testing/*"],
|
||||
token: "not-a-token",
|
||||
},
|
||||
{
|
||||
// with slash
|
||||
url: "https://containers.GHEHOSTNAME1/v2/",
|
||||
packages: "semmle/*",
|
||||
token: "still-not-a-token",
|
||||
},
|
||||
];
|
||||
// append a slash to the first url
|
||||
const expectedRegistries = registries.map((r, i) => ({
|
||||
packages: r.packages,
|
||||
url: i === 0 ? `${r.url}/` : r.url,
|
||||
}));
|
||||
const expectedConfigFile = path.join(tmpDir, "qlconfig.yml");
|
||||
const packDownloadStub = sinon.stub();
|
||||
packDownloadStub.callsFake((packs, configFile) => {
|
||||
t.deepEqual(configFile, expectedConfigFile);
|
||||
// verify the env vars were set correctly
|
||||
t.deepEqual(process.env.GITHUB_TOKEN, sampleApiDetails.auth);
|
||||
t.deepEqual(process.env.CODEQL_REGISTRIES_AUTH, "http://ghcr.io=not-a-token,https://containers.GHEHOSTNAME1/v2/=still-not-a-token");
|
||||
// verify the config file contents were set correctly
|
||||
const config = yaml.load(fs.readFileSync(configFile, "utf8"));
|
||||
t.deepEqual(config.registries, expectedRegistries);
|
||||
return {
|
||||
packs,
|
||||
};
|
||||
});
|
||||
const codeQL = (0, codeql_1.setCodeQL)({
|
||||
packDownload: packDownloadStub,
|
||||
getVersion: () => Promise.resolve("2.10.5"),
|
||||
});
|
||||
// packs are supplied for go, java, and python
|
||||
// analyzed languages are java, javascript, and python
|
||||
await configUtils.downloadPacks(codeQL, [languages_1.Language.javascript, languages_1.Language.java, languages_1.Language.python], {
|
||||
java: ["a", "b"],
|
||||
go: ["c", "d"],
|
||||
python: ["e", "f"],
|
||||
}, registries, sampleApiDetails, tmpDir, logger);
|
||||
// Same packs are downloaded as in previous test
|
||||
t.deepEqual(packDownloadStub.callCount, 2);
|
||||
t.deepEqual(packDownloadStub.firstCall.args, [
|
||||
["a", "b"],
|
||||
expectedConfigFile,
|
||||
]);
|
||||
t.deepEqual(packDownloadStub.secondCall.args, [
|
||||
["e", "f"],
|
||||
expectedConfigFile,
|
||||
]);
|
||||
// Verify that the env vars were unset.
|
||||
t.deepEqual(process.env.GITHUB_TOKEN, "not-a-token");
|
||||
t.deepEqual(process.env.CODEQL_REGISTRIES_AUTH, "not-a-registries-auth");
|
||||
});
|
||||
});
|
||||
(0, ava_1.default)("downloadPacks-with-registries fails on 2.10.3", async (t) => {
|
||||
// same thing, but this time include a registries block and
|
||||
// associated env vars
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
process.env.GITHUB_TOKEN = "not-a-token";
|
||||
process.env.CODEQL_REGISTRIES_AUTH = "not-a-registries-auth";
|
||||
const logger = (0, logging_1.getRunnerLogger)(true);
|
||||
const registries = [
|
||||
{
|
||||
url: "http://ghcr.io",
|
||||
packages: ["codeql/*", "dsp-testing/*"],
|
||||
token: "not-a-token",
|
||||
},
|
||||
{
|
||||
url: "https://containers.GHEHOSTNAME1/v2/",
|
||||
packages: "semmle/*",
|
||||
token: "still-not-a-token",
|
||||
},
|
||||
];
|
||||
const codeQL = (0, codeql_1.setCodeQL)({
|
||||
getVersion: () => Promise.resolve("2.10.3"),
|
||||
});
|
||||
await t.throwsAsync(async () => {
|
||||
return await configUtils.downloadPacks(codeQL, [languages_1.Language.javascript, languages_1.Language.java, languages_1.Language.python], {}, registries, sampleApiDetails, tmpDir, logger);
|
||||
}, { instanceOf: Error }, "'registries' input is not supported on CodeQL versions less than 2.10.4.");
|
||||
});
|
||||
});
|
||||
(0, ava_1.default)("downloadPacks-with-registries fails with invalid registries block", async (t) => {
|
||||
// same thing, but this time include a registries block and
|
||||
// associated env vars
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
process.env.GITHUB_TOKEN = "not-a-token";
|
||||
process.env.CODEQL_REGISTRIES_AUTH = "not-a-registries-auth";
|
||||
const logger = (0, logging_1.getRunnerLogger)(true);
|
||||
const registries = [
|
||||
{
|
||||
// missing url property
|
||||
packages: ["codeql/*", "dsp-testing/*"],
|
||||
token: "not-a-token",
|
||||
},
|
||||
{
|
||||
url: "https://containers.GHEHOSTNAME1/v2/",
|
||||
packages: "semmle/*",
|
||||
token: "still-not-a-token",
|
||||
},
|
||||
];
|
||||
const codeQL = (0, codeql_1.setCodeQL)({
|
||||
getVersion: () => Promise.resolve("2.10.4"),
|
||||
});
|
||||
await t.throwsAsync(async () => {
|
||||
return await configUtils.downloadPacks(codeQL, [languages_1.Language.javascript, languages_1.Language.java, languages_1.Language.python], {}, registries, sampleApiDetails, tmpDir, logger);
|
||||
}, { instanceOf: Error }, "Invalid 'registries' input. Must be an array of objects with 'url' and 'packages' properties.");
|
||||
});
|
||||
const logger = (0, logging_1.getRunnerLogger)(true);
|
||||
// packs are supplied for go, java, and python
|
||||
// analyzed languages are java, javascript, and python
|
||||
await configUtils.downloadPacks(codeQL, [languages_1.Language.javascript, languages_1.Language.java, languages_1.Language.python], {
|
||||
java: ["a", "b"],
|
||||
go: ["c", "d"],
|
||||
python: ["e", "f"],
|
||||
}, logger);
|
||||
t.deepEqual(packDownloadStub.callCount, 2);
|
||||
t.deepEqual(packDownloadStub.firstCall.args, [["a", "b"]]);
|
||||
t.deepEqual(packDownloadStub.secondCall.args, [["e", "f"]]);
|
||||
});
|
||||
//# sourceMappingURL=config-utils.test.js.map
|
||||
File diff suppressed because one or more lines are too long
2
lib/init-action.js
generated
2
lib/init-action.js
generated
|
|
@ -98,7 +98,7 @@ async function run() {
|
|||
codeql = initCodeQLResult.codeql;
|
||||
toolsVersion = initCodeQLResult.toolsVersion;
|
||||
await (0, util_1.enrichEnvironment)(util_1.Mode.actions, codeql);
|
||||
config = await (0, init_1.initConfig)((0, actions_util_1.getOptionalInput)("languages"), (0, actions_util_1.getOptionalInput)("queries"), (0, actions_util_1.getOptionalInput)("packs"), (0, actions_util_1.getOptionalInput)("config-file"), (0, actions_util_1.getOptionalInput)("db-location"), await getTrapCachingEnabled(featureFlags),
|
||||
config = await (0, init_1.initConfig)((0, actions_util_1.getOptionalInput)("languages"), (0, actions_util_1.getOptionalInput)("queries"), (0, actions_util_1.getOptionalInput)("packs"), (0, actions_util_1.getOptionalInput)("registries"), (0, actions_util_1.getOptionalInput)("config-file"), (0, actions_util_1.getOptionalInput)("db-location"), await getTrapCachingEnabled(featureFlags),
|
||||
// Debug mode is enabled if:
|
||||
// - The `init` Action is passed `debug: true`.
|
||||
// - Actions step debugging is enabled (e.g. by [enabling debug logging for a rerun](https://docs.github.com/en/actions/managing-workflow-runs/re-running-workflows-and-jobs#re-running-all-the-jobs-in-a-workflow),
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
4
lib/init.js
generated
4
lib/init.js
generated
|
|
@ -38,9 +38,9 @@ async function initCodeQL(codeqlURL, apiDetails, tempDir, variant, featureFlags,
|
|||
return { codeql, toolsVersion };
|
||||
}
|
||||
exports.initCodeQL = initCodeQL;
|
||||
async function initConfig(languagesInput, queriesInput, packsInput, configFile, dbLocation, trapCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeQL, workspacePath, gitHubVersion, apiDetails, featureFlags, logger) {
|
||||
async function initConfig(languagesInput, queriesInput, packsInput, registriesInput, configFile, dbLocation, trapCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeQL, workspacePath, gitHubVersion, apiDetails, featureFlags, logger) {
|
||||
logger.startGroup("Load language configuration");
|
||||
const config = await configUtils.initConfig(languagesInput, queriesInput, packsInput, configFile, dbLocation, trapCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeQL, workspacePath, gitHubVersion, apiDetails, featureFlags, logger);
|
||||
const config = await configUtils.initConfig(languagesInput, queriesInput, packsInput, registriesInput, configFile, dbLocation, trapCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeQL, workspacePath, gitHubVersion, apiDetails, featureFlags, logger);
|
||||
analysisPaths.printPathFiltersWarning(config, logger);
|
||||
logger.endGroup();
|
||||
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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"}
|
||||
3
lib/runner.js
generated
3
lib/runner.js
generated
|
|
@ -156,7 +156,8 @@ program
|
|||
}
|
||||
await (0, util_1.enrichEnvironment)(util_1.Mode.runner, codeql);
|
||||
const workspacePath = checkoutPath;
|
||||
const config = await (0, init_1.initConfig)(cmd.languages, cmd.queries, cmd.packs, cmd.configFile, undefined, false, false, "", "", (0, repository_1.parseRepositoryNwo)(cmd.repository), tempDir, codeql, workspacePath, gitHubVersion, apiDetails, (0, feature_flags_1.createFeatureFlags)([]), logger);
|
||||
const config = await (0, init_1.initConfig)(cmd.languages, cmd.queries, cmd.packs, undefined, // we won't support registries in the runner
|
||||
cmd.configFile, undefined, false, false, "", "", (0, repository_1.parseRepositoryNwo)(cmd.repository), tempDir, codeql, workspacePath, gitHubVersion, apiDetails, (0, feature_flags_1.createFeatureFlags)([]), logger);
|
||||
const sourceRoot = checkoutPath;
|
||||
const tracerConfig = await (0, init_1.runInit)(codeql, config, sourceRoot, parseTraceProcessName(), parseTraceProcessLevel(), (0, feature_flags_1.createFeatureFlags)([]), logger);
|
||||
if (tracerConfig === undefined) {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
44
pr-checks/checks/init-with-registries.yml
Normal file
44
pr-checks/checks/init-with-registries.yml
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# A test for running the init command with a registries block.
|
||||
# This test does _not_ validate that the action can authenticate
|
||||
# against multiple registries. All it does is validate that the
|
||||
# basic mechanics of multi-registry auth is working.
|
||||
name: "Packaging: Download using registries"
|
||||
description: "Checks that specifying a registries block and associated auth works as expected"
|
||||
versions: ["nightly-latest"] # This feature is not compatible with old CLIs
|
||||
|
||||
steps:
|
||||
- name: Init with registries
|
||||
uses: ./../action/init
|
||||
with:
|
||||
db-location: "${{ runner.temp }}/customDbLocation"
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
config-file: ./.github/codeql/codeql-config-registries.yml
|
||||
languages: javascript
|
||||
registries: |
|
||||
- url: "https://ghcr.io/v2/"
|
||||
packages: "*/*"
|
||||
token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
env:
|
||||
TEST_MODE: true
|
||||
- name: Verify packages installed
|
||||
shell: bash
|
||||
run: |
|
||||
PRIVATE_PACK="$HOME/.codeql/packages/dsp-testing/private-pack"
|
||||
CODEQL_PACK1="$HOME/.codeql/packages/dsp-testing/codeql-pack1"
|
||||
|
||||
if [[ -d $PRIVATE_PACK ]]
|
||||
then
|
||||
echo "$PRIVATE_PACK was installed."
|
||||
else
|
||||
echo "::error $PRIVATE_PACK pack was not installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -d $CODEQL_PACK1 ]]
|
||||
then
|
||||
echo "$CODEQL_PACK1 was installed."
|
||||
else
|
||||
echo "::error $CODEQL_PACK1 pack was not installed."
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -26,12 +26,14 @@ const sampleApiDetails = {
|
|||
auth: "token",
|
||||
url: "https://github.com",
|
||||
apiURL: undefined,
|
||||
registriesAuthTokens: undefined,
|
||||
};
|
||||
|
||||
const sampleGHAEApiDetails = {
|
||||
auth: "token",
|
||||
url: "https://example.githubenterprise.com",
|
||||
apiURL: undefined,
|
||||
registriesAuthTokens: undefined,
|
||||
};
|
||||
|
||||
let stubConfig: Config;
|
||||
|
|
|
|||
|
|
@ -134,7 +134,10 @@ export interface CodeQL {
|
|||
/**
|
||||
* Run 'codeql pack download'.
|
||||
*/
|
||||
packDownload(packs: string[]): Promise<PackDownloadOutput>;
|
||||
packDownload(
|
||||
packs: string[],
|
||||
qlconfigFile: string | undefined
|
||||
): Promise<PackDownloadOutput>;
|
||||
|
||||
/**
|
||||
* Run 'codeql database cleanup'.
|
||||
|
|
@ -252,6 +255,7 @@ export const CODEQL_VERSION_ML_POWERED_QUERIES = "2.7.5";
|
|||
const CODEQL_VERSION_LUA_TRACER_CONFIG = "2.10.0";
|
||||
export const CODEQL_VERSION_CONFIG_FILES = "2.10.1";
|
||||
const CODEQL_VERSION_LUA_TRACING_GO_WINDOWS_FIXED = "2.10.4";
|
||||
export const CODEQL_VERSION_GHES_PACK_DOWNLOAD = "2.10.4";
|
||||
|
||||
/**
|
||||
* This variable controls using the new style of tracing from the CodeQL
|
||||
|
|
@ -1097,11 +1101,22 @@ async function getCodeQLForCmd(
|
|||
* If no version is specified, then the latest version is
|
||||
* downloaded. The check to determine what the latest version is is done
|
||||
* each time this package is requested.
|
||||
*
|
||||
* Optionally, a `qlconfigFile` is included. If used, then this file
|
||||
* is used to determine which registry each pack is downloaded from.
|
||||
*/
|
||||
async packDownload(packs: string[]): Promise<PackDownloadOutput> {
|
||||
async packDownload(
|
||||
packs: string[],
|
||||
qlconfigFile: string | undefined
|
||||
): Promise<PackDownloadOutput> {
|
||||
const qlconfigArg = qlconfigFile
|
||||
? [`--qlconfig-file=${qlconfigFile}`]
|
||||
: ([] as string[]);
|
||||
|
||||
const codeqlArgs = [
|
||||
"pack",
|
||||
"download",
|
||||
...qlconfigArg,
|
||||
"--format=json",
|
||||
"--resolve-query-specs",
|
||||
...getExtraOptionsFromEnv(["pack", "download"]),
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import * as path from "path";
|
|||
|
||||
import * as github from "@actions/github";
|
||||
import test, { ExecutionContext } from "ava";
|
||||
import * as yaml from "js-yaml";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import * as api from "./api-client";
|
||||
|
|
@ -21,6 +22,7 @@ const sampleApiDetails = {
|
|||
externalRepoAuth: "token",
|
||||
url: "https://github.example.com",
|
||||
apiURL: undefined,
|
||||
registriesAuthTokens: undefined,
|
||||
};
|
||||
|
||||
const gitHubVersion = { type: util.GitHubVariant.DOTCOM } as util.GitHubVersion;
|
||||
|
|
@ -89,6 +91,7 @@ test("load empty config", async (t) => {
|
|||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
|
|
@ -159,6 +162,7 @@ test("loading config saves config", async (t) => {
|
|||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
|
|
@ -194,6 +198,7 @@ test("load input outside of workspace", async (t) => {
|
|||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
"../input",
|
||||
undefined,
|
||||
false,
|
||||
|
|
@ -233,6 +238,7 @@ test("load non-local input with invalid repo syntax", async (t) => {
|
|||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
configFile,
|
||||
undefined,
|
||||
false,
|
||||
|
|
@ -273,6 +279,7 @@ test("load non-existent input", async (t) => {
|
|||
languages,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
configFile,
|
||||
undefined,
|
||||
false,
|
||||
|
|
@ -379,6 +386,7 @@ test("load non-empty input", async (t) => {
|
|||
languages,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
configFilePath,
|
||||
undefined,
|
||||
false,
|
||||
|
|
@ -449,6 +457,7 @@ test("Default queries are used", async (t) => {
|
|||
languages,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
configFilePath,
|
||||
undefined,
|
||||
false,
|
||||
|
|
@ -527,6 +536,7 @@ test("Queries can be specified in config file", async (t) => {
|
|||
languages,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
configFilePath,
|
||||
undefined,
|
||||
false,
|
||||
|
|
@ -604,6 +614,7 @@ test("Queries from config file can be overridden in workflow file", async (t) =>
|
|||
languages,
|
||||
testQueries,
|
||||
undefined,
|
||||
undefined,
|
||||
configFilePath,
|
||||
undefined,
|
||||
false,
|
||||
|
|
@ -679,6 +690,7 @@ test("Queries in workflow file can be used in tandem with the 'disable default q
|
|||
languages,
|
||||
testQueries,
|
||||
undefined,
|
||||
undefined,
|
||||
configFilePath,
|
||||
undefined,
|
||||
false,
|
||||
|
|
@ -747,6 +759,7 @@ test("Multiple queries can be specified in workflow file, no config file require
|
|||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
|
|
@ -832,6 +845,7 @@ test("Queries in workflow file can be added to the set of queries without overri
|
|||
languages,
|
||||
testQueries,
|
||||
undefined,
|
||||
undefined,
|
||||
configFilePath,
|
||||
undefined,
|
||||
false,
|
||||
|
|
@ -915,6 +929,7 @@ test("Invalid queries in workflow file handled correctly", async (t) => {
|
|||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
|
|
@ -984,6 +999,7 @@ test("API client used when reading remote config", async (t) => {
|
|||
languages,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
configFile,
|
||||
undefined,
|
||||
false,
|
||||
|
|
@ -1014,6 +1030,7 @@ test("Remote config handles the case where a directory is provided", async (t) =
|
|||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
repoReference,
|
||||
undefined,
|
||||
false,
|
||||
|
|
@ -1052,6 +1069,7 @@ test("Invalid format of remote config handled correctly", async (t) => {
|
|||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
repoReference,
|
||||
undefined,
|
||||
false,
|
||||
|
|
@ -1096,6 +1114,7 @@ test("No detected languages", async (t) => {
|
|||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
|
|
@ -1127,6 +1146,7 @@ test("Unknown languages", async (t) => {
|
|||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
|
|
@ -1181,6 +1201,7 @@ test("Config specifies packages", async (t) => {
|
|||
languages,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
configFile,
|
||||
undefined,
|
||||
false,
|
||||
|
|
@ -1241,6 +1262,7 @@ test("Config specifies packages for multiple languages", async (t) => {
|
|||
languages,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
configFile,
|
||||
undefined,
|
||||
false,
|
||||
|
|
@ -1312,6 +1334,7 @@ function doInvalidInputTest(
|
|||
languages,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
configFile,
|
||||
undefined,
|
||||
false,
|
||||
|
|
@ -1901,6 +1924,7 @@ const mlPoweredQueriesMacro = test.macro({
|
|||
packsInput,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
|
|
@ -2208,30 +2232,209 @@ test(
|
|||
/"a-pack-without-a-scope" is not a valid pack/
|
||||
);
|
||||
|
||||
test("downloadPacks", async (t) => {
|
||||
const packDownloadStub = sinon.stub();
|
||||
packDownloadStub.callsFake((packs) => ({
|
||||
packs,
|
||||
}));
|
||||
const codeQL = setCodeQL({
|
||||
packDownload: packDownloadStub,
|
||||
test("downloadPacks-no-registries", async (t) => {
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
const packDownloadStub = sinon.stub();
|
||||
packDownloadStub.callsFake((packs) => ({
|
||||
packs,
|
||||
}));
|
||||
const codeQL = setCodeQL({
|
||||
packDownload: packDownloadStub,
|
||||
});
|
||||
const logger = getRunnerLogger(true);
|
||||
|
||||
// packs are supplied for go, java, and python
|
||||
// analyzed languages are java, javascript, and python
|
||||
await configUtils.downloadPacks(
|
||||
codeQL,
|
||||
[Language.javascript, Language.java, Language.python],
|
||||
{
|
||||
java: ["a", "b"],
|
||||
go: ["c", "d"],
|
||||
python: ["e", "f"],
|
||||
},
|
||||
undefined, // registries
|
||||
sampleApiDetails,
|
||||
tmpDir,
|
||||
logger
|
||||
);
|
||||
|
||||
// Expecting packs to be downloaded once for java and once for python
|
||||
t.deepEqual(packDownloadStub.callCount, 2);
|
||||
// no config file was created, so pass `undefined` as the config file path
|
||||
t.deepEqual(packDownloadStub.firstCall.args, [["a", "b"], undefined]);
|
||||
t.deepEqual(packDownloadStub.secondCall.args, [["e", "f"], undefined]);
|
||||
});
|
||||
});
|
||||
|
||||
test("downloadPacks-with-registries", async (t) => {
|
||||
// same thing, but this time include a registries block and
|
||||
// associated env vars
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
process.env.GITHUB_TOKEN = "not-a-token";
|
||||
process.env.CODEQL_REGISTRIES_AUTH = "not-a-registries-auth";
|
||||
const logger = getRunnerLogger(true);
|
||||
|
||||
const registries = [
|
||||
{
|
||||
// no slash
|
||||
url: "http://ghcr.io",
|
||||
packages: ["codeql/*", "dsp-testing/*"],
|
||||
token: "not-a-token",
|
||||
},
|
||||
{
|
||||
// with slash
|
||||
url: "https://containers.GHEHOSTNAME1/v2/",
|
||||
packages: "semmle/*",
|
||||
token: "still-not-a-token",
|
||||
},
|
||||
];
|
||||
|
||||
// append a slash to the first url
|
||||
const expectedRegistries = registries.map((r, i) => ({
|
||||
packages: r.packages,
|
||||
url: i === 0 ? `${r.url}/` : r.url,
|
||||
}));
|
||||
|
||||
const expectedConfigFile = path.join(tmpDir, "qlconfig.yml");
|
||||
const packDownloadStub = sinon.stub();
|
||||
packDownloadStub.callsFake((packs, configFile) => {
|
||||
t.deepEqual(configFile, expectedConfigFile);
|
||||
// verify the env vars were set correctly
|
||||
t.deepEqual(process.env.GITHUB_TOKEN, sampleApiDetails.auth);
|
||||
t.deepEqual(
|
||||
process.env.CODEQL_REGISTRIES_AUTH,
|
||||
"http://ghcr.io=not-a-token,https://containers.GHEHOSTNAME1/v2/=still-not-a-token"
|
||||
);
|
||||
|
||||
// verify the config file contents were set correctly
|
||||
const config = yaml.load(fs.readFileSync(configFile, "utf8")) as {
|
||||
registries: configUtils.RegistryConfigNoCredentials[];
|
||||
};
|
||||
t.deepEqual(config.registries, expectedRegistries);
|
||||
return {
|
||||
packs,
|
||||
};
|
||||
});
|
||||
|
||||
const codeQL = setCodeQL({
|
||||
packDownload: packDownloadStub,
|
||||
getVersion: () => Promise.resolve("2.10.5"),
|
||||
});
|
||||
|
||||
// packs are supplied for go, java, and python
|
||||
// analyzed languages are java, javascript, and python
|
||||
await configUtils.downloadPacks(
|
||||
codeQL,
|
||||
[Language.javascript, Language.java, Language.python],
|
||||
{
|
||||
java: ["a", "b"],
|
||||
go: ["c", "d"],
|
||||
python: ["e", "f"],
|
||||
},
|
||||
registries,
|
||||
sampleApiDetails,
|
||||
tmpDir,
|
||||
logger
|
||||
);
|
||||
|
||||
// Same packs are downloaded as in previous test
|
||||
t.deepEqual(packDownloadStub.callCount, 2);
|
||||
t.deepEqual(packDownloadStub.firstCall.args, [
|
||||
["a", "b"],
|
||||
expectedConfigFile,
|
||||
]);
|
||||
t.deepEqual(packDownloadStub.secondCall.args, [
|
||||
["e", "f"],
|
||||
expectedConfigFile,
|
||||
]);
|
||||
|
||||
// Verify that the env vars were unset.
|
||||
t.deepEqual(process.env.GITHUB_TOKEN, "not-a-token");
|
||||
t.deepEqual(process.env.CODEQL_REGISTRIES_AUTH, "not-a-registries-auth");
|
||||
});
|
||||
});
|
||||
|
||||
test("downloadPacks-with-registries fails on 2.10.3", async (t) => {
|
||||
// same thing, but this time include a registries block and
|
||||
// associated env vars
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
process.env.GITHUB_TOKEN = "not-a-token";
|
||||
process.env.CODEQL_REGISTRIES_AUTH = "not-a-registries-auth";
|
||||
const logger = getRunnerLogger(true);
|
||||
|
||||
const registries = [
|
||||
{
|
||||
url: "http://ghcr.io",
|
||||
packages: ["codeql/*", "dsp-testing/*"],
|
||||
token: "not-a-token",
|
||||
},
|
||||
{
|
||||
url: "https://containers.GHEHOSTNAME1/v2/",
|
||||
packages: "semmle/*",
|
||||
token: "still-not-a-token",
|
||||
},
|
||||
];
|
||||
|
||||
const codeQL = setCodeQL({
|
||||
getVersion: () => Promise.resolve("2.10.3"),
|
||||
});
|
||||
await t.throwsAsync(
|
||||
async () => {
|
||||
return await configUtils.downloadPacks(
|
||||
codeQL,
|
||||
[Language.javascript, Language.java, Language.python],
|
||||
{},
|
||||
registries,
|
||||
sampleApiDetails,
|
||||
tmpDir,
|
||||
logger
|
||||
);
|
||||
},
|
||||
{ instanceOf: Error },
|
||||
"'registries' input is not supported on CodeQL versions less than 2.10.4."
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test("downloadPacks-with-registries fails with invalid registries block", async (t) => {
|
||||
// same thing, but this time include a registries block and
|
||||
// associated env vars
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
process.env.GITHUB_TOKEN = "not-a-token";
|
||||
process.env.CODEQL_REGISTRIES_AUTH = "not-a-registries-auth";
|
||||
const logger = getRunnerLogger(true);
|
||||
|
||||
const registries = [
|
||||
{
|
||||
// missing url property
|
||||
packages: ["codeql/*", "dsp-testing/*"],
|
||||
token: "not-a-token",
|
||||
},
|
||||
{
|
||||
url: "https://containers.GHEHOSTNAME1/v2/",
|
||||
packages: "semmle/*",
|
||||
token: "still-not-a-token",
|
||||
},
|
||||
];
|
||||
|
||||
const codeQL = setCodeQL({
|
||||
getVersion: () => Promise.resolve("2.10.4"),
|
||||
});
|
||||
await t.throwsAsync(
|
||||
async () => {
|
||||
return await configUtils.downloadPacks(
|
||||
codeQL,
|
||||
[Language.javascript, Language.java, Language.python],
|
||||
{},
|
||||
registries as any,
|
||||
sampleApiDetails,
|
||||
tmpDir,
|
||||
logger
|
||||
);
|
||||
},
|
||||
{ instanceOf: Error },
|
||||
"Invalid 'registries' input. Must be an array of objects with 'url' and 'packages' properties."
|
||||
);
|
||||
});
|
||||
const logger = getRunnerLogger(true);
|
||||
|
||||
// packs are supplied for go, java, and python
|
||||
// analyzed languages are java, javascript, and python
|
||||
await configUtils.downloadPacks(
|
||||
codeQL,
|
||||
[Language.javascript, Language.java, Language.python],
|
||||
{
|
||||
java: ["a", "b"],
|
||||
go: ["c", "d"],
|
||||
python: ["e", "f"],
|
||||
},
|
||||
logger
|
||||
);
|
||||
|
||||
t.deepEqual(packDownloadStub.callCount, 2);
|
||||
t.deepEqual(packDownloadStub.firstCall.args, [["a", "b"]]);
|
||||
t.deepEqual(packDownloadStub.secondCall.args, [["e", "f"]]);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import * as semver from "semver";
|
|||
import * as api from "./api-client";
|
||||
import {
|
||||
CodeQL,
|
||||
CODEQL_VERSION_GHES_PACK_DOWNLOAD,
|
||||
CODEQL_VERSION_ML_POWERED_QUERIES,
|
||||
CODEQL_VERSION_ML_POWERED_QUERIES_WINDOWS,
|
||||
ResolveQueriesOutput,
|
||||
|
|
@ -61,6 +62,23 @@ export interface UserConfig {
|
|||
|
||||
export type QueryFilter = ExcludeQueryFilter | IncludeQueryFilter;
|
||||
|
||||
export type RegistryConfigWithCredentials = RegistryConfigNoCredentials & {
|
||||
// Token to use when downloading packs from this registry.
|
||||
token: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* The list of registries and the associated pack globs that determine where each
|
||||
* pack can be downloaded from.
|
||||
*/
|
||||
export interface RegistryConfigNoCredentials {
|
||||
// URL of a package registry, eg- https://ghcr.io/v2/
|
||||
url: string;
|
||||
|
||||
// List of globs that determine which packs are associated with this registry.
|
||||
packages: string[] | string;
|
||||
}
|
||||
|
||||
interface ExcludeQueryFilter {
|
||||
exclude: Record<string, string[] | string>;
|
||||
}
|
||||
|
|
@ -1608,6 +1626,7 @@ export async function initConfig(
|
|||
languagesInput: string | undefined,
|
||||
queriesInput: string | undefined,
|
||||
packsInput: string | undefined,
|
||||
registriesInput: string | undefined,
|
||||
configFile: string | undefined,
|
||||
dbLocation: string | undefined,
|
||||
trapCachingEnabled: boolean,
|
||||
|
|
@ -1686,7 +1705,16 @@ export async function initConfig(
|
|||
// happen in the CLI during the `database init` command, so no need
|
||||
// to download them here.
|
||||
if (!(await useCodeScanningConfigInCli(codeQL))) {
|
||||
await downloadPacks(codeQL, config.languages, config.packs, logger);
|
||||
const registries = parseRegistries(registriesInput);
|
||||
await downloadPacks(
|
||||
codeQL,
|
||||
config.languages,
|
||||
config.packs,
|
||||
registries,
|
||||
apiDetails,
|
||||
config.tempDir,
|
||||
logger
|
||||
);
|
||||
}
|
||||
|
||||
// Save the config so we can easily access it again in the future
|
||||
|
|
@ -1694,6 +1722,18 @@ export async function initConfig(
|
|||
return config;
|
||||
}
|
||||
|
||||
function parseRegistries(
|
||||
registriesInput: string | undefined
|
||||
): RegistryConfigWithCredentials[] | undefined {
|
||||
try {
|
||||
return registriesInput
|
||||
? (yaml.load(registriesInput) as RegistryConfigWithCredentials[])
|
||||
: undefined;
|
||||
} catch (e) {
|
||||
throw new Error("Invalid registries input. Must be a YAML string.");
|
||||
}
|
||||
}
|
||||
|
||||
function isLocal(configPath: string): boolean {
|
||||
// If the path starts with ./, look locally
|
||||
if (configPath.indexOf("./") === 0) {
|
||||
|
|
@ -1795,30 +1835,126 @@ export async function downloadPacks(
|
|||
codeQL: CodeQL,
|
||||
languages: Language[],
|
||||
packs: Packs,
|
||||
registries: RegistryConfigWithCredentials[] | undefined,
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
tmpDir: string,
|
||||
logger: Logger
|
||||
) {
|
||||
let numPacksDownloaded = 0;
|
||||
logger.startGroup("Downloading packs");
|
||||
for (const language of languages) {
|
||||
const packsWithVersion = packs[language];
|
||||
if (packsWithVersion?.length) {
|
||||
logger.info(`Downloading custom packs for ${language}`);
|
||||
const results = await codeQL.packDownload(packsWithVersion);
|
||||
numPacksDownloaded += results.packs.length;
|
||||
logger.info(
|
||||
`Downloaded packs: ${results.packs
|
||||
.map((r) => `${r.name}@${r.version || "latest"}`)
|
||||
.join(", ")}`
|
||||
let qlconfigFile: string | undefined;
|
||||
let registriesAuthTokens: string | undefined;
|
||||
if (registries) {
|
||||
if (
|
||||
!(await codeQlVersionAbove(codeQL, CODEQL_VERSION_GHES_PACK_DOWNLOAD))
|
||||
) {
|
||||
throw new Error(
|
||||
`'registries' input is not supported on CodeQL versions less than ${CODEQL_VERSION_GHES_PACK_DOWNLOAD}.`
|
||||
);
|
||||
}
|
||||
|
||||
// generate a qlconfig.yml file to hold the registry configs.
|
||||
const qlconfig = createRegistriesBlock(registries);
|
||||
qlconfigFile = path.join(tmpDir, "qlconfig.yml");
|
||||
fs.writeFileSync(qlconfigFile, yaml.dump(qlconfig), "utf8");
|
||||
|
||||
registriesAuthTokens = registries
|
||||
.map((registry) => `${registry.url}=${registry.token}`)
|
||||
.join(",");
|
||||
}
|
||||
|
||||
await wrapEnvironment(
|
||||
{
|
||||
GITHUB_TOKEN: apiDetails.auth,
|
||||
CODEQL_REGISTRIES_AUTH: registriesAuthTokens,
|
||||
},
|
||||
async () => {
|
||||
let numPacksDownloaded = 0;
|
||||
logger.startGroup("Downloading packs");
|
||||
for (const language of languages) {
|
||||
const packsWithVersion = packs[language];
|
||||
if (packsWithVersion?.length) {
|
||||
logger.info(`Downloading custom packs for ${language}`);
|
||||
const results = await codeQL.packDownload(
|
||||
packsWithVersion,
|
||||
qlconfigFile
|
||||
);
|
||||
numPacksDownloaded += results.packs.length;
|
||||
logger.info(
|
||||
`Downloaded: ${results.packs
|
||||
.map((r) => `${r.name}@${r.version || "latest"}`)
|
||||
.join(", ")}`
|
||||
);
|
||||
}
|
||||
}
|
||||
if (numPacksDownloaded > 0) {
|
||||
logger.info(
|
||||
`Downloaded ${numPacksDownloaded} ${packs === 1 ? "pack" : "packs"}`
|
||||
);
|
||||
} else {
|
||||
logger.info("No packs to download");
|
||||
}
|
||||
logger.endGroup();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function createRegistriesBlock(registries: RegistryConfigWithCredentials[]): {
|
||||
registries: RegistryConfigNoCredentials[];
|
||||
} {
|
||||
if (
|
||||
!Array.isArray(registries) ||
|
||||
registries.some((r) => !r.url || !r.packages)
|
||||
) {
|
||||
throw new Error(
|
||||
"Invalid 'registries' input. Must be an array of objects with 'url' and 'packages' properties."
|
||||
);
|
||||
}
|
||||
|
||||
// be sure to remove the `token` field from the registry before writing it to disk.
|
||||
const safeRegistries = registries.map((registry) => ({
|
||||
// ensure the url ends with a slash to avoid a bug in the CLI 2.10.4
|
||||
url: !registry?.url.endsWith("/") ? `${registry.url}/` : registry.url,
|
||||
packages: registry.packages,
|
||||
}));
|
||||
const qlconfig = {
|
||||
registries: safeRegistries,
|
||||
};
|
||||
return qlconfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a temporary environment based on the existing environment and overridden
|
||||
* by the given environment variables that are passed in as arguments.
|
||||
*
|
||||
* Use this new environment in the context of the given operation. After completing
|
||||
* the operation, restore the original environment.
|
||||
*
|
||||
* This function does not support un-setting environment variables.
|
||||
*
|
||||
* @param env
|
||||
* @param operation
|
||||
*/
|
||||
async function wrapEnvironment(
|
||||
env: Record<string, string | undefined>,
|
||||
operation: Function
|
||||
) {
|
||||
// Remember the original env
|
||||
const oldEnv = { ...process.env };
|
||||
|
||||
// Set the new env
|
||||
for (const [key, value] of Object.entries(env)) {
|
||||
// Ignore undefined keys
|
||||
if (value !== undefined) {
|
||||
process.env[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (numPacksDownloaded > 0) {
|
||||
logger.info(
|
||||
`Downloaded ${numPacksDownloaded} ${packs === 1 ? "pack" : "packs"}`
|
||||
);
|
||||
} else {
|
||||
logger.info("No packs to download");
|
||||
try {
|
||||
// Run the operation
|
||||
await operation();
|
||||
} finally {
|
||||
// Restore the old env
|
||||
for (const [key, value] of Object.entries(oldEnv)) {
|
||||
process.env[key] = value;
|
||||
}
|
||||
}
|
||||
logger.endGroup();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ async function run() {
|
|||
getOptionalInput("languages"),
|
||||
getOptionalInput("queries"),
|
||||
getOptionalInput("packs"),
|
||||
getOptionalInput("registries"),
|
||||
getOptionalInput("config-file"),
|
||||
getOptionalInput("db-location"),
|
||||
await getTrapCachingEnabled(featureFlags),
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ export async function initConfig(
|
|||
languagesInput: string | undefined,
|
||||
queriesInput: string | undefined,
|
||||
packsInput: string | undefined,
|
||||
registriesInput: string | undefined,
|
||||
configFile: string | undefined,
|
||||
dbLocation: string | undefined,
|
||||
trapCachingEnabled: boolean,
|
||||
|
|
@ -62,6 +63,7 @@ export async function initConfig(
|
|||
languagesInput,
|
||||
queriesInput,
|
||||
packsInput,
|
||||
registriesInput,
|
||||
configFile,
|
||||
dbLocation,
|
||||
trapCachingEnabled,
|
||||
|
|
|
|||
|
|
@ -240,6 +240,7 @@ program
|
|||
cmd.languages,
|
||||
cmd.queries,
|
||||
cmd.packs,
|
||||
undefined, // we won't support registries in the runner
|
||||
cmd.configFile,
|
||||
undefined,
|
||||
false,
|
||||
|
|
|
|||
7
tests/multi-language-repo/.github/codeql/codeql-config-registries.yml
vendored
Normal file
7
tests/multi-language-repo/.github/codeql/codeql-config-registries.yml
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
name: Pack testing in the CodeQL Action
|
||||
|
||||
disable-default-queries: true
|
||||
packs:
|
||||
javascript:
|
||||
- dsp-testing/private-pack
|
||||
- dsp-testing/codeql-pack1
|
||||
Loading…
Add table
Add a link
Reference in a new issue