Extract semantic CLI version from URL when requesting specific tools

This commit is contained in:
Henry Mercer 2023-05-16 14:47:12 +01:00
parent 5489416722
commit 2bf10dc4b9
12 changed files with 217 additions and 149 deletions

80
lib/codeql.test.js generated
View file

@ -49,20 +49,11 @@ const testing_utils_1 = require("./testing-utils");
const util = __importStar(require("./util")); const util = __importStar(require("./util"));
const util_1 = require("./util"); const util_1 = require("./util");
(0, testing_utils_1.setupTests)(ava_1.default); (0, testing_utils_1.setupTests)(ava_1.default);
const sampleApiDetails = {
auth: "token",
url: "https://github.com",
apiURL: "https://api.github.com",
};
const sampleGHAEApiDetails = { const sampleGHAEApiDetails = {
auth: "token", auth: "token",
url: "https://example.githubenterprise.com", url: "https://example.githubenterprise.com",
apiURL: "https://example.githubenterprise.com/api/v3", apiURL: "https://example.githubenterprise.com/api/v3",
}; };
const SAMPLE_DEFAULT_CLI_VERSION = {
cliVersion: "2.0.0",
variant: util.GitHubVariant.DOTCOM,
};
let stubConfig; let stubConfig;
ava_1.default.beforeEach(() => { ava_1.default.beforeEach(() => {
(0, util_1.initializeEnvironment)("1.2.3"); (0, util_1.initializeEnvironment)("1.2.3");
@ -91,34 +82,13 @@ ava_1.default.beforeEach(() => {
trapCacheDownloadTime: 0, trapCacheDownloadTime: 0,
}; };
}); });
/** async function installIntoToolcache({ apiDetails = testing_utils_1.SAMPLE_DOTCOM_API_DETAILS, cliVersion, isPinned, tagName, tmpDir, }) {
* Mocks the API for downloading the bundle tagged `tagName`. const url = (0, testing_utils_1.mockBundleDownloadApi)({ apiDetails, isPinned, tagName });
*
* @returns the download URL for the bundle. This can be passed to the tools parameter of
* `codeql.setupCodeQL`.
*/
function mockDownloadApi({ apiDetails = sampleApiDetails, isPinned, repo = "github/codeql-action", platformSpecific = true, tagName, }) {
const platform = process.platform === "win32"
? "win64"
: process.platform === "linux"
? "linux64"
: "osx64";
const baseUrl = apiDetails?.url ?? "https://example.com";
const relativeUrl = apiDetails
? `/${repo}/releases/download/${tagName}/codeql-bundle${platformSpecific ? `-${platform}` : ""}.tar.gz`
: `/download/${tagName}/codeql-bundle.tar.gz`;
(0, nock_1.default)(baseUrl)
.get(relativeUrl)
.replyWithFile(200, path_1.default.join(__dirname, `/../src/testdata/codeql-bundle${isPinned ? "-pinned" : ""}.tar.gz`));
return `${baseUrl}${relativeUrl}`;
}
async function installIntoToolcache({ apiDetails = sampleApiDetails, cliVersion, isPinned, tagName, tmpDir, }) {
const url = mockDownloadApi({ apiDetails, isPinned, tagName });
await codeql.setupCodeQL(cliVersion !== undefined ? undefined : url, apiDetails, tmpDir, util.GitHubVariant.GHES, cliVersion !== undefined await codeql.setupCodeQL(cliVersion !== undefined ? undefined : url, apiDetails, tmpDir, util.GitHubVariant.GHES, cliVersion !== undefined
? { cliVersion, tagName, variant: util.GitHubVariant.GHES } ? { cliVersion, tagName, variant: util.GitHubVariant.GHES }
: SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false); : testing_utils_1.SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
} }
function mockReleaseApi({ apiDetails = sampleApiDetails, assetNames, tagName, }) { function mockReleaseApi({ apiDetails = testing_utils_1.SAMPLE_DOTCOM_API_DETAILS, assetNames, tagName, }) {
return (0, nock_1.default)(apiDetails.apiURL) return (0, nock_1.default)(apiDetails.apiURL)
.get(`/repos/github/codeql-action/releases/tags/${tagName}`) .get(`/repos/github/codeql-action/releases/tags/${tagName}`)
.reply(200, { .reply(200, {
@ -149,11 +119,11 @@ function mockApiDetails(apiDetails) {
const versions = ["20200601", "20200610"]; const versions = ["20200601", "20200610"];
for (let i = 0; i < versions.length; i++) { for (let i = 0; i < versions.length; i++) {
const version = versions[i]; const version = versions[i];
const url = mockDownloadApi({ const url = (0, testing_utils_1.mockBundleDownloadApi)({
tagName: `codeql-bundle-${version}`, tagName: `codeql-bundle-${version}`,
isPinned: false, isPinned: false,
}); });
const result = await codeql.setupCodeQL(url, sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false); const result = await codeql.setupCodeQL(url, testing_utils_1.SAMPLE_DOTCOM_API_DETAILS, tmpDir, util.GitHubVariant.DOTCOM, testing_utils_1.SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
t.assert(toolcache.find("CodeQL", `0.0.0-${version}`)); t.assert(toolcache.find("CodeQL", `0.0.0-${version}`));
t.is(result.toolsVersion, `0.0.0-${version}`); t.is(result.toolsVersion, `0.0.0-${version}`);
t.is(result.toolsSource, init_1.ToolsSource.Download); t.is(result.toolsSource, init_1.ToolsSource.Download);
@ -170,10 +140,10 @@ function mockApiDetails(apiDetails) {
isPinned: true, isPinned: true,
tmpDir, tmpDir,
}); });
const url = mockDownloadApi({ const url = (0, testing_utils_1.mockBundleDownloadApi)({
tagName: "codeql-bundle-20200610", tagName: "codeql-bundle-20200610",
}); });
const result = await codeql.setupCodeQL(url, sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false); const result = await codeql.setupCodeQL(url, testing_utils_1.SAMPLE_DOTCOM_API_DETAILS, tmpDir, util.GitHubVariant.DOTCOM, testing_utils_1.SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
t.assert(toolcache.find("CodeQL", "0.0.0-20200610")); t.assert(toolcache.find("CodeQL", "0.0.0-20200610"));
t.deepEqual(result.toolsVersion, "0.0.0-20200610"); t.deepEqual(result.toolsVersion, "0.0.0-20200610");
t.is(result.toolsSource, init_1.ToolsSource.Download); t.is(result.toolsSource, init_1.ToolsSource.Download);
@ -198,16 +168,16 @@ for (const { cliVersion, expectedToolcacheVersion, } of EXPLICITLY_REQUESTED_BUN
(0, ava_1.default)(`caches an explicitly requested bundle containing CLI ${cliVersion} as ${expectedToolcacheVersion}`, async (t) => { (0, ava_1.default)(`caches an explicitly requested bundle containing CLI ${cliVersion} as ${expectedToolcacheVersion}`, async (t) => {
await util.withTmpDir(async (tmpDir) => { await util.withTmpDir(async (tmpDir) => {
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir); (0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
mockApiDetails(sampleApiDetails); mockApiDetails(testing_utils_1.SAMPLE_DOTCOM_API_DETAILS);
sinon.stub(actionsUtil, "isRunningLocalAction").returns(true); sinon.stub(actionsUtil, "isRunningLocalAction").returns(true);
const releaseApiMock = mockReleaseApi({ const releaseApiMock = mockReleaseApi({
assetNames: [`cli-version-${cliVersion}.txt`], assetNames: [`cli-version-${cliVersion}.txt`],
tagName: "codeql-bundle-20200610", tagName: "codeql-bundle-20200610",
}); });
const url = mockDownloadApi({ const url = (0, testing_utils_1.mockBundleDownloadApi)({
tagName: "codeql-bundle-20200610", tagName: "codeql-bundle-20200610",
}); });
const result = await codeql.setupCodeQL(url, sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false); const result = await codeql.setupCodeQL(url, testing_utils_1.SAMPLE_DOTCOM_API_DETAILS, tmpDir, util.GitHubVariant.DOTCOM, testing_utils_1.SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
t.assert(releaseApiMock.isDone(), "Releases API should have been called"); t.assert(releaseApiMock.isDone(), "Releases API should have been called");
t.assert(toolcache.find("CodeQL", expectedToolcacheVersion)); t.assert(toolcache.find("CodeQL", expectedToolcacheVersion));
t.deepEqual(result.toolsVersion, cliVersion); t.deepEqual(result.toolsVersion, cliVersion);
@ -220,19 +190,19 @@ for (const { githubReleases, toolcacheVersion } of [
// Test that we use the tools from the toolcache when `SAMPLE_DEFAULT_CLI_VERSION` is requested // Test that we use the tools from the toolcache when `SAMPLE_DEFAULT_CLI_VERSION` is requested
// and `SAMPLE_DEFAULT_CLI_VERSION-` is in the toolcache. // and `SAMPLE_DEFAULT_CLI_VERSION-` is in the toolcache.
{ {
toolcacheVersion: SAMPLE_DEFAULT_CLI_VERSION.cliVersion, toolcacheVersion: testing_utils_1.SAMPLE_DEFAULT_CLI_VERSION.cliVersion,
}, },
{ {
githubReleases: { githubReleases: {
"codeql-bundle-20230101": `cli-version-${SAMPLE_DEFAULT_CLI_VERSION.cliVersion}.txt`, "codeql-bundle-20230101": `cli-version-${testing_utils_1.SAMPLE_DEFAULT_CLI_VERSION.cliVersion}.txt`,
}, },
toolcacheVersion: "0.0.0-20230101", toolcacheVersion: "0.0.0-20230101",
}, },
{ {
toolcacheVersion: `${SAMPLE_DEFAULT_CLI_VERSION.cliVersion}-20230101`, toolcacheVersion: `${testing_utils_1.SAMPLE_DEFAULT_CLI_VERSION.cliVersion}-20230101`,
}, },
]) { ]) {
(0, ava_1.default)(`uses tools from toolcache when ${SAMPLE_DEFAULT_CLI_VERSION.cliVersion} is requested and ` + (0, ava_1.default)(`uses tools from toolcache when ${testing_utils_1.SAMPLE_DEFAULT_CLI_VERSION.cliVersion} is requested and ` +
`${toolcacheVersion} is installed`, async (t) => { `${toolcacheVersion} is installed`, async (t) => {
await util.withTmpDir(async (tmpDir) => { await util.withTmpDir(async (tmpDir) => {
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir); (0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
@ -256,8 +226,8 @@ for (const { githubReleases, toolcacheVersion } of [
}))), }))),
})); }));
} }
const result = await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false); const result = await codeql.setupCodeQL(undefined, testing_utils_1.SAMPLE_DOTCOM_API_DETAILS, tmpDir, util.GitHubVariant.DOTCOM, testing_utils_1.SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
t.is(result.toolsVersion, SAMPLE_DEFAULT_CLI_VERSION.cliVersion); t.is(result.toolsVersion, testing_utils_1.SAMPLE_DEFAULT_CLI_VERSION.cliVersion);
t.is(result.toolsSource, init_1.ToolsSource.Toolcache); t.is(result.toolsSource, init_1.ToolsSource.Toolcache);
t.is(result.toolsDownloadDurationMs, undefined); t.is(result.toolsDownloadDurationMs, undefined);
}); });
@ -272,7 +242,7 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
isPinned: true, isPinned: true,
tmpDir, tmpDir,
}); });
const result = await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, variant, { const result = await codeql.setupCodeQL(undefined, testing_utils_1.SAMPLE_DOTCOM_API_DETAILS, tmpDir, variant, {
cliVersion: defaults.cliVersion, cliVersion: defaults.cliVersion,
tagName: defaults.bundleVersion, tagName: defaults.bundleVersion,
variant, variant,
@ -292,10 +262,10 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
isPinned: false, isPinned: false,
tmpDir, tmpDir,
}); });
mockDownloadApi({ (0, testing_utils_1.mockBundleDownloadApi)({
tagName: defaults.bundleVersion, tagName: defaults.bundleVersion,
}); });
const result = await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, variant, { const result = await codeql.setupCodeQL(undefined, testing_utils_1.SAMPLE_DOTCOM_API_DETAILS, tmpDir, variant, {
cliVersion: defaults.cliVersion, cliVersion: defaults.cliVersion,
tagName: defaults.bundleVersion, tagName: defaults.bundleVersion,
variant, variant,
@ -316,10 +286,10 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
isPinned: true, isPinned: true,
tmpDir, tmpDir,
}); });
mockDownloadApi({ (0, testing_utils_1.mockBundleDownloadApi)({
tagName: defaults.bundleVersion, tagName: defaults.bundleVersion,
}); });
const result = await codeql.setupCodeQL("latest", sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false); const result = await codeql.setupCodeQL("latest", testing_utils_1.SAMPLE_DOTCOM_API_DETAILS, tmpDir, util.GitHubVariant.DOTCOM, testing_utils_1.SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
t.deepEqual(result.toolsVersion, defaults.cliVersion); t.deepEqual(result.toolsVersion, defaults.cliVersion);
t.is(result.toolsSource, init_1.ToolsSource.Download); t.is(result.toolsSource, init_1.ToolsSource.Download);
t.assert(Number.isInteger(result.toolsDownloadDurationMs)); t.assert(Number.isInteger(result.toolsDownloadDurationMs));
@ -375,18 +345,18 @@ for (const isBundleVersionInUrl of [true, false]) {
(0, ava_1.default)("bundle URL from another repo is cached as 0.0.0-bundleVersion", async (t) => { (0, ava_1.default)("bundle URL from another repo is cached as 0.0.0-bundleVersion", async (t) => {
await util.withTmpDir(async (tmpDir) => { await util.withTmpDir(async (tmpDir) => {
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir); (0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
mockApiDetails(sampleApiDetails); mockApiDetails(testing_utils_1.SAMPLE_DOTCOM_API_DETAILS);
sinon.stub(actionsUtil, "isRunningLocalAction").returns(true); sinon.stub(actionsUtil, "isRunningLocalAction").returns(true);
const releasesApiMock = mockReleaseApi({ const releasesApiMock = mockReleaseApi({
assetNames: ["cli-version-2.12.2.txt"], assetNames: ["cli-version-2.12.2.txt"],
tagName: "codeql-bundle-20230203", tagName: "codeql-bundle-20230203",
}); });
mockDownloadApi({ (0, testing_utils_1.mockBundleDownloadApi)({
repo: "codeql-testing/codeql-cli-nightlies", repo: "codeql-testing/codeql-cli-nightlies",
platformSpecific: false, platformSpecific: false,
tagName: "codeql-bundle-20230203", tagName: "codeql-bundle-20230203",
}); });
const result = await codeql.setupCodeQL("https://github.com/codeql-testing/codeql-cli-nightlies/releases/download/codeql-bundle-20230203/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false); const result = await codeql.setupCodeQL("https://github.com/codeql-testing/codeql-cli-nightlies/releases/download/codeql-bundle-20230203/codeql-bundle.tar.gz", testing_utils_1.SAMPLE_DOTCOM_API_DETAILS, tmpDir, util.GitHubVariant.DOTCOM, testing_utils_1.SAMPLE_DEFAULT_CLI_VERSION, (0, logging_1.getRunnerLogger)(true), false);
t.is(result.toolsVersion, "0.0.0-20230203"); t.is(result.toolsVersion, "0.0.0-20230203");
t.is(result.toolsSource, init_1.ToolsSource.Download); t.is(result.toolsSource, init_1.ToolsSource.Download);
t.true(Number.isInteger(result.toolsDownloadDurationMs)); t.true(Number.isInteger(result.toolsDownloadDurationMs));

File diff suppressed because one or more lines are too long

7
lib/setup-codeql.js generated
View file

@ -315,6 +315,13 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian
// If a tools URL was provided, then use that. // If a tools URL was provided, then use that.
tagName = tryGetTagNameFromUrl(toolsInput, logger); tagName = tryGetTagNameFromUrl(toolsInput, logger);
url = toolsInput; url = toolsInput;
if (tagName) {
const bundleVersion = tryGetBundleVersionFromTagName(tagName, logger);
// If the bundle version is a semantic version, it is a CLI version number.
if (bundleVersion && semver.valid(bundleVersion)) {
cliVersion = convertToSemVer(bundleVersion, logger);
}
}
} }
else { else {
// Otherwise, use the default CLI version passed in. // Otherwise, use the default CLI version passed in.

File diff suppressed because one or more lines are too long

View file

@ -117,4 +117,14 @@ ava_1.default.beforeEach(() => {
message: "Failed to find a release of the CodeQL tools that contains CodeQL CLI 2.12.1.", message: "Failed to find a release of the CodeQL tools that contains CodeQL CLI 2.12.1.",
}); });
}); });
(0, ava_1.default)("getCodeQLSource sets CLI version for a semver tagged bundle", async (t) => {
await (0, util_1.withTmpDir)(async (tmpDir) => {
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
const tagName = "codeql-bundle-v1.2.3";
(0, testing_utils_1.mockBundleDownloadApi)({ tagName });
const source = await setupCodeql.getCodeQLSource(`https://github.com/github/codeql-action/releases/download/${tagName}/codeql-bundle-linux64.tar.gz`, testing_utils_1.SAMPLE_DEFAULT_CLI_VERSION, testing_utils_1.SAMPLE_DOTCOM_API_DETAILS, util_1.GitHubVariant.DOTCOM, (0, logging_1.getRunnerLogger)(true));
t.is(source.sourceType, "download");
t.is(source["cliVersion"], "1.2.3");
});
});
//# sourceMappingURL=setup-codeql.test.js.map //# sourceMappingURL=setup-codeql.test.js.map

View file

@ -1 +1 @@
{"version":3,"file":"setup-codeql.test.js","sourceRoot":"","sources":["../src/setup-codeql.test.ts"],"names":[],"mappings":"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"} {"version":3,"file":"setup-codeql.test.js","sourceRoot":"","sources":["../src/setup-codeql.test.ts"],"names":[],"mappings":"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"}

41
lib/testing-utils.js generated
View file

@ -22,15 +22,28 @@ var __importStar = (this && this.__importStar) || function (mod) {
__setModuleDefault(result, mod); __setModuleDefault(result, mod);
return result; return result;
}; };
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.createFeatures = exports.mockCodeQLVersion = exports.mockLanguagesInRepo = exports.mockFeatureFlagApiEndpoint = exports.getRecordingLogger = exports.setupActionsVars = exports.setupTests = void 0; exports.mockBundleDownloadApi = exports.createFeatures = exports.mockCodeQLVersion = exports.mockLanguagesInRepo = exports.mockFeatureFlagApiEndpoint = exports.getRecordingLogger = exports.setupActionsVars = exports.setupTests = exports.SAMPLE_DEFAULT_CLI_VERSION = exports.SAMPLE_DOTCOM_API_DETAILS = void 0;
const node_util_1 = require("node:util"); const node_util_1 = require("node:util");
const path_1 = __importDefault(require("path"));
const github = __importStar(require("@actions/github")); const github = __importStar(require("@actions/github"));
const nock = __importStar(require("nock")); const nock_1 = __importDefault(require("nock"));
const sinon = __importStar(require("sinon")); const sinon = __importStar(require("sinon"));
const apiClient = __importStar(require("./api-client")); const apiClient = __importStar(require("./api-client"));
const CodeQL = __importStar(require("./codeql")); const CodeQL = __importStar(require("./codeql"));
const util_1 = require("./util"); const util_1 = require("./util");
exports.SAMPLE_DOTCOM_API_DETAILS = {
auth: "token",
url: "https://github.com",
apiURL: "https://api.github.com",
};
exports.SAMPLE_DEFAULT_CLI_VERSION = {
cliVersion: "2.0.0",
variant: util_1.GitHubVariant.DOTCOM,
};
function wrapOutput(context) { function wrapOutput(context) {
// Function signature taken from Socket.write. // Function signature taken from Socket.write.
// Note there are two overloads: // Note there are two overloads:
@ -92,7 +105,7 @@ function setupTests(test) {
process.stdout.write(t.context.testOutput); process.stdout.write(t.context.testOutput);
} }
// Undo any modifications made by nock // Undo any modifications made by nock
nock.cleanAll(); nock_1.default.cleanAll();
// Undo any modifications made by sinon // Undo any modifications made by sinon
sinon.restore(); sinon.restore();
// Undo any modifications to the env // Undo any modifications to the env
@ -196,4 +209,26 @@ function createFeatures(enabledFeatures) {
}; };
} }
exports.createFeatures = createFeatures; exports.createFeatures = createFeatures;
/**
* Mocks the API for downloading the bundle tagged `tagName`.
*
* @returns the download URL for the bundle. This can be passed to the tools parameter of
* `codeql.setupCodeQL`.
*/
function mockBundleDownloadApi({ apiDetails = exports.SAMPLE_DOTCOM_API_DETAILS, isPinned, repo = "github/codeql-action", platformSpecific = true, tagName, }) {
const platform = process.platform === "win32"
? "win64"
: process.platform === "linux"
? "linux64"
: "osx64";
const baseUrl = apiDetails?.url ?? "https://example.com";
const relativeUrl = apiDetails
? `/${repo}/releases/download/${tagName}/codeql-bundle${platformSpecific ? `-${platform}` : ""}.tar.gz`
: `/download/${tagName}/codeql-bundle.tar.gz`;
(0, nock_1.default)(baseUrl)
.get(relativeUrl)
.replyWithFile(200, path_1.default.join(__dirname, `/../src/testdata/codeql-bundle${isPinned ? "-pinned" : ""}.tar.gz`));
return `${baseUrl}${relativeUrl}`;
}
exports.mockBundleDownloadApi = mockBundleDownloadApi;
//# sourceMappingURL=testing-utils.js.map //# sourceMappingURL=testing-utils.js.map

File diff suppressed because one or more lines are too long

View file

@ -16,37 +16,29 @@ import { GitHubApiDetails } from "./api-client";
import * as codeql from "./codeql"; import * as codeql from "./codeql";
import { AugmentationProperties, Config } from "./config-utils"; import { AugmentationProperties, Config } from "./config-utils";
import * as defaults from "./defaults.json"; import * as defaults from "./defaults.json";
import { import { Feature, featureConfig } from "./feature-flags";
CodeQLDefaultVersionInfo,
Feature,
featureConfig,
} from "./feature-flags";
import { ToolsSource } from "./init"; import { ToolsSource } from "./init";
import { Language } from "./languages"; import { Language } from "./languages";
import { getRunnerLogger } from "./logging"; import { getRunnerLogger } from "./logging";
import { setupTests, createFeatures, setupActionsVars } from "./testing-utils"; import {
setupTests,
createFeatures,
setupActionsVars,
SAMPLE_DOTCOM_API_DETAILS,
SAMPLE_DEFAULT_CLI_VERSION,
mockBundleDownloadApi,
} from "./testing-utils";
import * as util from "./util"; import * as util from "./util";
import { initializeEnvironment } from "./util"; import { initializeEnvironment } from "./util";
setupTests(test); setupTests(test);
const sampleApiDetails = {
auth: "token",
url: "https://github.com",
apiURL: "https://api.github.com",
};
const sampleGHAEApiDetails = { const sampleGHAEApiDetails = {
auth: "token", auth: "token",
url: "https://example.githubenterprise.com", url: "https://example.githubenterprise.com",
apiURL: "https://example.githubenterprise.com/api/v3", apiURL: "https://example.githubenterprise.com/api/v3",
}; };
const SAMPLE_DEFAULT_CLI_VERSION: CodeQLDefaultVersionInfo = {
cliVersion: "2.0.0",
variant: util.GitHubVariant.DOTCOM,
};
let stubConfig: Config; let stubConfig: Config;
test.beforeEach(() => { test.beforeEach(() => {
@ -78,54 +70,8 @@ test.beforeEach(() => {
}; };
}); });
/**
* Mocks the API for downloading the bundle tagged `tagName`.
*
* @returns the download URL for the bundle. This can be passed to the tools parameter of
* `codeql.setupCodeQL`.
*/
function mockDownloadApi({
apiDetails = sampleApiDetails,
isPinned,
repo = "github/codeql-action",
platformSpecific = true,
tagName,
}: {
apiDetails?: GitHubApiDetails;
isPinned?: boolean;
repo?: string;
platformSpecific?: boolean;
tagName: string;
}): string {
const platform =
process.platform === "win32"
? "win64"
: process.platform === "linux"
? "linux64"
: "osx64";
const baseUrl = apiDetails?.url ?? "https://example.com";
const relativeUrl = apiDetails
? `/${repo}/releases/download/${tagName}/codeql-bundle${
platformSpecific ? `-${platform}` : ""
}.tar.gz`
: `/download/${tagName}/codeql-bundle.tar.gz`;
nock(baseUrl)
.get(relativeUrl)
.replyWithFile(
200,
path.join(
__dirname,
`/../src/testdata/codeql-bundle${isPinned ? "-pinned" : ""}.tar.gz`
)
);
return `${baseUrl}${relativeUrl}`;
}
async function installIntoToolcache({ async function installIntoToolcache({
apiDetails = sampleApiDetails, apiDetails = SAMPLE_DOTCOM_API_DETAILS,
cliVersion, cliVersion,
isPinned, isPinned,
tagName, tagName,
@ -137,7 +83,7 @@ async function installIntoToolcache({
tagName: string; tagName: string;
tmpDir: string; tmpDir: string;
}) { }) {
const url = mockDownloadApi({ apiDetails, isPinned, tagName }); const url = mockBundleDownloadApi({ apiDetails, isPinned, tagName });
await codeql.setupCodeQL( await codeql.setupCodeQL(
cliVersion !== undefined ? undefined : url, cliVersion !== undefined ? undefined : url,
apiDetails, apiDetails,
@ -152,7 +98,7 @@ async function installIntoToolcache({
} }
function mockReleaseApi({ function mockReleaseApi({
apiDetails = sampleApiDetails, apiDetails = SAMPLE_DOTCOM_API_DETAILS,
assetNames, assetNames,
tagName, tagName,
}: { }: {
@ -195,13 +141,13 @@ test("downloads and caches explicitly requested bundles that aren't in the toolc
for (let i = 0; i < versions.length; i++) { for (let i = 0; i < versions.length; i++) {
const version = versions[i]; const version = versions[i];
const url = mockDownloadApi({ const url = mockBundleDownloadApi({
tagName: `codeql-bundle-${version}`, tagName: `codeql-bundle-${version}`,
isPinned: false, isPinned: false,
}); });
const result = await codeql.setupCodeQL( const result = await codeql.setupCodeQL(
url, url,
sampleApiDetails, SAMPLE_DOTCOM_API_DETAILS,
tmpDir, tmpDir,
util.GitHubVariant.DOTCOM, util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION, SAMPLE_DEFAULT_CLI_VERSION,
@ -229,12 +175,12 @@ test("downloads an explicitly requested bundle even if a different version is ca
tmpDir, tmpDir,
}); });
const url = mockDownloadApi({ const url = mockBundleDownloadApi({
tagName: "codeql-bundle-20200610", tagName: "codeql-bundle-20200610",
}); });
const result = await codeql.setupCodeQL( const result = await codeql.setupCodeQL(
url, url,
sampleApiDetails, SAMPLE_DOTCOM_API_DETAILS,
tmpDir, tmpDir,
util.GitHubVariant.DOTCOM, util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION, SAMPLE_DEFAULT_CLI_VERSION,
@ -271,20 +217,20 @@ for (const {
await util.withTmpDir(async (tmpDir) => { await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir); setupActionsVars(tmpDir, tmpDir);
mockApiDetails(sampleApiDetails); mockApiDetails(SAMPLE_DOTCOM_API_DETAILS);
sinon.stub(actionsUtil, "isRunningLocalAction").returns(true); sinon.stub(actionsUtil, "isRunningLocalAction").returns(true);
const releaseApiMock = mockReleaseApi({ const releaseApiMock = mockReleaseApi({
assetNames: [`cli-version-${cliVersion}.txt`], assetNames: [`cli-version-${cliVersion}.txt`],
tagName: "codeql-bundle-20200610", tagName: "codeql-bundle-20200610",
}); });
const url = mockDownloadApi({ const url = mockBundleDownloadApi({
tagName: "codeql-bundle-20200610", tagName: "codeql-bundle-20200610",
}); });
const result = await codeql.setupCodeQL( const result = await codeql.setupCodeQL(
url, url,
sampleApiDetails, SAMPLE_DOTCOM_API_DETAILS,
tmpDir, tmpDir,
util.GitHubVariant.DOTCOM, util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION, SAMPLE_DEFAULT_CLI_VERSION,
@ -351,7 +297,7 @@ for (const { githubReleases, toolcacheVersion } of [
const result = await codeql.setupCodeQL( const result = await codeql.setupCodeQL(
undefined, undefined,
sampleApiDetails, SAMPLE_DOTCOM_API_DETAILS,
tmpDir, tmpDir,
util.GitHubVariant.DOTCOM, util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION, SAMPLE_DEFAULT_CLI_VERSION,
@ -379,7 +325,7 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
const result = await codeql.setupCodeQL( const result = await codeql.setupCodeQL(
undefined, undefined,
sampleApiDetails, SAMPLE_DOTCOM_API_DETAILS,
tmpDir, tmpDir,
variant, variant,
{ {
@ -409,12 +355,12 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
tmpDir, tmpDir,
}); });
mockDownloadApi({ mockBundleDownloadApi({
tagName: defaults.bundleVersion, tagName: defaults.bundleVersion,
}); });
const result = await codeql.setupCodeQL( const result = await codeql.setupCodeQL(
undefined, undefined,
sampleApiDetails, SAMPLE_DOTCOM_API_DETAILS,
tmpDir, tmpDir,
variant, variant,
{ {
@ -445,12 +391,12 @@ test('downloads bundle if "latest" tools specified but not cached', async (t) =>
tmpDir, tmpDir,
}); });
mockDownloadApi({ mockBundleDownloadApi({
tagName: defaults.bundleVersion, tagName: defaults.bundleVersion,
}); });
const result = await codeql.setupCodeQL( const result = await codeql.setupCodeQL(
"latest", "latest",
sampleApiDetails, SAMPLE_DOTCOM_API_DETAILS,
tmpDir, tmpDir,
util.GitHubVariant.DOTCOM, util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION, SAMPLE_DEFAULT_CLI_VERSION,
@ -547,13 +493,13 @@ test("bundle URL from another repo is cached as 0.0.0-bundleVersion", async (t)
await util.withTmpDir(async (tmpDir) => { await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir); setupActionsVars(tmpDir, tmpDir);
mockApiDetails(sampleApiDetails); mockApiDetails(SAMPLE_DOTCOM_API_DETAILS);
sinon.stub(actionsUtil, "isRunningLocalAction").returns(true); sinon.stub(actionsUtil, "isRunningLocalAction").returns(true);
const releasesApiMock = mockReleaseApi({ const releasesApiMock = mockReleaseApi({
assetNames: ["cli-version-2.12.2.txt"], assetNames: ["cli-version-2.12.2.txt"],
tagName: "codeql-bundle-20230203", tagName: "codeql-bundle-20230203",
}); });
mockDownloadApi({ mockBundleDownloadApi({
repo: "codeql-testing/codeql-cli-nightlies", repo: "codeql-testing/codeql-cli-nightlies",
platformSpecific: false, platformSpecific: false,
tagName: "codeql-bundle-20230203", tagName: "codeql-bundle-20230203",
@ -561,7 +507,7 @@ test("bundle URL from another repo is cached as 0.0.0-bundleVersion", async (t)
const result = await codeql.setupCodeQL( const result = await codeql.setupCodeQL(
"https://github.com/codeql-testing/codeql-cli-nightlies/releases/download/codeql-bundle-20230203/codeql-bundle.tar.gz", "https://github.com/codeql-testing/codeql-cli-nightlies/releases/download/codeql-bundle-20230203/codeql-bundle.tar.gz",
sampleApiDetails, SAMPLE_DOTCOM_API_DETAILS,
tmpDir, tmpDir,
util.GitHubVariant.DOTCOM, util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION, SAMPLE_DEFAULT_CLI_VERSION,

View file

@ -7,8 +7,19 @@ import * as actionsUtil from "./actions-util";
import * as api from "./api-client"; import * as api from "./api-client";
import { getRunnerLogger } from "./logging"; import { getRunnerLogger } from "./logging";
import * as setupCodeql from "./setup-codeql"; import * as setupCodeql from "./setup-codeql";
import { setupTests } from "./testing-utils"; import {
import { initializeEnvironment, wrapError } from "./util"; SAMPLE_DEFAULT_CLI_VERSION,
SAMPLE_DOTCOM_API_DETAILS,
mockBundleDownloadApi,
setupActionsVars,
setupTests,
} from "./testing-utils";
import {
GitHubVariant,
initializeEnvironment,
withTmpDir,
wrapError,
} from "./util";
setupTests(test); setupTests(test);
@ -123,3 +134,21 @@ test("findCodeQLBundleTagDotcomOnly() errors if no GitHub Release matches marker
} }
); );
}); });
test("getCodeQLSource sets CLI version for a semver tagged bundle", async (t) => {
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
const tagName = "codeql-bundle-v1.2.3";
mockBundleDownloadApi({ tagName });
const source = await setupCodeql.getCodeQLSource(
`https://github.com/github/codeql-action/releases/download/${tagName}/codeql-bundle-linux64.tar.gz`,
SAMPLE_DEFAULT_CLI_VERSION,
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
getRunnerLogger(true)
);
t.is(source.sourceType, "download");
t.is(source["cliVersion"], "1.2.3");
});
});

View file

@ -400,6 +400,14 @@ export async function getCodeQLSource(
// If a tools URL was provided, then use that. // If a tools URL was provided, then use that.
tagName = tryGetTagNameFromUrl(toolsInput, logger); tagName = tryGetTagNameFromUrl(toolsInput, logger);
url = toolsInput; url = toolsInput;
if (tagName) {
const bundleVersion = tryGetBundleVersionFromTagName(tagName, logger);
// If the bundle version is a semantic version, it is a CLI version number.
if (bundleVersion && semver.valid(bundleVersion)) {
cliVersion = convertToSemVer(bundleVersion, logger);
}
}
} else { } else {
// Otherwise, use the default CLI version passed in. // Otherwise, use the default CLI version passed in.
cliVersion = defaultCliVersion.cliVersion; cliVersion = defaultCliVersion.cliVersion;

View file

@ -1,15 +1,32 @@
import { TextDecoder } from "node:util"; import { TextDecoder } from "node:util";
import path from "path";
import * as github from "@actions/github"; import * as github from "@actions/github";
import { TestFn } from "ava"; import { TestFn } from "ava";
import * as nock from "nock"; import nock from "nock";
import * as sinon from "sinon"; import * as sinon from "sinon";
import * as apiClient from "./api-client"; import * as apiClient from "./api-client";
import { GitHubApiDetails } from "./api-client";
import * as CodeQL from "./codeql"; import * as CodeQL from "./codeql";
import { Feature, FeatureEnablement } from "./feature-flags"; import {
CodeQLDefaultVersionInfo,
Feature,
FeatureEnablement,
} from "./feature-flags";
import { Logger } from "./logging"; import { Logger } from "./logging";
import { HTTPError } from "./util"; import { GitHubVariant, HTTPError } from "./util";
export const SAMPLE_DOTCOM_API_DETAILS = {
auth: "token",
url: "https://github.com",
apiURL: "https://api.github.com",
};
export const SAMPLE_DEFAULT_CLI_VERSION: CodeQLDefaultVersionInfo = {
cliVersion: "2.0.0",
variant: GitHubVariant.DOTCOM,
};
type TestContext = { type TestContext = {
stdoutWrite: any; stdoutWrite: any;
@ -212,3 +229,49 @@ export function createFeatures(enabledFeatures: Feature[]): FeatureEnablement {
}, },
}; };
} }
/**
* Mocks the API for downloading the bundle tagged `tagName`.
*
* @returns the download URL for the bundle. This can be passed to the tools parameter of
* `codeql.setupCodeQL`.
*/
export function mockBundleDownloadApi({
apiDetails = SAMPLE_DOTCOM_API_DETAILS,
isPinned,
repo = "github/codeql-action",
platformSpecific = true,
tagName,
}: {
apiDetails?: GitHubApiDetails;
isPinned?: boolean;
repo?: string;
platformSpecific?: boolean;
tagName: string;
}): string {
const platform =
process.platform === "win32"
? "win64"
: process.platform === "linux"
? "linux64"
: "osx64";
const baseUrl = apiDetails?.url ?? "https://example.com";
const relativeUrl = apiDetails
? `/${repo}/releases/download/${tagName}/codeql-bundle${
platformSpecific ? `-${platform}` : ""
}.tar.gz`
: `/download/${tagName}/codeql-bundle.tar.gz`;
nock(baseUrl)
.get(relativeUrl)
.replyWithFile(
200,
path.join(
__dirname,
`/../src/testdata/codeql-bundle${isPinned ? "-pinned" : ""}.tar.gz`
)
);
return `${baseUrl}${relativeUrl}`;
}