debian-mirror-gitlab/doc/development/feature_flags.md

120 lines
3.7 KiB
Markdown
Raw Normal View History

2017-09-10 17:25:29 +05:30
# Manage feature flags
2018-03-27 19:54:05 +05:30
Starting from GitLab 9.3 we support feature flags for features in GitLab via
2017-09-10 17:25:29 +05:30
[Flipper](https://github.com/jnunemaker/flipper/). You should use the `Feature`
class (defined in `lib/feature.rb`) in your code to get, set and list feature
flags.
During runtime you can set the values for the gates via the
[features API](../api/features.md) (accessible to admins only).
## Feature groups
Starting from GitLab 9.4 we support feature groups via
[Flipper groups](https://github.com/jnunemaker/flipper/blob/v0.10.2/docs/Gates.md#2-group).
Feature groups must be defined statically in `lib/feature.rb` (in the
`.register_feature_groups` method), but their implementation can obviously be
dynamic (querying the DB etc.).
Once defined in `lib/feature.rb`, you will be able to activate a
feature for a given feature group via the [`feature_group` param of the features API](../api/features.md#set-or-create-a-feature)
2018-03-27 19:54:05 +05:30
2018-11-20 20:47:30 +05:30
For GitLab.com, team members have access to feature flags through chatops. Only
percentage gates are supported at this time. Setting a feature to be used 50% of
the time, you should execute `/chatops run feature set my_feature_flag 50`.
2018-03-27 19:54:05 +05:30
## Feature flags for user applications
GitLab does not yet support the use of feature flags in deployed user applications.
2018-11-20 20:47:30 +05:30
You can follow the progress on that [in the issue on our issue tracker](https://gitlab.com/gitlab-org/gitlab-ee/issues/779).
## Developing with feature flags
In general, it's better to have a group- or user-based gate, and you should prefer
it over the use of percentage gates. This would make debugging easier, as you
2019-01-03 12:48:30 +05:30
filter for example logs and errors based on actors too. Futhermore, this allows
2018-11-20 20:47:30 +05:30
for enabling for the `gitlab-org` group first, while the rest of the users
aren't impacted.
```ruby
# Good
Feature.enabled?(:feature_flag, project)
# Avoid, if possible
Feature.enabled?(:feature_flag)
```
To use feature gates based on actors, the model needs to respond to
`flipper_id`. For example, to enable for the Foo model:
```ruby
class Foo < ActiveRecord::Base
include FeatureGate
end
```
Features that are developed and are intended to be merged behind a feature flag
should not include a changelog entry. The entry should be added in the merge
request removing the feature flags.
In the rare case that you need the feature flag to be on automatically, use
`default_enabled: true` when checking:
```ruby
Feature.enabled?(:feature_flag, project, default_enabled: true)
```
2018-12-05 23:21:45 +05:30
For more information about rolling out changes using feature flags, refer to the
[Rolling out changes using feature flags](rolling_out_changes_using_feature_flags.md)
guide.
2018-12-13 13:39:08 +05:30
### Frontend
For frontend code you can use the method `push_frontend_feature_flag`, which is
available to all controllers that inherit from `ApplicationController`. Using
this method you can expose the state of a feature flag as follows:
```ruby
before_action do
push_frontend_feature_flag(:vim_bindings)
end
def index
# ...
end
def edit
# ...
end
```
You can then check for the state of the feature flag in JavaScript as follows:
```javascript
if ( gon.features.vimBindings ) {
// ...
}
```
The name of the feature flag in JavaScript will always be camelCased, meaning
that checking for `gon.features.vim_bindings` would not work.
2018-11-20 20:47:30 +05:30
### Specs
In the test environment `Feature.enabled?` is stubbed to always respond to `true`,
so we make sure behavior under feature flag doesn't go untested in some non-specific
contexts.
2018-12-05 23:21:45 +05:30
Whenever a feature flag is present, make sure to test _both_ states of the
feature flag. You can stub a feature flag as follows:
2018-11-20 20:47:30 +05:30
```ruby
stub_feature_flags(my_feature_flag: false)
```
2018-12-13 13:39:08 +05:30
2019-01-03 12:48:30 +05:30
## Enabling a feature flag
2018-12-13 13:39:08 +05:30
Check how to [roll out changes using feature flags](rolling_out_changes_using_feature_flags.md).