mirror of
https://github.com/github/codeql-action.git
synced 2026-10-21 02:01:27 +00:00
Refactor getCodeQLBundleDownloadURL out of setup-codeql
This commit is contained in:
142
lib/entry-points.js
generated
142
lib/entry-points.js
generated
@@ -107096,41 +107096,6 @@ var require_tool_cache = __commonJS({
|
||||
}
|
||||
});
|
||||
|
||||
// node_modules/fast-deep-equal/index.js
|
||||
var require_fast_deep_equal = __commonJS({
|
||||
"node_modules/fast-deep-equal/index.js"(exports2, module2) {
|
||||
"use strict";
|
||||
module2.exports = function equal(a, b) {
|
||||
if (a === b) return true;
|
||||
if (a && b && typeof a == "object" && typeof b == "object") {
|
||||
if (a.constructor !== b.constructor) return false;
|
||||
var length, i, keys;
|
||||
if (Array.isArray(a)) {
|
||||
length = a.length;
|
||||
if (length != b.length) return false;
|
||||
for (i = length; i-- !== 0; )
|
||||
if (!equal(a[i], b[i])) return false;
|
||||
return true;
|
||||
}
|
||||
if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
|
||||
if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
|
||||
if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
|
||||
keys = Object.keys(a);
|
||||
length = keys.length;
|
||||
if (length !== Object.keys(b).length) return false;
|
||||
for (i = length; i-- !== 0; )
|
||||
if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
|
||||
for (i = length; i-- !== 0; ) {
|
||||
var key = keys[i];
|
||||
if (!equal(a[key], b[key])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return a !== a && b !== b;
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// node_modules/follow-redirects/debug.js
|
||||
var require_debug3 = __commonJS({
|
||||
"node_modules/follow-redirects/debug.js"(exports2, module2) {
|
||||
@@ -175290,7 +175255,6 @@ var fs14 = __toESM(require("fs"));
|
||||
var path13 = __toESM(require("path"));
|
||||
var import_perf_hooks4 = require("perf_hooks");
|
||||
var toolcache3 = __toESM(require_tool_cache());
|
||||
var import_fast_deep_equal = __toESM(require_fast_deep_equal());
|
||||
var semver9 = __toESM(require_semver2());
|
||||
|
||||
// src/codeql-bundle.ts
|
||||
@@ -175757,6 +175721,55 @@ function getCodeQLActionRepository(action) {
|
||||
}
|
||||
return action.env.getRequired("GITHUB_ACTION_REPOSITORY" /* GITHUB_ACTION_REPOSITORY */);
|
||||
}
|
||||
var DEFAULT_DOWNLOAD_SOURCE = [
|
||||
GITHUB_DOTCOM_URL,
|
||||
CODEQL_DEFAULT_ACTION_REPOSITORY
|
||||
];
|
||||
var isSameDownloadSource = ([srcUrl, srcRepo], [otherUrl, otherRepo]) => {
|
||||
return srcUrl === otherUrl && srcRepo === otherRepo;
|
||||
};
|
||||
async function getCodeQLAssetDownloadURL(action, apiDetails, tagName, assetName, assetKind = "CodeQL bundle") {
|
||||
const codeQLActionRepository = getCodeQLActionRepository(action);
|
||||
const potentialDownloadSources = [
|
||||
// This GitHub instance, and this Action.
|
||||
[apiDetails.url, codeQLActionRepository],
|
||||
// This GitHub instance, and the canonical Action.
|
||||
[apiDetails.url, CODEQL_DEFAULT_ACTION_REPOSITORY],
|
||||
// GitHub.com, and the canonical Action.
|
||||
DEFAULT_DOWNLOAD_SOURCE
|
||||
];
|
||||
const uniqueDownloadSources = potentialDownloadSources.filter(
|
||||
(source, index2, self2) => {
|
||||
return !self2.slice(0, index2).some((other) => isSameDownloadSource(source, other));
|
||||
}
|
||||
);
|
||||
for (const [apiURL, repository] of uniqueDownloadSources) {
|
||||
if (isSameDownloadSource(DEFAULT_DOWNLOAD_SOURCE, [apiURL, repository])) {
|
||||
break;
|
||||
}
|
||||
const [repositoryOwner, repositoryName] = repository.split("/");
|
||||
try {
|
||||
const release2 = await getApiClient().rest.repos.getReleaseByTag({
|
||||
owner: repositoryOwner,
|
||||
repo: repositoryName,
|
||||
tag: tagName
|
||||
});
|
||||
for (const asset of release2.data.assets) {
|
||||
if (asset.name === assetName) {
|
||||
action.logger.info(
|
||||
`Found ${assetKind} ${assetName} in ${repository} on ${apiURL} with URL ${asset.url}.`
|
||||
);
|
||||
return asset.url;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
action.logger.info(
|
||||
`Looked for ${assetKind} ${assetName} in ${repository} on ${apiURL} but got error ${e}.`
|
||||
);
|
||||
}
|
||||
}
|
||||
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${assetName}`;
|
||||
}
|
||||
|
||||
// src/tar.ts
|
||||
var import_child_process = require("child_process");
|
||||
@@ -176154,52 +176167,6 @@ var CODEQL_NIGHTLIES_REPOSITORY_NAME = "codeql-cli-nightlies";
|
||||
var CODEQL_BUNDLE_VERSION_ALIAS = ["linked", "latest"];
|
||||
var CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"];
|
||||
var CODEQL_TOOLCACHE_INPUT = "toolcache";
|
||||
async function getCodeQLBundleDownloadURL(tagName, apiDetails, codeQLBundleName, logger2) {
|
||||
const codeQLActionRepository = getCodeQLActionRepository({
|
||||
logger: logger2,
|
||||
env: getEnv()
|
||||
});
|
||||
const potentialDownloadSources = [
|
||||
// This GitHub instance, and this Action.
|
||||
[apiDetails.url, codeQLActionRepository],
|
||||
// This GitHub instance, and the canonical Action.
|
||||
[apiDetails.url, CODEQL_DEFAULT_ACTION_REPOSITORY],
|
||||
// GitHub.com, and the canonical Action.
|
||||
[GITHUB_DOTCOM_URL, CODEQL_DEFAULT_ACTION_REPOSITORY]
|
||||
];
|
||||
const uniqueDownloadSources = potentialDownloadSources.filter(
|
||||
(source, index2, self2) => {
|
||||
return !self2.slice(0, index2).some((other) => (0, import_fast_deep_equal.default)(source, other));
|
||||
}
|
||||
);
|
||||
for (const downloadSource of uniqueDownloadSources) {
|
||||
const [apiURL, repository] = downloadSource;
|
||||
if (apiURL === GITHUB_DOTCOM_URL && repository === CODEQL_DEFAULT_ACTION_REPOSITORY) {
|
||||
break;
|
||||
}
|
||||
const [repositoryOwner, repositoryName] = repository.split("/");
|
||||
try {
|
||||
const release2 = await getApiClient().rest.repos.getReleaseByTag({
|
||||
owner: repositoryOwner,
|
||||
repo: repositoryName,
|
||||
tag: tagName
|
||||
});
|
||||
for (const asset of release2.data.assets) {
|
||||
if (asset.name === codeQLBundleName) {
|
||||
logger2.info(
|
||||
`Found CodeQL bundle ${codeQLBundleName} in ${repository} on ${apiURL} with URL ${asset.url}.`
|
||||
);
|
||||
return asset.url;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
logger2.info(
|
||||
`Looked for CodeQL bundle ${codeQLBundleName} in ${repository} on ${apiURL} but got error ${e}.`
|
||||
);
|
||||
}
|
||||
}
|
||||
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${codeQLBundleName}`;
|
||||
}
|
||||
function tryGetBundleVersionFromTagName(tagName, logger2) {
|
||||
const match2 = tagName.match(/^codeql-bundle-(.+)$/);
|
||||
if (match2 === null || match2.length < 2) {
|
||||
@@ -176557,9 +176524,10 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, othe
|
||||
);
|
||||
}
|
||||
compressionMethod = cliVersion2 !== void 0 && await useZstdBundle(cliVersion2, tarSupportsZstd) ? "zstd" : "gzip";
|
||||
const action = { env: getEnv(), logger: logger2 };
|
||||
const platform2 = getBundlePlatform();
|
||||
const perLanguageBundleLanguage = await getPerLanguageBundleLanguage(
|
||||
{ env: getEnv(), features, logger: logger2 },
|
||||
{ ...action, features },
|
||||
{
|
||||
rawLanguages,
|
||||
otherLanguagePacksReason,
|
||||
@@ -176569,11 +176537,11 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, othe
|
||||
variant
|
||||
}
|
||||
);
|
||||
const resolveBundleURL = (language) => getCodeQLBundleDownloadURL(
|
||||
bundleTagName,
|
||||
const resolveBundleURL = (language) => getCodeQLAssetDownloadURL(
|
||||
action,
|
||||
apiDetails,
|
||||
getCodeQLBundleName(compressionMethod, platform2, language),
|
||||
logger2
|
||||
bundleTagName,
|
||||
getCodeQLBundleName(compressionMethod, platform2, language)
|
||||
);
|
||||
const combinedBundleURL = await resolveBundleURL();
|
||||
if (perLanguageBundleLanguage !== void 0) {
|
||||
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -27,7 +27,6 @@
|
||||
"@octokit/plugin-rest-endpoint-methods": "^18.0.0",
|
||||
"@octokit/plugin-retry": "^8.1.1",
|
||||
"archiver": "^8.0.0",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"follow-redirects": "^1.16.0",
|
||||
"get-folder-size": "^5.0.0",
|
||||
"https-proxy-agent": "^7.0.6",
|
||||
@@ -5817,6 +5816,7 @@
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-diff": {
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
"@octokit/plugin-rest-endpoint-methods": "^18.0.0",
|
||||
"@octokit/plugin-retry": "^8.1.1",
|
||||
"archiver": "^8.0.0",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"follow-redirects": "^1.16.0",
|
||||
"get-folder-size": "^5.0.0",
|
||||
"https-proxy-agent": "^7.0.6",
|
||||
|
||||
@@ -4,7 +4,6 @@ import * as path from "path";
|
||||
import { performance } from "perf_hooks";
|
||||
|
||||
import * as toolcache from "@actions/tool-cache";
|
||||
import { default as deepEqual } from "fast-deep-equal";
|
||||
import * as semver from "semver";
|
||||
import { v4 as uuidV4 } from "uuid";
|
||||
|
||||
@@ -35,7 +34,6 @@ import {
|
||||
Feature,
|
||||
FeatureEnablement,
|
||||
} from "./feature-flags";
|
||||
import { GITHUB_DOTCOM_URL } from "./github";
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import { getCodeQlVersionsForOverlayBaseDatabases } from "./overlay/caching";
|
||||
@@ -44,10 +42,7 @@ import {
|
||||
logPerLanguageBundleFallback,
|
||||
} from "./per-language-bundles";
|
||||
import { getBundlePlatform } from "./platform";
|
||||
import {
|
||||
CODEQL_DEFAULT_ACTION_REPOSITORY,
|
||||
getCodeQLActionRepository,
|
||||
} from "./setup/repository";
|
||||
import { getCodeQLAssetDownloadURL } from "./setup/repository";
|
||||
import * as tar from "./tar";
|
||||
import {
|
||||
deleteToolcacheBundles,
|
||||
@@ -76,64 +71,6 @@ const CODEQL_BUNDLE_VERSION_ALIAS: string[] = ["linked", "latest"];
|
||||
const CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"];
|
||||
const CODEQL_TOOLCACHE_INPUT = "toolcache";
|
||||
|
||||
async function getCodeQLBundleDownloadURL(
|
||||
tagName: string,
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
codeQLBundleName: string,
|
||||
logger: Logger,
|
||||
): Promise<string> {
|
||||
const codeQLActionRepository = getCodeQLActionRepository({
|
||||
logger,
|
||||
env: getEnv(),
|
||||
});
|
||||
const potentialDownloadSources = [
|
||||
// This GitHub instance, and this Action.
|
||||
[apiDetails.url, codeQLActionRepository],
|
||||
// This GitHub instance, and the canonical Action.
|
||||
[apiDetails.url, CODEQL_DEFAULT_ACTION_REPOSITORY],
|
||||
// GitHub.com, and the canonical Action.
|
||||
[GITHUB_DOTCOM_URL, CODEQL_DEFAULT_ACTION_REPOSITORY],
|
||||
];
|
||||
// We now filter out any duplicates.
|
||||
// Duplicates will happen either because the GitHub instance is GitHub.com, or because the Action is not a fork.
|
||||
const uniqueDownloadSources = potentialDownloadSources.filter(
|
||||
(source, index, self) => {
|
||||
return !self.slice(0, index).some((other) => deepEqual(source, other));
|
||||
},
|
||||
);
|
||||
for (const downloadSource of uniqueDownloadSources) {
|
||||
const [apiURL, repository] = downloadSource;
|
||||
// If we've reached the final case, short-circuit the API check since we know the bundle exists and is public.
|
||||
if (
|
||||
apiURL === GITHUB_DOTCOM_URL &&
|
||||
repository === CODEQL_DEFAULT_ACTION_REPOSITORY
|
||||
) {
|
||||
break;
|
||||
}
|
||||
const [repositoryOwner, repositoryName] = repository.split("/");
|
||||
try {
|
||||
const release = await api.getApiClient().rest.repos.getReleaseByTag({
|
||||
owner: repositoryOwner,
|
||||
repo: repositoryName,
|
||||
tag: tagName,
|
||||
});
|
||||
for (const asset of release.data.assets) {
|
||||
if (asset.name === codeQLBundleName) {
|
||||
logger.info(
|
||||
`Found CodeQL bundle ${codeQLBundleName} in ${repository} on ${apiURL} with URL ${asset.url}.`,
|
||||
);
|
||||
return asset.url;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
logger.info(
|
||||
`Looked for CodeQL bundle ${codeQLBundleName} in ${repository} on ${apiURL} but got error ${e}.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${codeQLBundleName}`;
|
||||
}
|
||||
|
||||
function tryGetBundleVersionFromTagName(
|
||||
tagName: string,
|
||||
logger: Logger,
|
||||
@@ -712,9 +649,10 @@ export async function getCodeQLSource(
|
||||
? "zstd"
|
||||
: "gzip";
|
||||
|
||||
const action = { env: getEnv(), logger };
|
||||
const platform = getBundlePlatform();
|
||||
const perLanguageBundleLanguage = await getPerLanguageBundleLanguage(
|
||||
{ env: getEnv(), features, logger },
|
||||
{ ...action, features },
|
||||
{
|
||||
rawLanguages,
|
||||
otherLanguagePacksReason,
|
||||
@@ -727,11 +665,11 @@ export async function getCodeQLSource(
|
||||
|
||||
// Resolves the combined or per-language bundle URL for the requested release.
|
||||
const resolveBundleURL = (language?: BuiltInLanguage) =>
|
||||
getCodeQLBundleDownloadURL(
|
||||
bundleTagName,
|
||||
getCodeQLAssetDownloadURL(
|
||||
action,
|
||||
apiDetails,
|
||||
bundleTagName,
|
||||
getCodeQLBundleName(compressionMethod, platform, language),
|
||||
logger,
|
||||
);
|
||||
|
||||
const combinedBundleURL = await resolveBundleURL();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { ActionState } from "../action-common";
|
||||
import { isRunningLocalAction } from "../actions-util";
|
||||
import * as api from "../api-client";
|
||||
import { ActionsEnvVars } from "../environment";
|
||||
import { GITHUB_DOTCOM_URL } from "../github";
|
||||
|
||||
/** The NWO of the standard CodeQL Action repository. */
|
||||
export const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action";
|
||||
@@ -28,3 +30,100 @@ export function getCodeQLActionRepository(
|
||||
|
||||
return action.env.getRequired(ActionsEnvVars.GITHUB_ACTION_REPOSITORY);
|
||||
}
|
||||
|
||||
/**A download source is a pair of strings. */
|
||||
export type DownloadSource = [string, string];
|
||||
|
||||
/** GitHub.com, and the canonical Action. */
|
||||
export const DEFAULT_DOWNLOAD_SOURCE: DownloadSource = [
|
||||
GITHUB_DOTCOM_URL,
|
||||
CODEQL_DEFAULT_ACTION_REPOSITORY,
|
||||
];
|
||||
|
||||
/** Decides if the two provided download sources are the same. */
|
||||
const isSameDownloadSource = (
|
||||
[srcUrl, srcRepo]: DownloadSource,
|
||||
[otherUrl, otherRepo]: DownloadSource,
|
||||
) => {
|
||||
return srcUrl === otherUrl && srcRepo === otherRepo;
|
||||
};
|
||||
|
||||
/** A download URL is represented as a string. */
|
||||
export type DownloadURL = string;
|
||||
|
||||
/**
|
||||
* Tries to find a download URL for `assetName` in a release tagged with `tagName`.
|
||||
*
|
||||
* Depending on where and how the CodeQL Action is running, we may be using different `apiDetails` and there may be
|
||||
* different options for where to source CodeQL releases from.
|
||||
*
|
||||
* This function either returns the download URL for the asset for the first release we find, or
|
||||
* defaults to the assumed download URL for the asset on the default CodeQL Action repository on GitHub.com.
|
||||
* In the latter case, this function does not guarantee that the asset actually exists.
|
||||
*
|
||||
* @param action The Action state.
|
||||
* @param apiDetails The details of the GitHub API in use.
|
||||
* @param tagName The name of the release tag we want to obtain the asset from.
|
||||
* @param assetName The name of the asset we should look for in the release.
|
||||
* @param [assetKind="CodeQL bundle"] The kind of asset we are looking for to show in log messages.
|
||||
* @returns A URL that we can use to download the asset.
|
||||
*/
|
||||
export async function getCodeQLAssetDownloadURL(
|
||||
action: ActionState<["ReadOnlyEnv", "Logger"]>,
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
tagName: string,
|
||||
assetName: string,
|
||||
assetKind: "CodeQL bundle" = "CodeQL bundle",
|
||||
): Promise<DownloadURL> {
|
||||
const codeQLActionRepository = getCodeQLActionRepository(action);
|
||||
|
||||
const potentialDownloadSources: Array<[string, string]> = [
|
||||
// This GitHub instance, and this Action.
|
||||
[apiDetails.url, codeQLActionRepository],
|
||||
// This GitHub instance, and the canonical Action.
|
||||
[apiDetails.url, CODEQL_DEFAULT_ACTION_REPOSITORY],
|
||||
// GitHub.com, and the canonical Action.
|
||||
DEFAULT_DOWNLOAD_SOURCE,
|
||||
];
|
||||
|
||||
// We now filter out any duplicates.
|
||||
// Duplicates will happen either because the GitHub instance is GitHub.com, or because the Action is not a fork.
|
||||
const uniqueDownloadSources = potentialDownloadSources.filter(
|
||||
(source, index, self) => {
|
||||
return !self
|
||||
.slice(0, index)
|
||||
.some((other) => isSameDownloadSource(source, other));
|
||||
},
|
||||
);
|
||||
|
||||
for (const [apiURL, repository] of uniqueDownloadSources) {
|
||||
// If we've reached the final case, short-circuit the API check since we know the bundle exists and is public.
|
||||
if (isSameDownloadSource(DEFAULT_DOWNLOAD_SOURCE, [apiURL, repository])) {
|
||||
break;
|
||||
}
|
||||
|
||||
const [repositoryOwner, repositoryName] = repository.split("/");
|
||||
try {
|
||||
const release = await api.getApiClient().rest.repos.getReleaseByTag({
|
||||
owner: repositoryOwner,
|
||||
repo: repositoryName,
|
||||
tag: tagName,
|
||||
});
|
||||
|
||||
for (const asset of release.data.assets) {
|
||||
if (asset.name === assetName) {
|
||||
action.logger.info(
|
||||
`Found ${assetKind} ${assetName} in ${repository} on ${apiURL} with URL ${asset.url}.`,
|
||||
);
|
||||
return asset.url;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
action.logger.info(
|
||||
`Looked for ${assetKind} ${assetName} in ${repository} on ${apiURL} but got error ${e}.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${assetName}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user