-
Notifications
You must be signed in to change notification settings - Fork 9.1k
Add support for branch- and branding-based feature flagging #10361
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
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| 2. Enabled branches | ||
| 3. Disabled branches | ||
| * The longest branch token that matches your branch will win. | ||
| 3. Enabled brandings |
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.
weird numbering
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.
Thanks.
| <WriteLinesToFile File="$(OpenConsoleCommonOutDir)\inc\TilFeatureStaging.h" | ||
| Lines="@(_FeatureFlagFileLines)" | ||
| Overwrite="true" | ||
| WriteOnlyWhenDifferent="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.
This is some straight up wizardry.
src/internal/stubs.cpp
Outdated
| // True so propsheet will show configuration options but be sure that | ||
| // the open one won't attempt handoff from double click of OpenConsole.exe | ||
| isEnabled = true; | ||
| isEnabled = Feature_AttemptHandoff::IsEnabled(); |
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.
this actually breaks @miniksa's intent here, so NTS to fix it
miniksa
left a comment
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 to me, including the conversions from __INSIDE_WINDOWS. Now they actually have intent. If you've rid us of them all, though, you may want to remove that def completely so someone doesn't accidentally use it going forward and migrates to the feature flagging.
81ead62 to
8a10a63
Compare
This comment has been minimized.
This comment has been minimized.
carlos-zamora
left a comment
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.
This is fantastic! So excited for this to land :)
|
Hello @carlos-zamora! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
This pull request implements a "feature flagging" system that will let
us turn Terminal and conhost features on/off by branch, "release" status
or branding (Dev, Preview, etc.).
It's loosely modelled after the Windows OS concept of "Velocity," but
only insofar as it is driven by an XML document and there's a tool that
emits a header file for you to include.
It only supports toggling features at compile time, and the feature flag
evaluators are intended to be fully constant expressions.
Features are added to `src\features.xml` and marked with a "stage". For
now, the only stages available are `AlwaysDisabled` and `AlwaysEnabled`.
Features can be toggled to different states using branch and branding
tokens, as documented in the included feature flag docs.
For a given feature Feature_XYZ, we will emit two fixtures visible to
the compiler:
1. A preprocessor define `TIL_FEATURE_XYZ_ENABLED` (usable from MIDL,
C++ and C)
2. A feature class type `Feature_XYZ` with a static constexpr member
`IsEnabled()` (usable from C++, designed for `if constexpr()`).
Like Velocity, we rely on the compiler to eliminate dead code caused by
things that compile down to `if constexpr (false)`. :)
Michael suggested that we could use `WindowsInbox` as a branding to
determine when we were being built inside Windows to supplant our use of
the `__INSIDE_WINDOWS` preprocessor token. It was brilliant.
Design Decisions
----------------
* Emitting the header as part of an MSBuild project
* WHY: This allows the MSBuild engine to ensure that the build is
only run once, even in a parallel build situation.
* Only having one feature flag document for the entire project
* WHY: Ease.
* Forcibly including `TilFeatureStaging` with `/FI` for all CL compiler
invocations.
* WHY: If this is a project-wide feature system, we should make it as
easy as possible to use.
* Emitting preprocessor definitions instead of constexpr/consteval
* WHY: Removing entire functions/includes is impossible with `if
constexpr`.
* WHY: MIDL cannot use a `static constexpr bool`, but it can rely on
the C preprocessor to remove text.
* Using MSBuild to emit the text instead of PowerShell
* WHY: This allows us to leverage MSBuild's `WriteOnlyWhenDifferent`
task parameter to avoid changing the file's modification time when
it would have resulted in the same contents. This lets us use the
same FeatureStaging header across multiple builds and multiple
branches and brandings _assuming that they do not result in a
feature flag change_.
* The risk in using a force-include is always that it, for some
reason, determines that the entire project is out of date. We've
gone to great lengths to make sure that it only does so if the
features _actually materially changed_.
(cherry picked from commit 31a39b3)
This pull request implements a "feature flagging" system that will let
us turn Terminal and conhost features on/off by branch, "release" status
or branding (Dev, Preview, etc.).
It's loosely modelled after the Windows OS concept of "Velocity," but
only insofar as it is driven by an XML document and there's a tool that
emits a header file for you to include.
It only supports toggling features at compile time, and the feature flag
evaluators are intended to be fully constant expressions.
Features are added to `src\features.xml` and marked with a "stage". For
now, the only stages available are `AlwaysDisabled` and `AlwaysEnabled`.
Features can be toggled to different states using branch and branding
tokens, as documented in the included feature flag docs.
For a given feature Feature_XYZ, we will emit two fixtures visible to
the compiler:
1. A preprocessor define `TIL_FEATURE_XYZ_ENABLED` (usable from MIDL,
C++ and C)
2. A feature class type `Feature_XYZ` with a static constexpr member
`IsEnabled()` (usable from C++, designed for `if constexpr()`).
Like Velocity, we rely on the compiler to eliminate dead code caused by
things that compile down to `if constexpr (false)`. :)
Michael suggested that we could use `WindowsInbox` as a branding to
determine when we were being built inside Windows to supplant our use of
the `__INSIDE_WINDOWS` preprocessor token. It was brilliant.
Design Decisions
----------------
* Emitting the header as part of an MSBuild project
* WHY: This allows the MSBuild engine to ensure that the build is
only run once, even in a parallel build situation.
* Only having one feature flag document for the entire project
* WHY: Ease.
* Forcibly including `TilFeatureStaging` with `/FI` for all CL compiler
invocations.
* WHY: If this is a project-wide feature system, we should make it as
easy as possible to use.
* Emitting preprocessor definitions instead of constexpr/consteval
* WHY: Removing entire functions/includes is impossible with `if
constexpr`.
* WHY: MIDL cannot use a `static constexpr bool`, but it can rely on
the C preprocessor to remove text.
* Using MSBuild to emit the text instead of PowerShell
* WHY: This allows us to leverage MSBuild's `WriteOnlyWhenDifferent`
task parameter to avoid changing the file's modification time when
it would have resulted in the same contents. This lets us use the
same FeatureStaging header across multiple builds and multiple
branches and brandings _assuming that they do not result in a
feature flag change_.
* The risk in using a force-include is always that it, for some
reason, determines that the entire project is out of date. We've
gone to great lengths to make sure that it only does so if the
features _actually materially changed_.
(cherry picked from commit 31a39b3)
This pull request implements a "feature flagging" system that will let
us turn Terminal and conhost features on/off by branch, "release" status
or branding (Dev, Preview, etc.).
It's loosely modelled after the Windows OS concept of "Velocity," but
only insofar as it is driven by an XML document and there's a tool that
emits a header file for you to include.
It only supports toggling features at compile time, and the feature flag
evaluators are intended to be fully constant expressions.
Features are added to
src\features.xmland marked with a "stage". Fornow, the only stages available are
AlwaysDisabledandAlwaysEnabled.Features can be toggled to different states using branch and branding
tokens, as documented in the included feature flag docs.
For a given feature Feature_XYZ, we will emit two fixtures visible to
the compiler:
TIL_FEATURE_XYZ_ENABLED(usable from MIDL,C++ and C)
Feature_XYZwith a static constexpr memberIsEnabled()(usable from C++, designed forif constexpr()).Like Velocity, we rely on the compiler to eliminate dead code caused by
things that compile down to
if constexpr (false). :)Michael suggested that we could use
WindowsInboxas a branding todetermine when we were being built inside Windows to supplant our use of
the
__INSIDE_WINDOWSpreprocessor token. It was brilliant.Design Decisions
only run once, even in a parallel build situation.
TilFeatureStagingwith/FIfor all CL compilerinvocations.
easy as possible to use.
if constexpr.static constexpr bool, but it can rely onthe C preprocessor to remove text.
WriteOnlyWhenDifferenttask parameter to avoid changing the file's modification time when
it would have resulted in the same contents. This lets us use the
same FeatureStaging header across multiple builds and multiple
branches and brandings assuming that they do not result in a
feature flag change.
reason, determines that the entire project is out of date. We've
gone to great lengths to make sure that it only does so if the
features actually materially changed.