mirror of
https://github.com/github/codeql-action
synced 2026-05-25 15:00:36 +03:00
Add analysis-kinds input and parse it
This commit is contained in:
@@ -42,6 +42,19 @@ inputs:
|
||||
your workflow between the `init` and `analyze` steps. Available for all
|
||||
compiled languages.
|
||||
required: false
|
||||
analysis-kinds:
|
||||
description: >-
|
||||
[Internal] A comma-separated list of analysis kinds to enable. This input is intended for
|
||||
internal-use only at this time and the behaviour is subject to changes. Some features may
|
||||
not be available depending on which analysis kinds are enabled.
|
||||
|
||||
Available options are:
|
||||
|
||||
- `code-scanning`: The default, security-focused analysis.
|
||||
- `code-quality`: Analysis focused on code quality. This must be enabled in conjunction
|
||||
with `code-scanning`.
|
||||
default: 'code-scanning'
|
||||
required: true
|
||||
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 }}
|
||||
|
||||
Generated
+26
-1
@@ -1,9 +1,34 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AnalysisKind = void 0;
|
||||
exports.supportedAnalysisKinds = exports.AnalysisKind = void 0;
|
||||
exports.parseAnalysisKinds = parseAnalysisKinds;
|
||||
const util_1 = require("./util");
|
||||
var AnalysisKind;
|
||||
(function (AnalysisKind) {
|
||||
AnalysisKind["CodeScanning"] = "code-scanning";
|
||||
AnalysisKind["CodeQuality"] = "code-quality";
|
||||
})(AnalysisKind || (exports.AnalysisKind = AnalysisKind = {}));
|
||||
// Exported for testing. A set of all known analysis kinds.
|
||||
exports.supportedAnalysisKinds = new Set(Object.values(AnalysisKind));
|
||||
/**
|
||||
* Parses a comma-separated string into a list of unique analysis kinds.
|
||||
* Throws a configuration error if the input contains unknown analysis kinds
|
||||
* or doesn't contain at least one element.
|
||||
*
|
||||
* @param input The comma-separated string to parse.
|
||||
* @returns The array of unique analysis kinds that were parsed from the input string.
|
||||
*/
|
||||
async function parseAnalysisKinds(input) {
|
||||
const components = input.split(",");
|
||||
if (components.length < 1) {
|
||||
throw new util_1.ConfigurationError("At least one analysis kind must be configured.");
|
||||
}
|
||||
for (const component of components) {
|
||||
if (!exports.supportedAnalysisKinds.has(component)) {
|
||||
throw new util_1.ConfigurationError(`Unknown analysis kind: ${component}`);
|
||||
}
|
||||
}
|
||||
// Return all unique elements.
|
||||
return Array.from(new Set(components.map((component) => component)));
|
||||
}
|
||||
//# sourceMappingURL=analyses.js.map
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"analyses.js","sourceRoot":"","sources":["../src/analyses.ts"],"names":[],"mappings":";;;AAAA,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,8CAA8B,CAAA;IAC9B,4CAA4B,CAAA;AAC9B,CAAC,EAHW,YAAY,4BAAZ,YAAY,QAGvB"}
|
||||
{"version":3,"file":"analyses.js","sourceRoot":"","sources":["../src/analyses.ts"],"names":[],"mappings":";;;AAkBA,gDAqBC;AAvCD,iCAA4C;AAE5C,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,8CAA8B,CAAA;IAC9B,4CAA4B,CAAA;AAC9B,CAAC,EAHW,YAAY,4BAAZ,YAAY,QAGvB;AAED,2DAA2D;AAC9C,QAAA,sBAAsB,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;AAE3E;;;;;;;GAOG;AACI,KAAK,UAAU,kBAAkB,CACtC,KAAa;IAEb,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEpC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,yBAAkB,CAC1B,gDAAgD,CACjD,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,CAAC,8BAAsB,CAAC,GAAG,CAAC,SAAyB,CAAC,EAAE,CAAC;YAC3D,MAAM,IAAI,yBAAkB,CAAC,0BAA0B,SAAS,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,8BAA8B;IAC9B,OAAO,KAAK,CAAC,IAAI,CACf,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAyB,CAAC,CAAC,CAClE,CAAC;AACJ,CAAC"}
|
||||
Generated
+31
@@ -0,0 +1,31 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const analyses_1 = require("./analyses");
|
||||
const util_1 = require("./util");
|
||||
(0, ava_1.default)("All known analysis kinds can be parsed successfully", async (t) => {
|
||||
for (const analysisKind of analyses_1.supportedAnalysisKinds) {
|
||||
t.deepEqual(await (0, analyses_1.parseAnalysisKinds)(analysisKind), [analysisKind]);
|
||||
}
|
||||
});
|
||||
(0, ava_1.default)("Parsing analysis kinds returns unique results", async (t) => {
|
||||
const analysisKinds = await (0, analyses_1.parseAnalysisKinds)("code-scanning,code-quality,code-scanning");
|
||||
t.deepEqual(analysisKinds, [
|
||||
analyses_1.AnalysisKind.CodeScanning,
|
||||
analyses_1.AnalysisKind.CodeQuality,
|
||||
]);
|
||||
});
|
||||
(0, ava_1.default)("Parsing an unknown analysis kind fails with a configuration error", async (t) => {
|
||||
await t.throwsAsync((0, analyses_1.parseAnalysisKinds)("code-scanning,foo"), {
|
||||
instanceOf: util_1.ConfigurationError,
|
||||
});
|
||||
});
|
||||
(0, ava_1.default)("Parsing analysis kinds requires at least one analysis kind", async (t) => {
|
||||
await t.throwsAsync((0, analyses_1.parseAnalysisKinds)(","), {
|
||||
instanceOf: util_1.ConfigurationError,
|
||||
});
|
||||
});
|
||||
//# sourceMappingURL=analyses.test.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"analyses.test.js","sourceRoot":"","sources":["../src/analyses.test.ts"],"names":[],"mappings":";;;;;AAAA,8CAAuB;AAEvB,yCAIoB;AACpB,iCAA4C;AAE5C,IAAA,aAAI,EAAC,qDAAqD,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACtE,KAAK,MAAM,YAAY,IAAI,iCAAsB,EAAE,CAAC;QAClD,CAAC,CAAC,SAAS,CAAC,MAAM,IAAA,6BAAkB,EAAC,YAAY,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IACtE,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,+CAA+C,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAChE,MAAM,aAAa,GAAG,MAAM,IAAA,6BAAkB,EAC5C,0CAA0C,CAC3C,CAAC;IACF,CAAC,CAAC,SAAS,CAAC,aAAa,EAAE;QACzB,uBAAY,CAAC,YAAY;QACzB,uBAAY,CAAC,WAAW;KACzB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,mEAAmE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACpF,MAAM,CAAC,CAAC,WAAW,CAAC,IAAA,6BAAkB,EAAC,mBAAmB,CAAC,EAAE;QAC3D,UAAU,EAAE,yBAAkB;KAC/B,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,4DAA4D,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC7E,MAAM,CAAC,CAAC,WAAW,CAAC,IAAA,6BAAkB,EAAC,GAAG,CAAC,EAAE;QAC3C,UAAU,EAAE,yBAAkB;KAC/B,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
||||
Generated
+4
-1
@@ -69,6 +69,7 @@ const perf_hooks_1 = require("perf_hooks");
|
||||
const yaml = __importStar(require("js-yaml"));
|
||||
const semver = __importStar(require("semver"));
|
||||
const actions_util_1 = require("./actions-util");
|
||||
const analyses_1 = require("./analyses");
|
||||
const api = __importStar(require("./api-client"));
|
||||
const caching_utils_1 = require("./caching-utils");
|
||||
const diff_informed_analysis_utils_1 = require("./diff-informed-analysis-utils");
|
||||
@@ -263,12 +264,14 @@ async function getRawLanguages(languagesInput, repository, sourceRoot, logger) {
|
||||
/**
|
||||
* Get the default config, populated without user configuration file.
|
||||
*/
|
||||
async function getDefaultConfig({ languagesInput, queriesInput, qualityQueriesInput, packsInput, buildModeInput, dbLocation, trapCachingEnabled, dependencyCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeql, sourceRoot, githubVersion, features, logger, }) {
|
||||
async function getDefaultConfig({ analysisKindsInput, languagesInput, queriesInput, qualityQueriesInput, packsInput, buildModeInput, dbLocation, trapCachingEnabled, dependencyCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeql, sourceRoot, githubVersion, features, logger, }) {
|
||||
const analysisKinds = await (0, analyses_1.parseAnalysisKinds)(analysisKindsInput);
|
||||
const languages = await getLanguages(codeql, languagesInput, repository, sourceRoot, logger);
|
||||
const buildMode = await parseBuildModeInput(buildModeInput, languages, features, logger);
|
||||
const augmentationProperties = await calculateAugmentation(packsInput, queriesInput, qualityQueriesInput, languages);
|
||||
const { trapCaches, trapCacheDownloadTime } = await downloadCacheWithTime(trapCachingEnabled, codeql, languages, logger);
|
||||
return {
|
||||
analysisKinds,
|
||||
languages,
|
||||
buildMode,
|
||||
originalUserInput: {},
|
||||
|
||||
File diff suppressed because one or more lines are too long
Generated
+3
@@ -43,6 +43,7 @@ const ava_1 = __importDefault(require("ava"));
|
||||
const yaml = __importStar(require("js-yaml"));
|
||||
const sinon = __importStar(require("sinon"));
|
||||
const actionsUtil = __importStar(require("./actions-util"));
|
||||
const analyses_1 = require("./analyses");
|
||||
const api = __importStar(require("./api-client"));
|
||||
const caching_utils_1 = require("./caching-utils");
|
||||
const codeql_1 = require("./codeql");
|
||||
@@ -59,6 +60,7 @@ const util_1 = require("./util");
|
||||
const githubVersion = { type: util_1.GitHubVariant.DOTCOM };
|
||||
function createTestInitConfigInputs(overrides) {
|
||||
return Object.assign({}, {
|
||||
analysisKindsInput: "code-scanning",
|
||||
languagesInput: undefined,
|
||||
queriesInput: undefined,
|
||||
qualityQueriesInput: undefined,
|
||||
@@ -272,6 +274,7 @@ function mockListLanguages(languages) {
|
||||
fs.mkdirSync(path.join(tempDir, "foo"));
|
||||
// And the config we expect it to parse to
|
||||
const expectedConfig = {
|
||||
analysisKinds: [analyses_1.AnalysisKind.CodeScanning],
|
||||
languages: [languages_1.KnownLanguage.javascript],
|
||||
buildMode: util_1.BuildMode.None,
|
||||
originalUserInput: {
|
||||
|
||||
File diff suppressed because one or more lines are too long
Generated
+1
@@ -218,6 +218,7 @@ async function run() {
|
||||
}
|
||||
}
|
||||
config = await (0, init_1.initConfig)({
|
||||
analysisKindsInput: (0, actions_util_1.getRequiredInput)("analysis-kinds"),
|
||||
languagesInput: (0, actions_util_1.getOptionalInput)("languages"),
|
||||
queriesInput: (0, actions_util_1.getOptionalInput)("queries"),
|
||||
qualityQueriesInput: (0, actions_util_1.getOptionalInput)("quality-queries"),
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,36 @@
|
||||
import test from "ava";
|
||||
|
||||
import {
|
||||
AnalysisKind,
|
||||
parseAnalysisKinds,
|
||||
supportedAnalysisKinds,
|
||||
} from "./analyses";
|
||||
import { ConfigurationError } from "./util";
|
||||
|
||||
test("All known analysis kinds can be parsed successfully", async (t) => {
|
||||
for (const analysisKind of supportedAnalysisKinds) {
|
||||
t.deepEqual(await parseAnalysisKinds(analysisKind), [analysisKind]);
|
||||
}
|
||||
});
|
||||
|
||||
test("Parsing analysis kinds returns unique results", async (t) => {
|
||||
const analysisKinds = await parseAnalysisKinds(
|
||||
"code-scanning,code-quality,code-scanning",
|
||||
);
|
||||
t.deepEqual(analysisKinds, [
|
||||
AnalysisKind.CodeScanning,
|
||||
AnalysisKind.CodeQuality,
|
||||
]);
|
||||
});
|
||||
|
||||
test("Parsing an unknown analysis kind fails with a configuration error", async (t) => {
|
||||
await t.throwsAsync(parseAnalysisKinds("code-scanning,foo"), {
|
||||
instanceOf: ConfigurationError,
|
||||
});
|
||||
});
|
||||
|
||||
test("Parsing analysis kinds requires at least one analysis kind", async (t) => {
|
||||
await t.throwsAsync(parseAnalysisKinds(","), {
|
||||
instanceOf: ConfigurationError,
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,40 @@
|
||||
import { ConfigurationError } from "./util";
|
||||
|
||||
export enum AnalysisKind {
|
||||
CodeScanning = "code-scanning",
|
||||
CodeQuality = "code-quality",
|
||||
}
|
||||
|
||||
// Exported for testing. A set of all known analysis kinds.
|
||||
export const supportedAnalysisKinds = new Set(Object.values(AnalysisKind));
|
||||
|
||||
/**
|
||||
* Parses a comma-separated string into a list of unique analysis kinds.
|
||||
* Throws a configuration error if the input contains unknown analysis kinds
|
||||
* or doesn't contain at least one element.
|
||||
*
|
||||
* @param input The comma-separated string to parse.
|
||||
* @returns The array of unique analysis kinds that were parsed from the input string.
|
||||
*/
|
||||
export async function parseAnalysisKinds(
|
||||
input: string,
|
||||
): Promise<AnalysisKind[]> {
|
||||
const components = input.split(",");
|
||||
|
||||
if (components.length < 1) {
|
||||
throw new ConfigurationError(
|
||||
"At least one analysis kind must be configured.",
|
||||
);
|
||||
}
|
||||
|
||||
for (const component of components) {
|
||||
if (!supportedAnalysisKinds.has(component as AnalysisKind)) {
|
||||
throw new ConfigurationError(`Unknown analysis kind: ${component}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Return all unique elements.
|
||||
return Array.from(
|
||||
new Set(components.map((component) => component as AnalysisKind)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import * as yaml from "js-yaml";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import { AnalysisKind } from "./analyses";
|
||||
import * as api from "./api-client";
|
||||
import { CachingKind } from "./caching-utils";
|
||||
import { createStubCodeQL } from "./codeql";
|
||||
@@ -47,6 +48,7 @@ function createTestInitConfigInputs(
|
||||
return Object.assign(
|
||||
{},
|
||||
{
|
||||
analysisKindsInput: "code-scanning",
|
||||
languagesInput: undefined,
|
||||
queriesInput: undefined,
|
||||
qualityQueriesInput: undefined,
|
||||
@@ -322,6 +324,7 @@ test("load non-empty input", async (t) => {
|
||||
|
||||
// And the config we expect it to parse to
|
||||
const expectedConfig: configUtils.Config = {
|
||||
analysisKinds: [AnalysisKind.CodeScanning],
|
||||
languages: [KnownLanguage.javascript],
|
||||
buildMode: BuildMode.None,
|
||||
originalUserInput: {
|
||||
|
||||
@@ -6,6 +6,7 @@ import * as yaml from "js-yaml";
|
||||
import * as semver from "semver";
|
||||
|
||||
import { isAnalyzingPullRequest } from "./actions-util";
|
||||
import { AnalysisKind, parseAnalysisKinds } from "./analyses";
|
||||
import * as api from "./api-client";
|
||||
import { CachingKind, getCachingKind } from "./caching-utils";
|
||||
import { type CodeQL } from "./codeql";
|
||||
@@ -93,6 +94,10 @@ interface IncludeQueryFilter {
|
||||
* Format of the parsed config file.
|
||||
*/
|
||||
export interface Config {
|
||||
/**
|
||||
* Set of analysis kinds that are enabled.
|
||||
*/
|
||||
analysisKinds: AnalysisKind[];
|
||||
/**
|
||||
* Set of languages to run analysis for.
|
||||
*/
|
||||
@@ -483,6 +488,7 @@ export async function getRawLanguages(
|
||||
|
||||
/** Inputs required to initialize a configuration. */
|
||||
export interface InitConfigInputs {
|
||||
analysisKindsInput: string;
|
||||
languagesInput: string | undefined;
|
||||
queriesInput: string | undefined;
|
||||
qualityQueriesInput: string | undefined;
|
||||
@@ -511,6 +517,7 @@ export interface InitConfigInputs {
|
||||
* Get the default config, populated without user configuration file.
|
||||
*/
|
||||
export async function getDefaultConfig({
|
||||
analysisKindsInput,
|
||||
languagesInput,
|
||||
queriesInput,
|
||||
qualityQueriesInput,
|
||||
@@ -530,6 +537,8 @@ export async function getDefaultConfig({
|
||||
features,
|
||||
logger,
|
||||
}: InitConfigInputs): Promise<Config> {
|
||||
const analysisKinds = await parseAnalysisKinds(analysisKindsInput);
|
||||
|
||||
const languages = await getLanguages(
|
||||
codeql,
|
||||
languagesInput,
|
||||
@@ -560,6 +569,7 @@ export async function getDefaultConfig({
|
||||
);
|
||||
|
||||
return {
|
||||
analysisKinds,
|
||||
languages,
|
||||
buildMode,
|
||||
originalUserInput: {},
|
||||
|
||||
@@ -385,6 +385,7 @@ async function run() {
|
||||
}
|
||||
|
||||
config = await initConfig({
|
||||
analysisKindsInput: getRequiredInput("analysis-kinds"),
|
||||
languagesInput: getOptionalInput("languages"),
|
||||
queriesInput: getOptionalInput("queries"),
|
||||
qualityQueriesInput: getOptionalInput("quality-queries"),
|
||||
|
||||
Reference in New Issue
Block a user