Commit 2ddcaba1 authored by Kamil Trzciński's avatar Kamil Trzciński Committed by Marcel Amirault

Update development guide about feature flags

This does:
- moves feature flag testing into a single place
- heavily refactors `development` guide for feature flags
- document a `bin/feature-flag` workflow
parent 3c6ee540
...@@ -10,12 +10,12 @@ yarn clean ...@@ -10,12 +10,12 @@ yarn clean
## Creating feature flags in development ## Creating feature flags in development
The process for creating a feature flag is the same as [enabling a feature flag in development](../feature_flags/development.md#enabling-a-feature-flag-in-development). The process for creating a feature flag is the same as [enabling a feature flag in development](../feature_flags/development.md#enabling-a-feature-flag-locally-in-development).
Your feature flag can now be: Your feature flag can now be:
- [Made available to the frontend](../feature_flags/development.md#frontend) via the `gon` - [Made available to the frontend](../feature_flags/development.md#frontend) via the `gon`
- Queried in [tests](../feature_flags/development.md#specs) - Queried in [tests](../feature_flags/development.md#feature-flags-in-tests)
- Queried in HAML templates and Ruby files via the `Feature.enabled?(:my_shiny_new_feature_flag)` method - Queried in HAML templates and Ruby files via the `Feature.enabled?(:my_shiny_new_feature_flag)` method
### More on feature flags ### More on feature flags
......
...@@ -71,7 +71,7 @@ In order to actually use it, you need to enable measuring for the desired servic ...@@ -71,7 +71,7 @@ In order to actually use it, you need to enable measuring for the desired servic
### Enabling measurement using feature flags ### Enabling measurement using feature flags
In the following example, the `:gitlab_service_measuring_projects_import_service` In the following example, the `:gitlab_service_measuring_projects_import_service`
[feature flag](feature_flags/development.md#enabling-a-feature-flag-in-development) is used to enable the measuring feature [feature flag](feature_flags/development.md#enabling-a-feature-flag-locally-in-development) is used to enable the measuring feature
for `Projects::ImportService`. for `Projects::ImportService`.
From ChatOps: From ChatOps:
......
...@@ -315,109 +315,7 @@ end ...@@ -315,109 +315,7 @@ end
### Feature flags in tests ### Feature flags in tests
All feature flags are stubbed to be enabled by default in our Ruby-based This section was moved to [developing with feature flags](../feature_flags/development.md).
tests.
To disable a feature flag in a test, use the `stub_feature_flags`
helper. For example, to globally disable the `ci_live_trace` feature
flag in a test:
```ruby
stub_feature_flags(ci_live_trace: false)
Feature.enabled?(:ci_live_trace) # => false
```
If you wish to set up a test where a feature flag is enabled only
for some actors and not others, you can specify this in options
passed to the helper. For example, to enable the `ci_live_trace`
feature flag for a specific project:
```ruby
project1, project2 = build_list(:project, 2)
# Feature will only be enabled for project1
stub_feature_flags(ci_live_trace: project1)
Feature.enabled?(:ci_live_trace) # => false
Feature.enabled?(:ci_live_trace, project1) # => true
Feature.enabled?(:ci_live_trace, project2) # => false
```
This represents an actual behavior of FlipperGate:
1. You can enable an override for a specified actor to be enabled
1. You can disable (remove) an override for a specified actor,
falling back to default state
1. There's no way to model that you explicitly disable a specified actor
```ruby
Feature.enable(:my_feature)
Feature.disable(:my_feature, project1)
Feature.enabled?(:my_feature) # => true
Feature.enabled?(:my_feature, project1) # => true
```
```ruby
Feature.disable(:my_feature2)
Feature.enable(:my_feature2, project1)
Feature.enabled?(:my_feature2) # => false
Feature.enabled?(:my_feature2, project1) # => true
```
#### `stub_feature_flags` vs `Feature.enable*`
It is preferred to use `stub_feature_flags` for enabling feature flags
in testing environment. This method provides a simple and well described
interface for a simple use-cases.
However, in some cases a more complex behaviors needs to be tested,
like a feature flag percentage rollouts. This can be achieved using
the `.enable_percentage_of_time` and `.enable_percentage_of_actors`
```ruby
# Good: feature needs to be explicitly disabled, as it is enabled by default if not defined
stub_feature_flags(my_feature: false)
stub_feature_flags(my_feature: true)
stub_feature_flags(my_feature: project)
stub_feature_flags(my_feature: [project, project2])
# Bad
Feature.enable(:my_feature_2)
# Good: enable my_feature for 50% of time
Feature.enable_percentage_of_time(:my_feature_3, 50)
# Good: enable my_feature for 50% of actors/gates/things
Feature.enable_percentage_of_actors(:my_feature_4, 50)
```
Each feature flag that has a defined state will be persisted
for test execution time:
```ruby
Feature.persisted_names.include?('my_feature') => true
Feature.persisted_names.include?('my_feature_2') => true
Feature.persisted_names.include?('my_feature_3') => true
Feature.persisted_names.include?('my_feature_4') => true
```
#### Stubbing gate
It is required that a gate that is passed as an argument to `Feature.enabled?`
and `Feature.disabled?` is an object that includes `FeatureGate`.
In specs you can use a `stub_feature_flag_gate` method that allows you to have
quickly your custom gate:
```ruby
gate = stub_feature_flag_gate('CustomActor')
stub_feature_flags(ci_live_trace: gate)
Feature.enabled?(:ci_live_trace) # => false
Feature.enabled?(:ci_live_trace, gate) # => true
```
### Pristine test environments ### Pristine test environments
......
...@@ -26,9 +26,9 @@ The following analytics features are available at the group level: ...@@ -26,9 +26,9 @@ The following analytics features are available at the group level:
- [Insights](../group/insights/index.md). **(ULTIMATE)** - [Insights](../group/insights/index.md). **(ULTIMATE)**
- [Issues](../group/issues_analytics/index.md). **(PREMIUM)** - [Issues](../group/issues_analytics/index.md). **(PREMIUM)**
- [Productivity](productivity_analytics.md), enabled with the `productivity_analytics` - [Productivity](productivity_analytics.md), enabled with the `productivity_analytics`
[feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). **(PREMIUM)** [feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-locally-in-development). **(PREMIUM)**
- [Value Stream](value_stream_analytics.md), enabled with the `cycle_analytics` - [Value Stream](value_stream_analytics.md), enabled with the `cycle_analytics`
[feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). **(PREMIUM)** [feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-locally-in-development). **(PREMIUM)**
## Project-level analytics ## Project-level analytics
...@@ -40,4 +40,4 @@ The following analytics features are available at the project level: ...@@ -40,4 +40,4 @@ The following analytics features are available at the project level:
- [Issues](../group/issues_analytics/index.md). **(PREMIUM)** - [Issues](../group/issues_analytics/index.md). **(PREMIUM)**
- [Repository](repository_analytics.md). - [Repository](repository_analytics.md).
- [Value Stream](value_stream_analytics.md), enabled with the `cycle_analytics` - [Value Stream](value_stream_analytics.md), enabled with the `cycle_analytics`
[feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). **(STARTER)** [feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-locally-in-development). **(STARTER)**
...@@ -278,7 +278,7 @@ The group details view also shows the number of the following items created in t ...@@ -278,7 +278,7 @@ The group details view also shows the number of the following items created in t
- Issues. - Issues.
- Members. - Members.
These Group Activity Analytics can be enabled with the `group_activity_analytics` [feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). These Group Activity Analytics can be enabled with the `group_activity_analytics` [feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-locally-in-development).
![Recent Group Activity](img/group_activity_analytics_v12_10.png) ![Recent Group Activity](img/group_activity_analytics_v12_10.png)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment