Address comments from review
- Change env var name for `MlPoweredQueriesEnabled` - Throw error if minimumVersion is specified, but CodeQL argument is not supplied. - Fix failing tests. Note that I removed a config-utils test because it is no longer relevant since we handle codeql minimum versions in the `getValue` function.
This commit is contained in:
parent
e5c3375225
commit
b16314e16c
9 changed files with 202 additions and 129 deletions
2
lib/config-utils.test.js
generated
2
lib/config-utils.test.js
generated
|
|
@ -1007,8 +1007,6 @@ const mlPoweredQueriesMacro = ava_1.default.macro({
|
|||
: "aren't"} loaded for packs: ${packsInput}, queries: ${queriesInput} using CLI v${codeQLVersion} when feature flag is ${isMlPoweredQueriesFlagEnabled ? "enabled" : "disabled"}`,
|
||||
});
|
||||
// macro, codeQLVersion, isMlPoweredQueriesFlagEnabled, packsInput, queriesInput, expectedVersionString
|
||||
// Test that ML-powered queries aren't run on v2.7.4 of the CLI.
|
||||
(0, ava_1.default)(mlPoweredQueriesMacro, "2.7.4", true, undefined, "security-extended", undefined);
|
||||
// Test that ML-powered queries aren't run when the feature flag is off.
|
||||
(0, ava_1.default)(mlPoweredQueriesMacro, "2.7.5", false, undefined, "security-extended", undefined);
|
||||
// Test that the ~0.1.0 version of ML-powered queries is run on v2.8.3 of the CLI.
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
17
lib/feature-flags.js
generated
17
lib/feature-flags.js
generated
|
|
@ -36,7 +36,7 @@ exports.featureFlagConfig = {
|
|||
minimumVersion: undefined,
|
||||
},
|
||||
[FeatureFlag.MlPoweredQueriesEnabled]: {
|
||||
envVar: "CODEQL_VERSION_ML_POWERED_QUERIES",
|
||||
envVar: "CODEQL_ML_POWERED_QUERIES",
|
||||
minimumVersion: "2.7.5",
|
||||
},
|
||||
[FeatureFlag.TrapCachingEnabled]: {
|
||||
|
|
@ -59,7 +59,22 @@ class GitHubFeatureFlags {
|
|||
this.repositoryNwo = repositoryNwo;
|
||||
this.logger = logger;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param flag The feature flag to check.
|
||||
* @param codeql An optional CodeQL object. If provided, and a `minimumVersion` is specified for the
|
||||
* feature flag, the version of the CodeQL CLI will be checked against the minimum version.
|
||||
* If the version is less than the minimum version, the feature flag will be considered
|
||||
* disabled. If not provided, and a `minimumVersion` is specified for the feature flag, the
|
||||
* this function will throw.
|
||||
* @returns true if the feature flag is enabled, false otherwise.
|
||||
*
|
||||
* @throws if a `minimumVersion` is specified for the feature flag, and `codeql` is not provided.
|
||||
*/
|
||||
async getValue(flag, codeql) {
|
||||
if (!codeql && exports.featureFlagConfig[flag].minimumVersion) {
|
||||
throw new Error(`A minimum version is specified for feature flag ${flag}, but no instance of CodeQL was provided.`);
|
||||
}
|
||||
// Bypassing the toolcache is disabled in test mode.
|
||||
if (flag === FeatureFlag.BypassToolcacheEnabled && util.isInTestMode()) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"version":3,"file":"feature-flags.js","sourceRoot":"","sources":["../src/feature-flags.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"feature-flags.js","sourceRoot":"","sources":["../src/feature-flags.ts"],"names":[],"mappings":"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"}
|
||||
107
lib/feature-flags.test.js
generated
107
lib/feature-flags.test.js
generated
|
|
@ -30,9 +30,10 @@ for (const variant of ALL_FEATURE_FLAGS_DISABLED_VARIANTS) {
|
|||
(0, ava_1.default)(`All feature flags are disabled if running against ${variant.description}`, async (t) => {
|
||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||
const loggedMessages = [];
|
||||
const featureFlags = setUpTmpDir(tmpDir, (0, testing_utils_1.getRecordingLogger)(loggedMessages), variant.gitHubVersion);
|
||||
const featureFlags = setUpTests(tmpDir, (0, testing_utils_1.getRecordingLogger)(loggedMessages), variant.gitHubVersion);
|
||||
for (const flag of Object.values(feature_flags_1.FeatureFlag)) {
|
||||
t.assert((await featureFlags.getValue(flag)) === false);
|
||||
t.assert((await featureFlags.getValue(flag, includeCodeQlIfRequired(flag))) ===
|
||||
false);
|
||||
}
|
||||
t.assert(loggedMessages.find((v) => v.type === "debug" &&
|
||||
v.message ===
|
||||
|
|
@ -43,46 +44,40 @@ for (const variant of ALL_FEATURE_FLAGS_DISABLED_VARIANTS) {
|
|||
(0, ava_1.default)("API response missing", async (t) => {
|
||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||
const loggedMessages = [];
|
||||
const featureFlags = setUpTmpDir(tmpDir, (0, testing_utils_1.getRecordingLogger)(loggedMessages));
|
||||
const featureFlags = setUpTests(tmpDir, (0, testing_utils_1.getRecordingLogger)(loggedMessages));
|
||||
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(403, {});
|
||||
for (const flag of Object.values(feature_flags_1.FeatureFlag)) {
|
||||
t.assert((await featureFlags.getValue(flag)) === false);
|
||||
}
|
||||
for (const featureFlag of Object.keys(feature_flags_1.featureFlagConfig)) {
|
||||
t.assert(loggedMessages.find((v) => v.type === "debug" &&
|
||||
v.message ===
|
||||
`No feature flags API response for ${featureFlag}, considering it disabled.`) !== undefined);
|
||||
t.assert((await featureFlags.getValue(flag, includeCodeQlIfRequired(flag))) ===
|
||||
false);
|
||||
}
|
||||
assertAllFeaturesUndefinedInApi(t, loggedMessages);
|
||||
});
|
||||
});
|
||||
(0, ava_1.default)("Feature flags are disabled if they're not returned in API response", async (t) => {
|
||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||
const loggedMessages = [];
|
||||
const featureFlags = setUpTmpDir(tmpDir, (0, testing_utils_1.getRecordingLogger)(loggedMessages));
|
||||
const featureFlags = setUpTests(tmpDir, (0, testing_utils_1.getRecordingLogger)(loggedMessages));
|
||||
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, {});
|
||||
for (const flag of Object.values(feature_flags_1.FeatureFlag)) {
|
||||
t.assert((await featureFlags.getValue(flag)) === false);
|
||||
}
|
||||
for (const featureFlag of Object.keys(feature_flags_1.featureFlagConfig)) {
|
||||
t.assert(loggedMessages.find((v) => v.type === "debug" &&
|
||||
v.message ===
|
||||
`Feature flag '${featureFlag}' undefined in API response, considering it disabled.`) !== undefined);
|
||||
t.assert((await featureFlags.getValue(flag, includeCodeQlIfRequired(flag))) ===
|
||||
false);
|
||||
}
|
||||
assertAllFeaturesUndefinedInApi(t, loggedMessages);
|
||||
});
|
||||
});
|
||||
(0, ava_1.default)("Feature flags exception is propagated if the API request errors", async (t) => {
|
||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||
const featureFlags = setUpTmpDir(tmpDir);
|
||||
const featureFlags = setUpTests(tmpDir);
|
||||
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(500, {});
|
||||
await t.throwsAsync(async () => featureFlags.getValue(feature_flags_1.FeatureFlag.MlPoweredQueriesEnabled), {
|
||||
await t.throwsAsync(async () => featureFlags.getValue(feature_flags_1.FeatureFlag.MlPoweredQueriesEnabled, includeCodeQlIfRequired(feature_flags_1.FeatureFlag.MlPoweredQueriesEnabled)), {
|
||||
message: "Encountered an error while trying to load feature flags: Error: some error message",
|
||||
});
|
||||
});
|
||||
});
|
||||
for (const featureFlag of Object.keys(feature_flags_1.featureFlagConfig)) {
|
||||
(0, ava_1.default)(`Feature flag '${featureFlag}' is enabled if enabled in the API response`, async (t) => {
|
||||
(0, ava_1.default)(`Only feature flag '${featureFlag}' is enabled if enabled in the API response. Other flags disabled`, async (t) => {
|
||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||
const featureFlags = setUpTmpDir(tmpDir);
|
||||
const featureFlags = setUpTests(tmpDir);
|
||||
// set all feature flags to false except the one we're testing
|
||||
const expectedFeatureFlags = {};
|
||||
for (const f of Object.keys(feature_flags_1.featureFlagConfig)) {
|
||||
|
|
@ -92,56 +87,54 @@ for (const featureFlag of Object.keys(feature_flags_1.featureFlagConfig)) {
|
|||
// retrieve the values of the actual feature flags
|
||||
const actualFeatureFlags = {};
|
||||
for (const f of Object.keys(feature_flags_1.featureFlagConfig)) {
|
||||
actualFeatureFlags[f] = await featureFlags.getValue(f);
|
||||
actualFeatureFlags[f] = await featureFlags.getValue(f, includeCodeQlIfRequired(f));
|
||||
}
|
||||
// Alls flags should be false except the one we're testing
|
||||
t.deepEqual(actualFeatureFlags, expectedFeatureFlags);
|
||||
});
|
||||
});
|
||||
(0, ava_1.default)(`Feature flag '${featureFlag}' is enabled if the associated environment variable is true`, async (t) => {
|
||||
(0, ava_1.default)(`Only feature flag '${featureFlag}' is enabled if the associated environment variable is true. Others disabled.`, async (t) => {
|
||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||
const featureFlags = setUpTmpDir(tmpDir);
|
||||
// set all feature flags to false
|
||||
const expectedFeatureFlags = {};
|
||||
for (const f of Object.keys(feature_flags_1.featureFlagConfig)) {
|
||||
expectedFeatureFlags[f] = false;
|
||||
}
|
||||
const featureFlags = setUpTests(tmpDir);
|
||||
const expectedFeatureFlags = initializeFeatures(false);
|
||||
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, expectedFeatureFlags);
|
||||
// feature flag should be disabled initially
|
||||
t.assert(!(await featureFlags.getValue(featureFlag)));
|
||||
t.assert(!(await featureFlags.getValue(featureFlag, includeCodeQlIfRequired(featureFlag))));
|
||||
// set env var to true and check that the feature flag is now enabled
|
||||
process.env[feature_flags_1.featureFlagConfig[featureFlag].envVar] = "true";
|
||||
t.assert(await featureFlags.getValue(featureFlag));
|
||||
t.assert(await featureFlags.getValue(featureFlag, includeCodeQlIfRequired(featureFlag)));
|
||||
});
|
||||
});
|
||||
(0, ava_1.default)(`Feature flag '${featureFlag}' is disabled if the associated environment variable is false`, async (t) => {
|
||||
(0, ava_1.default)(`Feature flag '${featureFlag}' is disabled if the associated environment variable is false, even if enabled in API`, async (t) => {
|
||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||
const featureFlags = setUpTmpDir(tmpDir);
|
||||
// set all feature flags to true
|
||||
const expectedFeatureFlags = {};
|
||||
for (const f of Object.keys(feature_flags_1.featureFlagConfig)) {
|
||||
expectedFeatureFlags[f] = true;
|
||||
}
|
||||
const featureFlags = setUpTests(tmpDir);
|
||||
const expectedFeatureFlags = initializeFeatures(true);
|
||||
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, expectedFeatureFlags);
|
||||
// feature flag should be enabled initially
|
||||
t.assert(await featureFlags.getValue(featureFlag));
|
||||
t.assert(await featureFlags.getValue(featureFlag, includeCodeQlIfRequired(featureFlag)));
|
||||
// set env var to false and check that the feature flag is now disabled
|
||||
process.env[feature_flags_1.featureFlagConfig[featureFlag].envVar] = "false";
|
||||
t.assert(!(await featureFlags.getValue(featureFlag)));
|
||||
t.assert(!(await featureFlags.getValue(featureFlag, includeCodeQlIfRequired(featureFlag))));
|
||||
});
|
||||
});
|
||||
if (feature_flags_1.featureFlagConfig[featureFlag].minimumVersion !== undefined) {
|
||||
(0, ava_1.default)(`Getting Feature Flag '${featureFlag} should throw if no codeql is provided`, async (t) => {
|
||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||
const featureFlags = setUpTests(tmpDir);
|
||||
const expectedFeatureFlags = initializeFeatures(true);
|
||||
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, expectedFeatureFlags);
|
||||
await t.throwsAsync(async () => featureFlags.getValue(featureFlag), {
|
||||
message: `A minimum version is specified for feature flag ${featureFlag}, but no instance of CodeQL was provided.`,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
if (feature_flags_1.featureFlagConfig[featureFlag].minimumVersion !== undefined) {
|
||||
(0, ava_1.default)(`Feature flag '${featureFlag}' is disabled if the minimum CLI version is below ${feature_flags_1.featureFlagConfig[featureFlag].minimumVersion}`, async (t) => {
|
||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||
const featureFlags = setUpTmpDir(tmpDir);
|
||||
// set all feature flags to true
|
||||
const expectedFeatureFlags = {};
|
||||
for (const f of Object.keys(feature_flags_1.featureFlagConfig)) {
|
||||
expectedFeatureFlags[f] = true;
|
||||
}
|
||||
const featureFlags = setUpTests(tmpDir);
|
||||
const expectedFeatureFlags = initializeFeatures(true);
|
||||
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, expectedFeatureFlags);
|
||||
// feature flag should be enabled initially (ignoring the minimum CLI version)
|
||||
t.assert(await featureFlags.getValue(featureFlag));
|
||||
// feature flag should be disabled when an old CLI version is set
|
||||
let codeql = (0, testing_utils_1.mockCodeQLVersion)("2.0.0");
|
||||
t.assert(!(await featureFlags.getValue(featureFlag, codeql)));
|
||||
|
|
@ -161,8 +154,26 @@ for (const featureFlag of Object.keys(feature_flags_1.featureFlagConfig)) {
|
|||
});
|
||||
}
|
||||
}
|
||||
function setUpTmpDir(tmpDir, logger = (0, logging_1.getRunnerLogger)(true), gitHubVersion = { type: util_1.GitHubVariant.DOTCOM }) {
|
||||
function assertAllFeaturesUndefinedInApi(t, loggedMessages) {
|
||||
for (const featureFlag of Object.keys(feature_flags_1.featureFlagConfig)) {
|
||||
t.assert(loggedMessages.find((v) => v.type === "debug" &&
|
||||
v.message.includes(featureFlag) &&
|
||||
v.message.includes("considering it disabled")) !== undefined);
|
||||
}
|
||||
}
|
||||
function initializeFeatures(initialValue) {
|
||||
return Object.keys(feature_flags_1.featureFlagConfig).reduce((features, key) => {
|
||||
features[key] = initialValue;
|
||||
return features;
|
||||
}, {});
|
||||
}
|
||||
function setUpTests(tmpDir, logger = (0, logging_1.getRunnerLogger)(true), gitHubVersion = { type: util_1.GitHubVariant.DOTCOM }) {
|
||||
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
|
||||
return new feature_flags_1.GitHubFeatureFlags(gitHubVersion, testApiDetails, testRepositoryNwo, logger);
|
||||
}
|
||||
function includeCodeQlIfRequired(featureFlag) {
|
||||
return feature_flags_1.featureFlagConfig[featureFlag].minimumVersion !== undefined
|
||||
? (0, testing_utils_1.mockCodeQLVersion)("9.9.9")
|
||||
: undefined;
|
||||
}
|
||||
//# sourceMappingURL=feature-flags.test.js.map
|
||||
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue