mirror of
https://github.com/github/codeql-action.git
synced 2026-01-05 06:00:32 +08:00
Merge remote-tracking branch 'upstream/main' into aeisenberg/qlconfig-in-cli
This commit is contained in:
@@ -143,7 +143,6 @@ async function installIntoToolcache({
|
||||
apiDetails,
|
||||
tmpDir,
|
||||
util.GitHubVariant.GHES,
|
||||
false,
|
||||
cliVersion !== undefined
|
||||
? { cliVersion, tagName, variant: util.GitHubVariant.GHES }
|
||||
: SAMPLE_DEFAULT_CLI_VERSION,
|
||||
@@ -205,7 +204,6 @@ test("downloads and caches explicitly requested bundles that aren't in the toolc
|
||||
sampleApiDetails,
|
||||
tmpDir,
|
||||
util.GitHubVariant.DOTCOM,
|
||||
false,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
getRunnerLogger(true),
|
||||
false
|
||||
@@ -239,7 +237,6 @@ test("downloads an explicitly requested bundle even if a different version is ca
|
||||
sampleApiDetails,
|
||||
tmpDir,
|
||||
util.GitHubVariant.DOTCOM,
|
||||
false,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
getRunnerLogger(true),
|
||||
false
|
||||
@@ -290,7 +287,6 @@ for (const {
|
||||
sampleApiDetails,
|
||||
tmpDir,
|
||||
util.GitHubVariant.DOTCOM,
|
||||
false,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
getRunnerLogger(true),
|
||||
false
|
||||
@@ -358,7 +354,6 @@ for (const { githubReleases, toolcacheVersion } of [
|
||||
sampleApiDetails,
|
||||
tmpDir,
|
||||
util.GitHubVariant.DOTCOM,
|
||||
false,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
getRunnerLogger(true),
|
||||
false
|
||||
@@ -387,7 +382,6 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
|
||||
sampleApiDetails,
|
||||
tmpDir,
|
||||
variant,
|
||||
false,
|
||||
{
|
||||
cliVersion: defaults.cliVersion,
|
||||
tagName: defaults.bundleVersion,
|
||||
@@ -423,7 +417,6 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
|
||||
sampleApiDetails,
|
||||
tmpDir,
|
||||
variant,
|
||||
false,
|
||||
{
|
||||
cliVersion: defaults.cliVersion,
|
||||
tagName: defaults.bundleVersion,
|
||||
@@ -460,7 +453,6 @@ test('downloads bundle if "latest" tools specified but not cached', async (t) =>
|
||||
sampleApiDetails,
|
||||
tmpDir,
|
||||
util.GitHubVariant.DOTCOM,
|
||||
false,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
getRunnerLogger(true),
|
||||
false
|
||||
@@ -533,7 +525,6 @@ for (const isBundleVersionInUrl of [true, false]) {
|
||||
sampleGHAEApiDetails,
|
||||
tmpDir,
|
||||
util.GitHubVariant.GHAE,
|
||||
false,
|
||||
{
|
||||
cliVersion: defaults.cliVersion,
|
||||
tagName: defaults.bundleVersion,
|
||||
@@ -573,7 +564,6 @@ test("bundle URL from another repo is cached as 0.0.0-bundleVersion", async (t)
|
||||
sampleApiDetails,
|
||||
tmpDir,
|
||||
util.GitHubVariant.DOTCOM,
|
||||
false,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
getRunnerLogger(true),
|
||||
false
|
||||
|
||||
@@ -296,7 +296,6 @@ export const CODEQL_VERSION_INIT_WITH_QLCONFIG = "2.12.3";
|
||||
* @param apiDetails
|
||||
* @param tempDir
|
||||
* @param variant
|
||||
* @param bypassToolcache
|
||||
* @param defaultCliVersion
|
||||
* @param logger
|
||||
* @param checkVersion Whether to check that CodeQL CLI meets the minimum
|
||||
@@ -308,7 +307,6 @@ export async function setupCodeQL(
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
tempDir: string,
|
||||
variant: util.GitHubVariant,
|
||||
bypassToolcache: boolean,
|
||||
defaultCliVersion: CodeQLDefaultVersionInfo,
|
||||
logger: Logger,
|
||||
checkVersion: boolean
|
||||
@@ -325,7 +323,6 @@ export async function setupCodeQL(
|
||||
apiDetails,
|
||||
tempDir,
|
||||
variant,
|
||||
bypassToolcache,
|
||||
defaultCliVersion,
|
||||
logger
|
||||
);
|
||||
|
||||
@@ -34,8 +34,6 @@ export interface FeatureEnablement {
|
||||
}
|
||||
|
||||
export enum Feature {
|
||||
BypassToolcacheEnabled = "bypass_toolcache_enabled",
|
||||
BypassToolcacheKotlinSwiftEnabled = "bypass_toolcache_kotlin_swift_enabled",
|
||||
CliConfigFileEnabled = "cli_config_file_enabled",
|
||||
DisableKotlinAnalysisEnabled = "disable_kotlin_analysis_enabled",
|
||||
MlPoweredQueriesEnabled = "ml_powered_queries_enabled",
|
||||
@@ -47,18 +45,6 @@ export const featureConfig: Record<
|
||||
Feature,
|
||||
{ envVar: string; minimumVersion: string | undefined }
|
||||
> = {
|
||||
[Feature.BypassToolcacheEnabled]: {
|
||||
envVar: "CODEQL_BYPASS_TOOLCACHE",
|
||||
// Cannot specify a minimum version because this flag is checked before we have
|
||||
// access to the CodeQL instance.
|
||||
minimumVersion: undefined,
|
||||
},
|
||||
[Feature.BypassToolcacheKotlinSwiftEnabled]: {
|
||||
envVar: "CODEQL_BYPASS_TOOLCACHE_KOTLIN_SWIFT",
|
||||
// Cannot specify a minimum version because this flag is checked before we have
|
||||
// access to the CodeQL instance.
|
||||
minimumVersion: undefined,
|
||||
},
|
||||
[Feature.DisableKotlinAnalysisEnabled]: {
|
||||
envVar: "CODEQL_DISABLE_KOTLIN_ANALYSIS",
|
||||
minimumVersion: undefined,
|
||||
@@ -138,11 +124,6 @@ export class Features implements FeatureEnablement {
|
||||
);
|
||||
}
|
||||
|
||||
// Bypassing the toolcache is disabled in test mode.
|
||||
if (feature === Feature.BypassToolcacheEnabled && util.isInTestMode()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const envVar = (
|
||||
process.env[featureConfig[feature].envVar] || ""
|
||||
).toLocaleLowerCase();
|
||||
|
||||
@@ -43,7 +43,6 @@ import {
|
||||
GitHubVariant,
|
||||
initializeEnvironment,
|
||||
isHostedRunner,
|
||||
shouldBypassToolcache,
|
||||
} from "./util";
|
||||
import { validateWorkflow } from "./workflow";
|
||||
|
||||
@@ -239,13 +238,6 @@ async function run() {
|
||||
apiDetails,
|
||||
getTemporaryDirectory(),
|
||||
gitHubVersion.type,
|
||||
await shouldBypassToolcache(
|
||||
features,
|
||||
getOptionalInput("tools"),
|
||||
getOptionalInput("languages"),
|
||||
repositoryNwo,
|
||||
logger
|
||||
),
|
||||
codeQLDefaultVersionInfo,
|
||||
logger
|
||||
);
|
||||
|
||||
@@ -27,7 +27,6 @@ export async function initCodeQL(
|
||||
apiDetails: GitHubApiDetails,
|
||||
tempDir: string,
|
||||
variant: util.GitHubVariant,
|
||||
bypassToolcache: boolean,
|
||||
defaultCliVersion: CodeQLDefaultVersionInfo,
|
||||
logger: Logger
|
||||
): Promise<{
|
||||
@@ -43,7 +42,6 @@ export async function initCodeQL(
|
||||
apiDetails,
|
||||
tempDir,
|
||||
variant,
|
||||
bypassToolcache,
|
||||
defaultCliVersion,
|
||||
logger,
|
||||
true
|
||||
|
||||
@@ -21,8 +21,6 @@ export const LANGUAGE_ALIASES: { [lang: string]: Language } = {
|
||||
|
||||
export type LanguageOrAlias = Language | keyof typeof LANGUAGE_ALIASES;
|
||||
|
||||
export const KOTLIN_SWIFT_BYPASS = ["kotlin", "swift"];
|
||||
|
||||
export function resolveAlias(lang: LanguageOrAlias): Language {
|
||||
return LANGUAGE_ALIASES[lang] || lang;
|
||||
}
|
||||
|
||||
@@ -354,7 +354,6 @@ async function findOverridingToolsInCache(
|
||||
|
||||
export async function getCodeQLSource(
|
||||
toolsInput: string | undefined,
|
||||
bypassToolcache: boolean,
|
||||
defaultCliVersion: CodeQLDefaultVersionInfo,
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
variant: util.GitHubVariant,
|
||||
@@ -368,25 +367,18 @@ export async function getCodeQLSource(
|
||||
};
|
||||
}
|
||||
|
||||
/** The reason why the tools shipped with the Action have been forced. */
|
||||
const forceShippedToolsReason =
|
||||
// We use the special value of 'latest' to prioritize the version in the
|
||||
// defaults over any pinned cached version.
|
||||
toolsInput === "latest"
|
||||
? '"tools: latest" was requested'
|
||||
: // If the user hasn't requested a particular CodeQL version, then bypass
|
||||
// the toolcache when the appropriate feature is enabled. This
|
||||
// allows us to quickly rollback a broken bundle that has made its way
|
||||
// into the toolcache.
|
||||
toolsInput === undefined && bypassToolcache
|
||||
? "a specific version of the CodeQL tools was not requested and the bypass toolcache feature is enabled"
|
||||
: undefined;
|
||||
/** Whether the tools shipped with the Action, i.e. those in `defaults.json`, have been forced. */
|
||||
const forceShippedTools = forceShippedToolsReason !== undefined;
|
||||
/**
|
||||
* Whether the tools shipped with the Action, i.e. those in `defaults.json`, have been forced.
|
||||
*
|
||||
* We use the special value of 'latest' to prioritize the version in `defaults.json` over the
|
||||
* version specified by the feature flags on Dotcom and over any pinned cached version on
|
||||
* Enterprise Server.
|
||||
*/
|
||||
const forceShippedTools = toolsInput === "latest";
|
||||
if (forceShippedTools) {
|
||||
logger.info(
|
||||
"Overriding the version of the CodeQL tools by the version shipped with the Action since " +
|
||||
`${forceShippedToolsReason}.`
|
||||
`"tools: latest" was requested.`
|
||||
);
|
||||
}
|
||||
|
||||
@@ -714,7 +706,6 @@ export function getCodeQLURLVersion(url: string): string {
|
||||
* @param apiDetails
|
||||
* @param tempDir
|
||||
* @param variant
|
||||
* @param bypassToolcache
|
||||
* @param defaultCliVersion
|
||||
* @param logger
|
||||
* @param checkVersion Whether to check that CodeQL CLI meets the minimum
|
||||
@@ -726,7 +717,6 @@ export async function setupCodeQLBundle(
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
tempDir: string,
|
||||
variant: util.GitHubVariant,
|
||||
bypassToolcache: boolean,
|
||||
defaultCliVersion: CodeQLDefaultVersionInfo,
|
||||
logger: Logger
|
||||
): Promise<{
|
||||
@@ -737,7 +727,6 @@ export async function setupCodeQLBundle(
|
||||
}> {
|
||||
const source = await getCodeQLSource(
|
||||
toolsInput,
|
||||
bypassToolcache,
|
||||
defaultCliVersion,
|
||||
apiDetails,
|
||||
variant,
|
||||
|
||||
128
src/util.test.ts
128
src/util.test.ts
@@ -8,14 +8,8 @@ import * as sinon from "sinon";
|
||||
|
||||
import * as api from "./api-client";
|
||||
import { Config } from "./config-utils";
|
||||
import { Feature } from "./feature-flags";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import { parseRepositoryNwo } from "./repository";
|
||||
import {
|
||||
createFeatures,
|
||||
mockLanguagesInRepo,
|
||||
setupTests,
|
||||
} from "./testing-utils";
|
||||
import { setupTests } from "./testing-utils";
|
||||
import * as util from "./util";
|
||||
|
||||
setupTests(test);
|
||||
@@ -398,123 +392,3 @@ test("withTimeout doesn't call callback if promise resolves", async (t) => {
|
||||
t.deepEqual(shortTaskTimedOut, false);
|
||||
t.deepEqual(result, 99);
|
||||
});
|
||||
|
||||
const mockRepositoryNwo = parseRepositoryNwo("owner/repo");
|
||||
// eslint-disable-next-line github/array-foreach
|
||||
[
|
||||
{
|
||||
name: "disabled",
|
||||
features: [],
|
||||
hasCustomCodeQL: false,
|
||||
languagesInput: undefined,
|
||||
languagesInRepository: [],
|
||||
expected: false,
|
||||
expectedApiCall: false,
|
||||
},
|
||||
{
|
||||
name: "disabled even though swift kotlin bypassed",
|
||||
features: [Feature.BypassToolcacheKotlinSwiftEnabled],
|
||||
hasCustomCodeQL: false,
|
||||
languagesInput: undefined,
|
||||
languagesInRepository: [],
|
||||
expected: false,
|
||||
expectedApiCall: true,
|
||||
},
|
||||
{
|
||||
name: "disabled even though swift kotlin analyzed",
|
||||
features: [],
|
||||
hasCustomCodeQL: false,
|
||||
languagesInput: " sWiFt , KoTlIn ",
|
||||
languagesInRepository: [],
|
||||
expected: false,
|
||||
expectedApiCall: false,
|
||||
},
|
||||
{
|
||||
name: "toolcache bypass all",
|
||||
features: [Feature.BypassToolcacheEnabled],
|
||||
hasCustomCodeQL: false,
|
||||
languagesInput: undefined,
|
||||
languagesInRepository: [],
|
||||
expected: true,
|
||||
expectedApiCall: false,
|
||||
},
|
||||
{
|
||||
name: "custom CodeQL",
|
||||
features: [],
|
||||
hasCustomCodeQL: true,
|
||||
languagesInput: undefined,
|
||||
languagesInRepository: [],
|
||||
expected: true,
|
||||
expectedApiCall: false,
|
||||
},
|
||||
{
|
||||
name: "bypass swift",
|
||||
features: [Feature.BypassToolcacheKotlinSwiftEnabled],
|
||||
hasCustomCodeQL: false,
|
||||
languagesInput: " sWiFt ,other",
|
||||
languagesInRepository: [],
|
||||
expected: true,
|
||||
expectedApiCall: false,
|
||||
},
|
||||
{
|
||||
name: "bypass kotlin",
|
||||
features: [Feature.BypassToolcacheKotlinSwiftEnabled],
|
||||
hasCustomCodeQL: false,
|
||||
languagesInput: "other, KoTlIn ",
|
||||
languagesInRepository: [],
|
||||
expected: true,
|
||||
expectedApiCall: false,
|
||||
},
|
||||
{
|
||||
name: "bypass kotlin language from repository",
|
||||
features: [Feature.BypassToolcacheKotlinSwiftEnabled],
|
||||
hasCustomCodeQL: false,
|
||||
languagesInput: "",
|
||||
languagesInRepository: ["KoTlIn", "other"],
|
||||
expected: true,
|
||||
expectedApiCall: true,
|
||||
},
|
||||
{
|
||||
name: "bypass swift language from repository",
|
||||
features: [Feature.BypassToolcacheKotlinSwiftEnabled],
|
||||
hasCustomCodeQL: false,
|
||||
languagesInput: "",
|
||||
languagesInRepository: ["SwiFt", "other"],
|
||||
expected: true,
|
||||
expectedApiCall: true,
|
||||
},
|
||||
{
|
||||
name: "bypass java from input if there is kotlin in repository",
|
||||
features: [Feature.BypassToolcacheKotlinSwiftEnabled],
|
||||
hasCustomCodeQL: false,
|
||||
languagesInput: "java",
|
||||
languagesInRepository: ["kotlin", "other"],
|
||||
expected: true,
|
||||
expectedApiCall: true,
|
||||
},
|
||||
{
|
||||
name: "don't bypass java from input if there is no kotlin in repository",
|
||||
features: [Feature.BypassToolcacheKotlinSwiftEnabled],
|
||||
hasCustomCodeQL: false,
|
||||
languagesInput: "java",
|
||||
languagesInRepository: ["java", "other"],
|
||||
expected: false,
|
||||
expectedApiCall: true,
|
||||
},
|
||||
].forEach((args) => {
|
||||
test(`shouldBypassToolcache: ${args.name}`, async (t) => {
|
||||
const mockRequest = mockLanguagesInRepo(args.languagesInRepository);
|
||||
const mockLogger = getRunnerLogger(true);
|
||||
const featureEnablement = createFeatures(args.features);
|
||||
const codeqlUrl = args.hasCustomCodeQL ? "custom-codeql-url" : undefined;
|
||||
const actual = await util.shouldBypassToolcache(
|
||||
featureEnablement,
|
||||
codeqlUrl,
|
||||
args.languagesInput,
|
||||
mockRepositoryNwo,
|
||||
mockLogger
|
||||
);
|
||||
t.deepEqual(actual, args.expected);
|
||||
t.deepEqual(mockRequest.called, args.expectedApiCall);
|
||||
});
|
||||
});
|
||||
|
||||
63
src/util.ts
63
src/util.ts
@@ -13,15 +13,12 @@ import * as apiCompatibility from "./api-compatibility.json";
|
||||
import { CodeQL, CODEQL_VERSION_NEW_TRACING } from "./codeql";
|
||||
import {
|
||||
Config,
|
||||
getLanguagesInRepo,
|
||||
getRawLanguages,
|
||||
parsePacksSpecification,
|
||||
prettyPrintPack,
|
||||
} from "./config-utils";
|
||||
import { Feature, FeatureEnablement } from "./feature-flags";
|
||||
import { KOTLIN_SWIFT_BYPASS, Language } from "./languages";
|
||||
import { Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import { RepositoryNwo } from "./repository";
|
||||
import { CODEQL_ACTION_TEST_MODE } from "./shared-environment";
|
||||
|
||||
/**
|
||||
@@ -802,64 +799,6 @@ export function isHostedRunner() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param featuresEnablement The features enabled for the current run
|
||||
* @param languagesInput Languages input from the workflow
|
||||
* @param repository The owner/name of the repository
|
||||
* @param logger A logger
|
||||
* @returns A boolean indicating whether or not the toolcache should be bypassed
|
||||
* and the latest codeql should be downloaded.
|
||||
*/
|
||||
export async function shouldBypassToolcache(
|
||||
featuresEnablement: FeatureEnablement,
|
||||
codeqlUrl: string | undefined,
|
||||
languagesInput: string | undefined,
|
||||
repository: RepositoryNwo,
|
||||
logger: Logger
|
||||
): Promise<boolean> {
|
||||
// An explicit codeql url is specified, that means the toolcache will not be used.
|
||||
if (codeqlUrl) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if the toolcache is disabled for all languages
|
||||
if (await featuresEnablement.getValue(Feature.BypassToolcacheEnabled)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if the toolcache is disabled for kotlin and swift.
|
||||
if (
|
||||
!(await featuresEnablement.getValue(
|
||||
Feature.BypassToolcacheKotlinSwiftEnabled
|
||||
))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now check to see if kotlin or swift is one of the languages being analyzed.
|
||||
const { rawLanguages, autodetected } = await getRawLanguages(
|
||||
languagesInput,
|
||||
repository,
|
||||
logger
|
||||
);
|
||||
let bypass = rawLanguages.some((lang) => KOTLIN_SWIFT_BYPASS.includes(lang));
|
||||
if (bypass) {
|
||||
logger.info(
|
||||
`Bypassing toolcache for kotlin or swift. Languages: ${rawLanguages}`
|
||||
);
|
||||
} else if (!autodetected && rawLanguages.includes(Language.java)) {
|
||||
// special case: java was explicitly specified, but there might be
|
||||
// some kotlin in the repository, so we need to make a request for that.
|
||||
const langsInRepo = await getLanguagesInRepo(repository, logger);
|
||||
if (langsInRepo.includes("kotlin")) {
|
||||
logger.info(`Bypassing toolcache for kotlin.`);
|
||||
bypass = true;
|
||||
}
|
||||
}
|
||||
return bypass;
|
||||
}
|
||||
|
||||
export function parseMatrixInput(
|
||||
matrixInput: string | undefined
|
||||
): { [key: string]: string } | undefined {
|
||||
|
||||
Reference in New Issue
Block a user