From f4f892e527519d5df60c49fa84d807aa92750190 Mon Sep 17 00:00:00 2001 From: Gabe Villalobos Date: Mon, 3 Jun 2024 15:10:37 -0700 Subject: [PATCH] feat(flagpole): Updates feature flag docs for Flagpole rollout Adds `options-backed-features` as fallback documentation for the stopgap options feature flagging, which is now deprecated. --- src/components/sidebar.tsx | 1 + src/docs/feature-flags/flagpole.mdx | 37 +++++- src/docs/feature-flags/index.mdx | 122 ++++++------------ .../feature-flags/options-backed-features.mdx | 49 +++++++ 4 files changed, 124 insertions(+), 85 deletions(-) create mode 100644 src/docs/feature-flags/options-backed-features.mdx diff --git a/src/components/sidebar.tsx b/src/components/sidebar.tsx index ef61a98438..9b623bde71 100644 --- a/src/components/sidebar.tsx +++ b/src/components/sidebar.tsx @@ -75,6 +75,7 @@ export default () => { Issue Platform - Writing Detectors Feature Flags + Flagpole A/B Testing Options Serializers diff --git a/src/docs/feature-flags/flagpole.mdx b/src/docs/feature-flags/flagpole.mdx index 57958ea7be..26271f2f14 100644 --- a/src/docs/feature-flags/flagpole.mdx +++ b/src/docs/feature-flags/flagpole.mdx @@ -124,9 +124,35 @@ Once the option change is deployed, the feature checks will immediately be activ ## Testing a Flagpole feature locally -You can test a flagpole feature flag locally using the GetSentry devserver. Because the feature handler for Flagpole only exists in GetSentry, it's not currently possible to test Sentry-only flagpole features. +You can test a flagpole feature flag locally using the GetSentry devserver. +Because the feature handler for Flagpole only exists in GetSentry, it's not + currently possible to test Sentry-only flagpole features. + +Start by creating a new yaml file containing your feature config. The config +file should contain a top-level `options` object containing your feature object, +and a `flagpole.flagpole_only_features` list option containing the name of the +feature you want to test, without the `feature.` prefix: +```yaml +options: + flagpole.flagpole_only_features: ['organizations:is_sentry'] + + 'feature.organizations:is_sentry': + created_at: '2024-06-01T00:00:00.000000' + enabled: false + owner: hybrid-cloud + segments: + - conditions: + - operator: in + value: + - sentry + property: organization_slug + name: is_sentry + rollout: 100 +``` + +_Note:_ The `flagpole_only_features` option will only be required while +Flagpole is actively being rolled out. -Start by creating a new yaml file containing your feature config. You can push your feature option to your local devserver using the following `getsentry` CLI command: @@ -134,4 +160,9 @@ You can push your feature option to your local devserver using the following `ge getsentry configoptions -f ///.yml -l DEBUG patch ``` -If this command runs successfully, your flagpole feature should now be active in your local devserver instance and will persist across runs until you remove the feature option. \ No newline at end of file +If this command runs successfully, your flagpole feature should now be +active in your local devserver instance and will persist across runs until +you remove the feature option. + +To unset your feature, comment out or remove your feature config from the +`option` object, and rerun the `getsentry configoptions` command above. \ No newline at end of file diff --git a/src/docs/feature-flags/index.mdx b/src/docs/feature-flags/index.mdx index 26622135b5..05b7bd2281 100644 --- a/src/docs/feature-flags/index.mdx +++ b/src/docs/feature-flags/index.mdx @@ -15,10 +15,12 @@ You can find a list of features available by looking at two files: They're declared on the `FeatureManager` like so: ```python -# pass FeatureHandlerStrategy.OPTIONS to use options automator: -manager.add("organizations:onboarding", OrganizationFeature, FeatureHandlerStrategy.OPTIONS) +# pass FeatureHandlerStrategy.FLAGPOLE to use our options-backed feature flagging system: +manager.add("organizations:onboarding", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE) # pass FeatureHandlerStrategy.INTERNAL if you don't plan to use options automator: manager.add("organizations:onboarding", OrganizationFeature, FeatureHandlerStrategy.INTERNAL) +# [DEPRECATED] pass FeatureHandlerStrategy.OPTIONS to use options automator: +manager.add("organizations:onboarding", OrganizationFeature, FeatureHandlerStrategy.OPTIONS) ``` The feature can be enabled with the following in your `sentry.conf.py`, usually located at `~/.sentry/`: @@ -46,41 +48,36 @@ we'll build a feature called `test-feature` scoped at the _organization_ level ### Determine the permanency of your feature Typically we use feature flags for development. They are usually [intended to -be graduated](#after-launch-graduation). Feature flag that controls a -subscription-based feature for sentry.io are permanent. +be graduated](#after-launch-graduation). The only exceptions to this are permanent +flags which control [subscription plan-specific features](#plan-specific-features) +in GetSentry. -Most feature flags are placed in `temporary.py`, permanent flags live in +Most Sentry feature flags are placed in `temporary.py`, while permanent Sentry flags live in `permanent.py`. -### Add your feature to server.py +GetSentry only flags are typically placed in [`features.py`](https://github.com/getsentry/getsentry/blob/master/getsentry/features.py). -[`conf/server.py`](https://github.com/getsentry/sentry/blob/master/src/sentry/conf/server.py) -contains many of the default settings in the application. Here you will add -your feature, and decide what default value it should hold unless specified by -the user. +### Add your feature to the FeatureManager -The `SENTRY_FEATURES` dictionary contains all the features in the application -with their corresponding scope. Your feature should start off disabled by default: +If you want to back your feature flag via options, you can do so using the [Flagpole](/feature-flags/flagpole/) library +by adding the feature to the `FeatureManager` with the `FLAGPOLE` enum set as the feature strategy: ```python -SENTRY_FEATURES = { - 'organizations:test-feature': False, - 'auth:register': True, - # ... - 'projects:minidump': False, -} +default_manager.add('organizations:test-feature', OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE) ``` -### Add your feature to the FeatureManager +This is only available in GetSentry at the moment, so all Flagpole features must be defined in [`features.py`](https://github.com/getsentry/getsentry/blob/master/getsentry/features.py). -If you want to back your feature [flag via options](#building-your-options-based-feature) -add the feature to the `FeatureManager` like so using the `OPTIONS` enum.: +_Note:_ It used to be required to add a new feature's name to `server.py` in Sentry in order to set a default value, but this +is no longer required. Instead, the `manager.add()` method takes a default value, or automatically sets the value +to `False` if no default is provided. ```python -default_manager.add('organizations:test-feature', OrganizationFeature, FeatureHandlerStrategy.OPTIONS) +# Example of a feature set with a default value of True +default_manager.add('organizations:test-feature', OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, True) ``` -If you don't plan to use options, use `FeatureHandlerStrategy.INTERNAL`, for example: +If you don't plan to use Flagpole, use `FeatureHandlerStrategy.INTERNAL` with a custom feature handler instead, for example: ```python default_manager.add('organizations:test-feature', OrganizationFeature, FeatureHandlerStrategy.INTERNAL) @@ -90,10 +87,10 @@ default_manager.add('organizations:test-feature', OrganizationFeature, FeatureHa The Organization model serializer (`src/sentry/api/serializers/models/organization.py`) builds a list -called `feature_list` that is given to the front-end to use. By default the all -features are checked and those that are present are added into the list. If -your feature requires additional custom logic you will have to update the -organization serializer +called `feature_list` that is given to the front-end to use. By default, all +organiation features are checked and those that are present are added into the list. If +your feature requires additional custom logic, you will have to update the +organization serializer to check and include it manually. ### Using Model Flags (Less common) @@ -117,18 +114,18 @@ if getattr(obj.flags, 'require_2fa'): ### In Python code -The FeatureManager's `has` method checks see if the feature exists. The has -method takes in the feature's name, the object that corresponds to the scope of +The FeatureManager's `has` method checks see if the feature exists. The `has` +method takes in the feature's name, the objects that correspond to the scope of the feature *(i.e. an organization for an organization level feature or -a project for a project level feature)*, and the actor (aka user). In our case -the feature will be added like: +a project for a project level feature)*, and the actor (aka user). Here's an example +Organization feature check: ```python if features.has('organizations:test-feature', obj, actor=user): feature_list.append('test-feature') ``` -which only adds the feature to the `feature_list` if that feature is enabled for +The example code only adds the feature to the `feature_list` if that feature is enabled for the organization and the type of user given. Note that when we give the feature to the frontend, we remove the scope prefix, and our `'organizations:test-feature'` becomes `'test-feature'`. @@ -182,63 +179,24 @@ configuration file: SENTRY_FEATURES['organizations:test-feature'] = True ``` -Where `SENTRY_FEATURES` will correspond to the `SENTRY_FEATURES` from `step 2`. -Set it to `True` if you'd like the feature to be available and `False` if not. + +Alternatively, you can test Flagpole features by setting custom options locally. +See the [Flagpole Local Development](/feature-flags/flagpole/#testing-a-flagpole-feature-locally) docs for more information on this. ## Enabling your feature in production Feature flags are declared in Sentry's codebase. For self-hosted users, those flags are then configured via `sentry.conf.py`. For Sentry's SaaS deployment, -you have the choice of using an option backed rollout via Options Automator, +you have the choice of using an option backed rollout via Options Automator with Flagpole, or by writing a custom feature flag handler. +- [Flagpole](/feature-flags/flagpole/) is Sentry's internal feature flagging library, allowing a feature +with multiple target segments and condition filters to be defined in YAML within Options Automator. -- [Options based features](#building-your-options-based-feature) allow a feature +- [Options based features](/feature-flags/options-backed-features/) [DEPRECATED] allow a feature to be rolled out to a specific subset of LA orgs, a percentage of EA orgs, and/or a percentage of all orgs. These can be used in high scale situations, and are generally -preferred over customer feature handlers. - -## Building your options based feature -Declare your feature in sentry/features/temporary.py or -sentry/features/permanent.py like so: -```python -manager.add("organizations:your-new-flag", OrganizationFeature, FeatureHandlerStrategy.OPTIONS) -``` - -This automatically registers a feature handler for you in getsentry, and also -auto registers the relevant options. - -To roll out your feature, you'll want to set the rollout options via options -automator. To figure out the options you need to configure, you can run the -following script in getsentry: -```python -./bin/generate_automator_feature_options.py --flag organizations:your-new-flag -``` - -It will then produce output like - -```python -Generating automator options for feature flag `organizations:your-new-flag` -Add these to the appropriate file in options automator to roll out your feature -For example, to roll out in the US, you can add them to https://github.com/getsentry/sentry-options-automator/blob/main/options/regions/us/app.yaml -To roll out to all production regions, you can add them to https://github.com/getsentry/sentry-options-automator/blob/main/options/default/app.yaml -Options: - organizations.your-new-flag.la-rollout: 0.0 - organizations.your-new-flag.ea-rollout: 0.0 - organizations.your-new-flag.ga-rollout: 0.0 - organizations.your-new-flag.la-orgs: [ - "codecov", - "sentry", - "sentry-sdks", - "sentry-test", - "sentry-st", - "sentry-emerging-tech", - "specto-dev", - ] -``` - -Open a pr in https://github.com/getsentry/sentry-options-automator to set -these options and you can roll out your feature flag. You can also customize -which orgs will be in your la rollout by modifying `la-orgs` +preferred over customer feature handlers. This strategy predates Flagpole, which is the new standard +way to define an option-backed feature flag. ## After launch (Graduation) @@ -259,7 +217,7 @@ sentry.io, you have a few potential paths: ## Getsentry feature handlers Getsentry contains a variety of feature handlers that override the -`SENTRY_FEATURES` map. +`SENTRY_FEATURES` map, which are defined in the [`features.py`](https://github.com/getsentry/getsentry/blob/master/getsentry/features.py) file. ### Plan specific features @@ -277,4 +235,4 @@ implement a feature handler in getsentry. For example, you can create a feature 1. Disable the feature in `getsentry/conf/settings/defaults.py` by updating `SENTRY_FEATURES`. 2. Add a new feature handler class in `getsentry/features.py` that determines availability of the feature based on the organization or actor. -3. Register the handler at the bottom of `getsentry/features.py`. +3. Register the handler at the bottom of `getsentry/features.py`. \ No newline at end of file diff --git a/src/docs/feature-flags/options-backed-features.mdx b/src/docs/feature-flags/options-backed-features.mdx new file mode 100644 index 0000000000..e222560eae --- /dev/null +++ b/src/docs/feature-flags/options-backed-features.mdx @@ -0,0 +1,49 @@ +# Options Backed Features [DEPRECATED] +Options backed features using the `OPTIONS` strategy enum were a temporary stopgap +that was used to formalize options-backed feature flags. These have since been +replaced by [Flagpole](/feature-flags/flagpole/), which is Sentry's preferred +means of setting feature flags now. + + +## Building your options based feature +Declare your feature in sentry/features/temporary.py or +sentry/features/permanent.py like so: +```python +manager.add("organizations:your-new-flag", OrganizationFeature, FeatureHandlerStrategy.OPTIONS) +``` + +This automatically registers a feature handler for you in getsentry, and also +auto registers the relevant options. + +To roll out your feature, you'll want to set the rollout options via options +automator. To figure out the options you need to configure, you can run the +following script in getsentry: +```python +./bin/generate_automator_feature_options.py --flag organizations:your-new-flag +``` + +It will then produce output like + +```python +Generating automator options for feature flag `organizations:your-new-flag` +Add these to the appropriate file in options automator to roll out your feature +For example, to roll out in the US, you can add them to https://github.com/getsentry/sentry-options-automator/blob/main/options/regions/us/app.yaml +To roll out to all production regions, you can add them to https://github.com/getsentry/sentry-options-automator/blob/main/options/default/app.yaml +Options: + organizations.your-new-flag.la-rollout: 0.0 + organizations.your-new-flag.ea-rollout: 0.0 + organizations.your-new-flag.ga-rollout: 0.0 + organizations.your-new-flag.la-orgs: [ + "codecov", + "sentry", + "sentry-sdks", + "sentry-test", + "sentry-st", + "sentry-emerging-tech", + "specto-dev", + ] +``` + +Open a pr in https://github.com/getsentry/sentry-options-automator to set +these options and you can roll out your feature flag. You can also customize +which orgs will be in your la rollout by modifying `la-orgs`