-
Notifications
You must be signed in to change notification settings - Fork 764
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for sourcing feature flags from bicepconfig.json #8559
Conversation
5b447a5
to
fe8fd4d
Compare
src/Bicep.Core/Configuration/ExperimentalFeaturesEnabledConfiguration.cs
Outdated
Show resolved
Hide resolved
@@ -17,14 +16,14 @@ public class InvocationContext | |||
IAzResourceTypeLoader azResourceTypeLoader, | |||
TextWriter outputWriter, | |||
TextWriter errorWriter, | |||
IFeatureProvider? features = null, | |||
IFeatureProviderFactory? featureProviderFactory = null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be nullable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes; this parameter is a backdoor for the integration tests to toggle various feature flags and set the assembly version to a static string. It is never set on contexts created in the Bicep.Cli package, which instead relies on the DI container to instantiate the factory.
Also emit a deprecation notice when a feature flag is sourced from an environment variable.
fe8fd4d
to
a7cd125
Compare
src/Bicep.Core/Analyzers/Linter/ApiVersions/ApiVersionProviderFactory.cs
Outdated
Show resolved
Hide resolved
public bool RegistryEnabled => true; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we remove this? (feel free to create a follow-up issue)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably. A fair number of tests explicitly disable the registry, so there may be something to address there.
bool? SourceMapping, | ||
bool? ParamsFiles) | ||
{ | ||
public static ExperimentalFeaturesEnabled Bind(JsonElement element, string? configurationPath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to be difficult:
- What benefit do we get out of this being an object vs an array? e.g.
"experimentalFeatures": ["foo", "bar"]
- What's the experience if the user opts-in to a feature which isn't supported by the compiler? Should we error/warning if that happens?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using an object lets us turn on an experimental feature by default while still giving users a way to disable it if they run into any issues. We currently support this form of transition today (e.g., if we enabled symbolic name codegen by default, a user could turn it off with export BICEP_SYMBOLIC_NAME_CODEGEN_EXPERIMENTAL=false
).
The behavior when a user tries to enable a non-existent feature flag is a config load error, which blocks compilation. This could be converted from an error to a warning, but I think that creates a confusing situation: with "symbolcNameCodegen": true
, we would emit a non-blocking warning and then not use symbolic names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense to start strict and wait for feedback to relax it.
I can see a hypothetical situation where different users sharing the bicepconfig.json in a repo run different versions of bicep that have different sets of experimental features, which would force the enabled experimental features being a common denominator but I'm not terribly worried about that scenario... yet.
My preference is object as well for the same reasons. Disabling in an array requires removing the whole item from the array or comment out the item with block comments. With an object you can just change to false. (With completions that's as simple as selecting true
, typing f and enter or tab.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as disabling features goes - my expectation is that we won't be shipping any "experimental" features that are true by default - instead we'll just remove the property from IFeatureProvider
.
The scenarios for the object do feel a little hypothetical - but I also don't feel strongly about it being an array vs object.
@@ -61,5 +61,6 @@ | |||
} | |||
} | |||
} | |||
} | |||
}, | |||
"experimentalFeaturesEnabled": {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this to schema file but didn't document the sub-properties. We don't document the environment variables today, and it seemed like a lot of content to generate 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
|
||
if (invocationContext.EmitterSettings.EnableSymbolicNames) | ||
if (emitterSettings.EnableSymbolicNames) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a follow-up item, I think we should converge on a single message that covers enablement of all experimental features.
Resolves #7955
This PR updates Bicep's feature flag façade to support multiple sources and adds two more: configuration viabicepconfig.json
files and CLI arguments. The existing feature flag environment variables are still supported, but they may be overridden with a CLI argument, and if a feature is not explicitly enabled or disabled via CLI args or environment variables, the appropriatebicepconfig.json
file for the template/module being compiled will be queried.This PR updates
IFeatureProvider
to read frombicepconfig.json
instead of the currently supported environment variables.As a consequence of reading
bicepconfig.json
for feature flags, we can no longer associated anIFeatureProvider
with aCompilation
instance but must instead bind feature providers to theCompilation
's constituentSemanticModel
instances, as each bicep file may have different features enabled or disabled depending on its location on disk. The same is true ofIApiVersionProvider
, which takes anIFeatureProvider
as a constructor argument.Microsoft Reviewers: Open in CodeFlow