mirror of
https://github.com/github/codeql-action.git
synced 2026-08-06 05:07:52 -05:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0560247397 | |||
| e6801c5a55 | |||
| 479e61c602 | |||
| c5d7d6b3ac | |||
| 6e76342b54 | |||
| c54d34d000 |
Generated
+75
-70
@@ -146550,7 +146550,7 @@ async function sendStatusReport(statusReport) {
|
||||
);
|
||||
}
|
||||
}
|
||||
async function createInitWithConfigStatusReport(config, initStatusReport, configFile, totalCacheSize, overlayBaseDatabaseStats, dependencyCachingResults) {
|
||||
async function createInitWithConfigStatusReport(config, initStatusReport, configFileInput, totalCacheSize, overlayBaseDatabaseStats, dependencyCachingResults) {
|
||||
const languages = config.languages.join(",");
|
||||
const paths = (config.originalUserInput.paths || []).join(",");
|
||||
const pathsIgnore = (config.originalUserInput["paths-ignore"] || []).join(
|
||||
@@ -146576,7 +146576,7 @@ async function createInitWithConfigStatusReport(config, initStatusReport, config
|
||||
}
|
||||
return {
|
||||
...initStatusReport,
|
||||
config_file: configFile ?? "",
|
||||
config_file: configFileInput?.value ?? "",
|
||||
disable_default_queries: disableDefaultQueries,
|
||||
paths,
|
||||
paths_ignore: pathsIgnore,
|
||||
@@ -147996,13 +147996,17 @@ var stringProperty = {
|
||||
validate: isString2,
|
||||
parse: parseStringRepositoryProperty
|
||||
};
|
||||
var nonEmptyStringProperty = {
|
||||
...stringProperty,
|
||||
parse: parseNonEmptyStringRepositoryProperty
|
||||
};
|
||||
var booleanProperty = {
|
||||
// The value from the API should come as a string, which we then parse into a boolean.
|
||||
validate: isString2,
|
||||
parse: parseBooleanRepositoryProperty
|
||||
};
|
||||
var repositoryPropertyParsers = {
|
||||
["github-codeql-config-file" /* CONFIG_FILE */]: stringProperty,
|
||||
["github-codeql-config-file" /* CONFIG_FILE */]: nonEmptyStringProperty,
|
||||
["github-codeql-disable-overlay" /* DISABLE_OVERLAY */]: booleanProperty,
|
||||
["github-codeql-extra-queries" /* EXTRA_QUERIES */]: stringProperty,
|
||||
["github-codeql-file-coverage-on-prs" /* FILE_COVERAGE_ON_PRS */]: booleanProperty,
|
||||
@@ -148080,6 +148084,12 @@ function parseBooleanRepositoryProperty(name, value, logger) {
|
||||
function parseStringRepositoryProperty(_name, value) {
|
||||
return value;
|
||||
}
|
||||
function parseNonEmptyStringRepositoryProperty(_name, value) {
|
||||
if (value.trim().length === 0) {
|
||||
return void 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set(
|
||||
Object.values(RepositoryPropertyName)
|
||||
);
|
||||
@@ -148423,6 +148433,50 @@ function parseUserConfig(logger, pathInput, contents, validateConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
// src/config/inputs.ts
|
||||
async function getComputedInput(action, repositoryProperties, name, options) {
|
||||
const input = action.actions.getOptionalInput(name);
|
||||
const propertyValue = repositoryProperties[options.repositoryPropertyName];
|
||||
if (options.repositoryPropertyFeatureEnabled && options.allowForcedRepositoryPropertyValue && propertyValue?.startsWith("!")) {
|
||||
action.logger.info(
|
||||
`Using ${name} input from repository property (enforced): ${propertyValue}`
|
||||
);
|
||||
return {
|
||||
// Drop the '!' from the value.
|
||||
value: propertyValue.substring(1),
|
||||
source: "repository-property" /* RepositoryProperty */
|
||||
};
|
||||
}
|
||||
if (input !== void 0) {
|
||||
action.logger.info(`Using ${name} input from workflow: ${input}`);
|
||||
return { value: input, source: "workflow" /* Workflow */ };
|
||||
}
|
||||
if (options.repositoryPropertyFeatureEnabled && propertyValue !== void 0) {
|
||||
action.logger.info(
|
||||
`Using ${name} input from repository property: ${propertyValue}`
|
||||
);
|
||||
return {
|
||||
value: propertyValue,
|
||||
source: "repository-property" /* RepositoryProperty */
|
||||
};
|
||||
} else if (propertyValue !== void 0) {
|
||||
action.logger.info(
|
||||
`Ignoring ${name} input from repository property, because the corresponding feature flag is disabled.`
|
||||
);
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
async function getToolsInput(action, repositoryProperties) {
|
||||
const allowRepositoryProperty = await action.features.getValue(
|
||||
"tools_repository_property" /* ToolsRepositoryProperty */
|
||||
);
|
||||
return getComputedInput(action, repositoryProperties, "tools" /* Tools */, {
|
||||
repositoryPropertyFeatureEnabled: allowRepositoryProperty,
|
||||
allowForcedRepositoryPropertyValue: true,
|
||||
repositoryPropertyName: "github-codeql-tools" /* TOOLS */
|
||||
});
|
||||
}
|
||||
|
||||
// src/config/remote-file.ts
|
||||
var DEFAULT_CONFIG_FILE_NAME = ".github/codeql-action.yaml";
|
||||
var DEFAULT_CONFIG_FILE_REF = "main";
|
||||
@@ -148496,33 +148550,15 @@ async function parseRemoteFileAddress(actionState, configFile) {
|
||||
// src/config/file.ts
|
||||
var LOCAL_PATH_PREFIX = "./";
|
||||
var REMOTE_PATH_PREFIX = "remote=";
|
||||
async function getConfigFileInput({
|
||||
logger,
|
||||
actions,
|
||||
features
|
||||
}, repositoryProperties) {
|
||||
const input = actions.getOptionalInput("config-file");
|
||||
if (input !== void 0) {
|
||||
logger.info(`Using configuration file input from workflow: ${input}`);
|
||||
return input;
|
||||
}
|
||||
const propertyValue = repositoryProperties["github-codeql-config-file" /* CONFIG_FILE */];
|
||||
if (propertyValue !== void 0 && propertyValue.trim().length > 0) {
|
||||
const useRepositoryProperty = await features.getValue(
|
||||
"config_file_repository_property" /* ConfigFileRepositoryProperty */
|
||||
);
|
||||
if (useRepositoryProperty) {
|
||||
logger.info(
|
||||
`Using configuration file input from repository property: ${propertyValue}`
|
||||
);
|
||||
return propertyValue;
|
||||
} else {
|
||||
logger.info(
|
||||
"Ignoring configuration file input from repository property, because the corresponding feature flag is disabled."
|
||||
);
|
||||
}
|
||||
}
|
||||
return void 0;
|
||||
async function getConfigFileInput(action, repositoryProperties) {
|
||||
const useRepositoryProperty = await action.features.getValue(
|
||||
"config_file_repository_property" /* ConfigFileRepositoryProperty */
|
||||
);
|
||||
return getComputedInput(action, repositoryProperties, "config-file" /* ConfigFile */, {
|
||||
repositoryPropertyFeatureEnabled: useRepositoryProperty,
|
||||
allowForcedRepositoryPropertyValue: false,
|
||||
repositoryPropertyName: "github-codeql-config-file" /* CONFIG_FILE */
|
||||
});
|
||||
}
|
||||
async function getRemoteConfig(actionState, configFile, apiDetails) {
|
||||
const address = await parseRemoteFileAddress(actionState, configFile);
|
||||
@@ -160347,40 +160383,6 @@ var core21 = __toESM(require_core());
|
||||
var io7 = __toESM(require_io());
|
||||
var semver10 = __toESM(require_semver2());
|
||||
|
||||
// src/config/inputs.ts
|
||||
async function getToolsInput(action, repositoryProperties) {
|
||||
const name = "tools" /* Tools */;
|
||||
const input = action.actions.getOptionalInput(name);
|
||||
const propertyValue = repositoryProperties["github-codeql-tools" /* TOOLS */];
|
||||
const allowRepositoryProperty = await action.features.getValue(
|
||||
"tools_repository_property" /* ToolsRepositoryProperty */
|
||||
);
|
||||
if (allowRepositoryProperty && propertyValue?.startsWith("!")) {
|
||||
action.logger.info(
|
||||
`Using ${name} input from repository property (enforced): ${propertyValue}`
|
||||
);
|
||||
return {
|
||||
// Drop the '!' from the value.
|
||||
value: propertyValue.substring(1),
|
||||
source: "repository-property" /* RepositoryProperty */
|
||||
};
|
||||
}
|
||||
if (input !== void 0) {
|
||||
action.logger.info(`Using ${name} input from workflow: ${input}`);
|
||||
return { value: input, source: "workflow" /* Workflow */ };
|
||||
}
|
||||
if (allowRepositoryProperty && propertyValue !== void 0) {
|
||||
action.logger.info(
|
||||
`Using ${name} input from repository property: ${propertyValue}`
|
||||
);
|
||||
return {
|
||||
value: propertyValue,
|
||||
source: "repository-property" /* RepositoryProperty */
|
||||
};
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
|
||||
// src/workflow.ts
|
||||
var fs27 = __toESM(require("fs"));
|
||||
var path23 = __toESM(require("path"));
|
||||
@@ -160671,7 +160673,7 @@ async function sendStartingStatusReport(startedAt, config, logger) {
|
||||
await sendStatusReport(statusReportBase);
|
||||
}
|
||||
}
|
||||
async function sendCompletedStatusReport2(startedAt, config, configFile, toolsInput, toolsDownloadStatusReport, toolsFeatureFlagsValid, toolsSource, toolsVersion, overlayBaseDatabaseStats, dependencyCachingResults, logger, error3) {
|
||||
async function sendCompletedStatusReport2(startedAt, config, configFileInput, toolsInput, toolsDownloadStatusReport, toolsFeatureFlagsValid, toolsSource, toolsVersion, overlayBaseDatabaseStats, dependencyCachingResults, logger, error3) {
|
||||
const statusReportBase = await createStatusReportBase(
|
||||
"init" /* Init */,
|
||||
getActionsStatus(error3),
|
||||
@@ -160696,6 +160698,9 @@ async function sendCompletedStatusReport2(startedAt, config, configFile, toolsIn
|
||||
if (toolsInput !== void 0) {
|
||||
initStatusReport.computed_inputs.tools = toolsInput;
|
||||
}
|
||||
if (configFileInput !== void 0) {
|
||||
initStatusReport.computed_inputs["config-file"] = configFileInput;
|
||||
}
|
||||
const initToolsDownloadFields = {};
|
||||
if (toolsDownloadStatusReport?.downloadDurationMs !== void 0) {
|
||||
initToolsDownloadFields.tools_download_duration_ms = toolsDownloadStatusReport.downloadDurationMs;
|
||||
@@ -160707,7 +160712,7 @@ async function sendCompletedStatusReport2(startedAt, config, configFile, toolsIn
|
||||
const initWithConfigStatusReport = await createInitWithConfigStatusReport(
|
||||
config,
|
||||
initStatusReport,
|
||||
configFile,
|
||||
configFileInput,
|
||||
Math.round(
|
||||
await getTotalCacheSize(Object.values(config.trapCaches), logger)
|
||||
),
|
||||
@@ -160727,7 +160732,7 @@ async function run3(actionState) {
|
||||
const logger = actionState.logger;
|
||||
let apiDetails;
|
||||
let config;
|
||||
let configFile;
|
||||
let configFileInput;
|
||||
let codeql;
|
||||
let features;
|
||||
let sourceRoot;
|
||||
@@ -160765,7 +160770,7 @@ async function run3(actionState) {
|
||||
core21.exportVariable("JOB_RUN_UUID" /* JOB_RUN_UUID */, jobRunUuid);
|
||||
core21.exportVariable("CODEQL_ACTION_INIT_HAS_RUN" /* INIT_ACTION_HAS_RUN */, "true");
|
||||
const actionStateWithFeatures = { ...actionState, features };
|
||||
configFile = await getConfigFileInput(
|
||||
configFileInput = await getConfigFileInput(
|
||||
actionStateWithFeatures,
|
||||
repositoryProperties
|
||||
);
|
||||
@@ -160846,7 +160851,7 @@ async function run3(actionState) {
|
||||
packsInput: getOptionalInput("packs"),
|
||||
buildModeInput: getOptionalInput("build-mode"),
|
||||
ramInput: getOptionalInput("ram"),
|
||||
configFile,
|
||||
configFile: configFileInput?.value,
|
||||
dbLocation: getOptionalInput("db-location"),
|
||||
configInput: getOptionalInput("config"),
|
||||
dependencyCachingEnabled: getDependencyCachingEnabled(),
|
||||
@@ -161133,7 +161138,7 @@ exec ${goBinaryPath} "$@"`
|
||||
await sendCompletedStatusReport2(
|
||||
startedAt,
|
||||
config,
|
||||
configFile,
|
||||
configFileInput,
|
||||
toolsInput,
|
||||
toolsDownloadStatusReport,
|
||||
toolsFeatureFlagsValid,
|
||||
|
||||
+10
-14
@@ -13,6 +13,7 @@ import {
|
||||
} from "../testing-utils";
|
||||
|
||||
import { getConfigFileInput, getRemoteConfig } from "./file";
|
||||
import { InputSource } from "./inputs";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
@@ -41,8 +42,8 @@ test("getConfigFileInput returns input value", async (t) => {
|
||||
.returns(testInput);
|
||||
})
|
||||
.withArgs(repositoryProperties)
|
||||
.logs(t, "Using configuration file input from workflow")
|
||||
.passes(t.is, testInput);
|
||||
.logs(t, "Using config-file input from workflow")
|
||||
.passes(t.deepEqual, { value: testInput, source: InputSource.Workflow });
|
||||
});
|
||||
|
||||
test("getConfigFileInput returns repository property value", async (t) => {
|
||||
@@ -50,16 +51,11 @@ test("getConfigFileInput returns repository property value", async (t) => {
|
||||
await callee(getConfigFileInput)
|
||||
.withFeatures([Feature.ConfigFileRepositoryProperty])
|
||||
.withArgs(repositoryProperties)
|
||||
.logs(t, "Using configuration file input from repository property")
|
||||
.passes(t.is, repositoryProperties[RepositoryPropertyName.CONFIG_FILE]);
|
||||
});
|
||||
|
||||
test("getConfigFileInput ignores empty repository property value", async (t) => {
|
||||
// Since the repository property value is an empty/whitespace string, we should ignore it.
|
||||
await callee(getConfigFileInput)
|
||||
.withFeatures([Feature.ConfigFileRepositoryProperty])
|
||||
.withArgs({ [RepositoryPropertyName.CONFIG_FILE]: " " })
|
||||
.passes(t.is, undefined);
|
||||
.logs(t, "Using config-file input from repository property")
|
||||
.passes(t.deepEqual, {
|
||||
value: repositoryProperties[RepositoryPropertyName.CONFIG_FILE],
|
||||
source: InputSource.RepositoryProperty,
|
||||
});
|
||||
});
|
||||
|
||||
test("getConfigFileInput ignores repository property value when FF is off", async (t) => {
|
||||
@@ -67,10 +63,10 @@ test("getConfigFileInput ignores repository property value when FF is off", asyn
|
||||
await callee(getConfigFileInput)
|
||||
.withFeatures([])
|
||||
.withArgs(repositoryProperties)
|
||||
.notLogs(t, "Using configuration file input from repository property")
|
||||
.notLogs(t, "Using config-file input from repository property")
|
||||
.logs(
|
||||
t,
|
||||
"Ignoring configuration file input from repository property, because the corresponding feature flag is disabled.",
|
||||
"Ignoring config-file input from repository property, because the corresponding feature flag is disabled.",
|
||||
)
|
||||
.passes(t.is, undefined);
|
||||
});
|
||||
|
||||
+12
-34
@@ -9,6 +9,7 @@ import {
|
||||
import { ConfigurationError } from "../util";
|
||||
|
||||
import { parseUserConfig, UserConfig } from "./db-config";
|
||||
import { getComputedInput, InputName, type ComputedInput } from "./inputs";
|
||||
import { parseRemoteFileAddress } from "./remote-file";
|
||||
|
||||
/**
|
||||
@@ -28,42 +29,19 @@ export const REMOTE_PATH_PREFIX = "remote=";
|
||||
* Gets the value that is configured for the configuration file, if any.
|
||||
*/
|
||||
export async function getConfigFileInput(
|
||||
{
|
||||
logger,
|
||||
actions,
|
||||
features,
|
||||
}: ActionState<["Logger", "Actions", "FeatureFlags"]>,
|
||||
action: ActionState<["Logger", "Actions", "FeatureFlags"]>,
|
||||
repositoryProperties: Partial<RepositoryProperties>,
|
||||
): Promise<string | undefined> {
|
||||
const input = actions.getOptionalInput("config-file");
|
||||
): Promise<ComputedInput | undefined> {
|
||||
// Only use the repository property value if the FF is enabled.
|
||||
const useRepositoryProperty = await action.features.getValue(
|
||||
Feature.ConfigFileRepositoryProperty,
|
||||
);
|
||||
|
||||
if (input !== undefined) {
|
||||
logger.info(`Using configuration file input from workflow: ${input}`);
|
||||
return input;
|
||||
}
|
||||
|
||||
const propertyValue =
|
||||
repositoryProperties[RepositoryPropertyName.CONFIG_FILE];
|
||||
|
||||
if (propertyValue !== undefined && propertyValue.trim().length > 0) {
|
||||
// Only use the repository property value if the FF is enabled.
|
||||
const useRepositoryProperty = await features.getValue(
|
||||
Feature.ConfigFileRepositoryProperty,
|
||||
);
|
||||
|
||||
if (useRepositoryProperty) {
|
||||
logger.info(
|
||||
`Using configuration file input from repository property: ${propertyValue}`,
|
||||
);
|
||||
return propertyValue;
|
||||
} else {
|
||||
logger.info(
|
||||
"Ignoring configuration file input from repository property, because the corresponding feature flag is disabled.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return getComputedInput(action, repositoryProperties, InputName.ConfigFile, {
|
||||
repositoryPropertyFeatureEnabled: useRepositoryProperty,
|
||||
allowForcedRepositoryPropertyValue: false,
|
||||
repositoryPropertyName: RepositoryPropertyName.CONFIG_FILE,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+62
-10
@@ -3,10 +3,12 @@ import { Feature } from "../feature-flags";
|
||||
import {
|
||||
RepositoryProperties,
|
||||
RepositoryPropertyName,
|
||||
StringRepositoryPropertyNames,
|
||||
} from "../feature-flags/properties";
|
||||
|
||||
/** Enumerates input names. */
|
||||
export enum InputName {
|
||||
ConfigFile = "config-file",
|
||||
Tools = "tools",
|
||||
}
|
||||
|
||||
@@ -28,26 +30,50 @@ export type ComputedInput = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the computed `tools` input. This comes from either the workflow or
|
||||
* Represents options for how to compute an input.
|
||||
*/
|
||||
export interface ComputedInputOptions {
|
||||
/**
|
||||
* Whether the FF for the repository property (if any) is enabled.
|
||||
*/
|
||||
repositoryPropertyFeatureEnabled: boolean;
|
||||
/**
|
||||
* The name of the repository property to try and get the input value from.
|
||||
*/
|
||||
repositoryPropertyName: StringRepositoryPropertyNames;
|
||||
/**
|
||||
* Whether the repository property value may start with `!` to take precedence
|
||||
* over any input value provided in the workflow file.
|
||||
*/
|
||||
allowForcedRepositoryPropertyValue: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the computed input for `name`. This comes from either the workflow or
|
||||
* the repository property.
|
||||
*
|
||||
* @param action The Action state.
|
||||
* @param repositoryProperties The values of known repository properties.
|
||||
* @param name The name of the input to compute.
|
||||
* @param options Options for how to compute the input value.
|
||||
*
|
||||
* @returns The computed input or `undefined` if there is no input.
|
||||
*/
|
||||
export async function getToolsInput(
|
||||
export async function getComputedInput(
|
||||
action: ActionState<["Logger", "Actions", "FeatureFlags"]>,
|
||||
repositoryProperties: Partial<RepositoryProperties>,
|
||||
repositoryProperties: RepositoryProperties,
|
||||
name: InputName,
|
||||
options: ComputedInputOptions,
|
||||
): Promise<ComputedInput | undefined> {
|
||||
const name = InputName.Tools;
|
||||
const input = action.actions.getOptionalInput(name);
|
||||
const propertyValue = repositoryProperties[RepositoryPropertyName.TOOLS];
|
||||
const allowRepositoryProperty = await action.features.getValue(
|
||||
Feature.ToolsRepositoryProperty,
|
||||
);
|
||||
const propertyValue = repositoryProperties[options.repositoryPropertyName];
|
||||
|
||||
// The repository property takes precedence if it starts with an '!'.
|
||||
if (allowRepositoryProperty && propertyValue?.startsWith("!")) {
|
||||
if (
|
||||
options.repositoryPropertyFeatureEnabled &&
|
||||
options.allowForcedRepositoryPropertyValue &&
|
||||
propertyValue?.startsWith("!")
|
||||
) {
|
||||
action.logger.info(
|
||||
`Using ${name} input from repository property (enforced): ${propertyValue}`,
|
||||
);
|
||||
@@ -65,7 +91,7 @@ export async function getToolsInput(
|
||||
}
|
||||
|
||||
// Use the repository property if there's no workflow input.
|
||||
if (allowRepositoryProperty && propertyValue !== undefined) {
|
||||
if (options.repositoryPropertyFeatureEnabled && propertyValue !== undefined) {
|
||||
action.logger.info(
|
||||
`Using ${name} input from repository property: ${propertyValue}`,
|
||||
);
|
||||
@@ -73,8 +99,34 @@ export async function getToolsInput(
|
||||
value: propertyValue,
|
||||
source: InputSource.RepositoryProperty,
|
||||
};
|
||||
} else if (propertyValue !== undefined) {
|
||||
action.logger.info(
|
||||
`Ignoring ${name} input from repository property, because the corresponding feature flag is disabled.`,
|
||||
);
|
||||
}
|
||||
|
||||
// There's no input.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the computed `tools` input. This comes from either the workflow or
|
||||
* the repository property.
|
||||
*
|
||||
* @param action The Action state.
|
||||
* @param repositoryProperties The values of known repository properties.
|
||||
* @returns The computed input or `undefined` if there is no input.
|
||||
*/
|
||||
export async function getToolsInput(
|
||||
action: ActionState<["Logger", "Actions", "FeatureFlags"]>,
|
||||
repositoryProperties: Partial<RepositoryProperties>,
|
||||
): Promise<ComputedInput | undefined> {
|
||||
const allowRepositoryProperty = await action.features.getValue(
|
||||
Feature.ToolsRepositoryProperty,
|
||||
);
|
||||
return getComputedInput(action, repositoryProperties, InputName.Tools, {
|
||||
repositoryPropertyFeatureEnabled: allowRepositoryProperty,
|
||||
allowForcedRepositoryPropertyValue: true,
|
||||
repositoryPropertyName: RepositoryPropertyName.TOOLS,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -176,6 +176,30 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"loadPropertiesFromApi returns undefined if non-empty string property is empty",
|
||||
async (t) => {
|
||||
sinon.stub(api, "getRepositoryProperties").resolves({
|
||||
headers: {},
|
||||
status: 200,
|
||||
url: "",
|
||||
data: [{ property_name: "github-codeql-config-file", value: "" }],
|
||||
});
|
||||
const logger = getRunnerLogger(true);
|
||||
const mockRepositoryNwo = parseRepositoryNwo("owner/repo");
|
||||
|
||||
// `github-codeql-config-file` is a `nonEmptyStringProperty`, so we expect to
|
||||
// get `undefined` instead of the empty string
|
||||
const response = await properties.loadPropertiesFromApi(
|
||||
logger,
|
||||
mockRepositoryNwo,
|
||||
);
|
||||
t.deepEqual(response, {
|
||||
"github-codeql-config-file": undefined,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"loadPropertiesFromApi warns if boolean property has unexpected value",
|
||||
async (t) => {
|
||||
|
||||
@@ -22,13 +22,25 @@ export enum RepositoryPropertyName {
|
||||
|
||||
/** Parsed types of the known repository properties. */
|
||||
export type AllRepositoryProperties = {
|
||||
[RepositoryPropertyName.CONFIG_FILE]: string;
|
||||
[RepositoryPropertyName.CONFIG_FILE]: string | undefined;
|
||||
[RepositoryPropertyName.DISABLE_OVERLAY]: boolean;
|
||||
[RepositoryPropertyName.EXTRA_QUERIES]: string;
|
||||
[RepositoryPropertyName.FILE_COVERAGE_ON_PRS]: boolean;
|
||||
[RepositoryPropertyName.TOOLS]: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* The subset of known repository properties which are of type `string`.
|
||||
* We tolerate `undefined` for `string`-typed properties that are empty.
|
||||
*/
|
||||
export type StringRepositoryPropertyNames = keyof {
|
||||
[K in keyof AllRepositoryProperties as AllRepositoryProperties[K] extends
|
||||
| string
|
||||
| undefined
|
||||
? K
|
||||
: never]: AllRepositoryProperties[K];
|
||||
};
|
||||
|
||||
/** Parsed repository properties. */
|
||||
export type RepositoryProperties = Partial<AllRepositoryProperties>;
|
||||
|
||||
@@ -72,6 +84,12 @@ const stringProperty = {
|
||||
parse: parseStringRepositoryProperty,
|
||||
};
|
||||
|
||||
/** A repository property that we expect to contain a non-empty string value. */
|
||||
const nonEmptyStringProperty = {
|
||||
...stringProperty,
|
||||
parse: parseNonEmptyStringRepositoryProperty,
|
||||
};
|
||||
|
||||
/** A repository property that we expect to contain a boolean value. */
|
||||
const booleanProperty = {
|
||||
// The value from the API should come as a string, which we then parse into a boolean.
|
||||
@@ -83,7 +101,7 @@ const booleanProperty = {
|
||||
const repositoryPropertyParsers: {
|
||||
[K in RepositoryPropertyName]: PropertyInfo<K>;
|
||||
} = {
|
||||
[RepositoryPropertyName.CONFIG_FILE]: stringProperty,
|
||||
[RepositoryPropertyName.CONFIG_FILE]: nonEmptyStringProperty,
|
||||
[RepositoryPropertyName.DISABLE_OVERLAY]: booleanProperty,
|
||||
[RepositoryPropertyName.EXTRA_QUERIES]: stringProperty,
|
||||
[RepositoryPropertyName.FILE_COVERAGE_ON_PRS]: booleanProperty,
|
||||
@@ -228,6 +246,17 @@ function parseStringRepositoryProperty(_name: string, value: string): string {
|
||||
return value;
|
||||
}
|
||||
|
||||
/** Parse a non-empty string repository property. */
|
||||
function parseNonEmptyStringRepositoryProperty(
|
||||
_name: string,
|
||||
value: string,
|
||||
): string | undefined {
|
||||
if (value.trim().length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/** Set of known repository property names, for fast lookups. */
|
||||
const KNOWN_REPOSITORY_PROPERTY_NAMES = new Set<string>(
|
||||
Object.values(RepositoryPropertyName),
|
||||
|
||||
+9
-6
@@ -129,7 +129,7 @@ async function sendStartingStatusReport(
|
||||
async function sendCompletedStatusReport(
|
||||
startedAt: Date,
|
||||
config: configUtils.Config | undefined,
|
||||
configFile: string | undefined,
|
||||
configFileInput: ComputedInput | undefined,
|
||||
toolsInput: ComputedInput | undefined,
|
||||
toolsDownloadStatusReport: ToolsDownloadStatusReport | undefined,
|
||||
toolsFeatureFlagsValid: boolean | undefined,
|
||||
@@ -168,6 +168,9 @@ async function sendCompletedStatusReport(
|
||||
if (toolsInput !== undefined) {
|
||||
initStatusReport.computed_inputs.tools = toolsInput;
|
||||
}
|
||||
if (configFileInput !== undefined) {
|
||||
initStatusReport.computed_inputs["config-file"] = configFileInput;
|
||||
}
|
||||
|
||||
const initToolsDownloadFields: InitToolsDownloadFields = {};
|
||||
|
||||
@@ -185,7 +188,7 @@ async function sendCompletedStatusReport(
|
||||
await createInitWithConfigStatusReport(
|
||||
config,
|
||||
initStatusReport,
|
||||
configFile,
|
||||
configFileInput,
|
||||
Math.round(
|
||||
await getTotalCacheSize(Object.values(config.trapCaches), logger),
|
||||
),
|
||||
@@ -212,7 +215,7 @@ async function run(
|
||||
|
||||
let apiDetails: GitHubApiCombinedDetails;
|
||||
let config: configUtils.Config | undefined;
|
||||
let configFile: string | undefined;
|
||||
let configFileInput: ComputedInput | undefined;
|
||||
let codeql: CodeQL;
|
||||
let features: FeatureEnablement;
|
||||
let sourceRoot: string;
|
||||
@@ -263,7 +266,7 @@ async function run(
|
||||
core.exportVariable(EnvVar.INIT_ACTION_HAS_RUN, "true");
|
||||
|
||||
const actionStateWithFeatures = { ...actionState, features };
|
||||
configFile = await getConfigFileInput(
|
||||
configFileInput = await getConfigFileInput(
|
||||
actionStateWithFeatures,
|
||||
repositoryProperties,
|
||||
);
|
||||
@@ -376,7 +379,7 @@ async function run(
|
||||
packsInput: getOptionalInput("packs"),
|
||||
buildModeInput: getOptionalInput("build-mode"),
|
||||
ramInput: getOptionalInput("ram"),
|
||||
configFile,
|
||||
configFile: configFileInput?.value,
|
||||
dbLocation: getOptionalInput("db-location"),
|
||||
configInput: getOptionalInput("config"),
|
||||
dependencyCachingEnabled: getDependencyCachingEnabled(),
|
||||
@@ -782,7 +785,7 @@ async function run(
|
||||
await sendCompletedStatusReport(
|
||||
startedAt,
|
||||
config,
|
||||
configFile,
|
||||
configFileInput,
|
||||
toolsInput,
|
||||
toolsDownloadStatusReport,
|
||||
toolsFeatureFlagsValid,
|
||||
|
||||
@@ -554,7 +554,7 @@ export interface InitToolsDownloadFields {
|
||||
*
|
||||
* @param config The CodeQL Action configuration whose values should be added to the base status report.
|
||||
* @param initStatusReport The base status report.
|
||||
* @param configFile Optionally, the filename of the configuration file that was read.
|
||||
* @param configFileInput Optionally, the filename of the configuration file that was read.
|
||||
* @param totalCacheSize The computed total TRAP cache size.
|
||||
* @param overlayBaseDatabaseStats Statistics about the overlay database, if any.
|
||||
* @returns
|
||||
@@ -562,7 +562,7 @@ export interface InitToolsDownloadFields {
|
||||
export async function createInitWithConfigStatusReport(
|
||||
config: Config,
|
||||
initStatusReport: InitStatusReport,
|
||||
configFile: string | undefined,
|
||||
configFileInput: ComputedInput | undefined,
|
||||
totalCacheSize: number,
|
||||
overlayBaseDatabaseStats: OverlayBaseDatabaseDownloadStats | undefined,
|
||||
dependencyCachingResults: DependencyCacheRestoreStatusReport | undefined,
|
||||
@@ -601,7 +601,7 @@ export async function createInitWithConfigStatusReport(
|
||||
|
||||
return {
|
||||
...initStatusReport,
|
||||
config_file: configFile ?? "",
|
||||
config_file: configFileInput?.value ?? "",
|
||||
disable_default_queries: disableDefaultQueries,
|
||||
paths,
|
||||
paths_ignore: pathsIgnore,
|
||||
|
||||
Reference in New Issue
Block a user