summaryrefslogtreecommitdiff
path: root/lib/gitlab/experimentation.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/experimentation.rb')
-rw-r--r--lib/gitlab/experimentation.rb74
1 files changed, 42 insertions, 32 deletions
diff --git a/lib/gitlab/experimentation.rb b/lib/gitlab/experimentation.rb
index 68f3c9e332e..3495b4a0b72 100644
--- a/lib/gitlab/experimentation.rb
+++ b/lib/gitlab/experimentation.rb
@@ -2,48 +2,53 @@
# == Experimentation
#
-# Utility module used for A/B testing experimental features. Define your experiments in the `EXPERIMENTS` constant.
-# The feature_toggle and environment keys are optional. If the feature_toggle is not set, a feature with the name of
-# the experiment will be checked, with a default value of true. The enabled_ratio is required and should be
-# the ratio for the number of users for which this experiment is enabled. For example: a ratio of 0.1 will
-# enable the experiment for 10% of the users (determined by the `experimentation_subject_index`).
+# Utility module for A/B testing experimental features. Define your experiments in the `EXPERIMENTS` constant.
+# Experiment options:
+# - environment (optional, defaults to enabled for development and GitLab.com)
+# - tracking_category (optional, used to set the category when tracking an experiment event)
+#
+# The experiment is controlled by a Feature Flag (https://docs.gitlab.com/ee/development/feature_flags/controls.html),
+# which is named "#{experiment_key}_experiment_percentage" and *must* be set with a percentage and not be used for other purposes.
+#
+# To enable the experiment for 10% of the users:
+#
+# chatops: `/chatops run feature set experiment_key_experiment_percentage 10`
+# console: `Feature.get(:experiment_key_experiment_percentage).enable_percentage_of_time(10)`
+#
+# To disable the experiment:
+#
+# chatops: `/chatops run feature delete experiment_key_experiment_percentage`
+# console: `Feature.get(:experiment_key_experiment_percentage).remove`
+#
+# To check the current rollout percentage:
+#
+# chatops: `/chatops run feature get experiment_key_experiment_percentage`
+# console: `Feature.get(:experiment_key_experiment_percentage).percentage_of_time_value`
#
module Gitlab
module Experimentation
EXPERIMENTS = {
signup_flow: {
- feature_toggle: :experimental_separate_sign_up_flow,
- environment: ::Gitlab.dev_env_or_com?,
- enabled_ratio: 1,
tracking_category: 'Growth::Acquisition::Experiment::SignUpFlow'
},
- paid_signup_flow: {
- feature_toggle: :paid_signup_flow,
- environment: ::Gitlab.dev_env_or_com?,
- enabled_ratio: 1,
- tracking_category: 'Growth::Acquisition::Experiment::PaidSignUpFlow'
+ onboarding_issues: {
+ tracking_category: 'Growth::Conversion::Experiment::OnboardingIssues'
},
suggest_pipeline: {
- feature_toggle: :suggest_pipeline,
- environment: ::Gitlab.dev_env_or_com?,
- enabled_ratio: 0.1,
tracking_category: 'Growth::Expansion::Experiment::SuggestPipeline'
},
ci_notification_dot: {
- feature_toggle: :ci_notification_dot,
- environment: ::Gitlab.dev_env_or_com?,
- enabled_ratio: 0.1,
tracking_category: 'Growth::Expansion::Experiment::CiNotificationDot'
},
buy_ci_minutes_version_a: {
- feature_toggle: :buy_ci_minutes_version_a,
- environment: ::Gitlab.dev_env_or_com?,
- enabled_ratio: 0.2,
tracking_category: 'Growth::Expansion::Experiment::BuyCiMinutesVersionA'
+ },
+ upgrade_link_in_user_menu_a: {
+ tracking_category: 'Growth::Expansion::Experiment::UpgradeLinkInUserMenuA'
}
}.freeze
- # Controller concern that checks if an experimentation_subject_id cookie is present and sets it if absent.
+ # Controller concern that checks if an `experimentation_subject_id cookie` is present and sets it if absent.
# Used for A/B testing of experimental features. Exposes the `experiment_enabled?(experiment_name)` method
# to controllers and views. It returns true when the experiment is enabled and the user is selected as part
# of the experimental group.
@@ -144,7 +149,7 @@ module Gitlab
return false unless EXPERIMENTS.key?(experiment_key)
experiment = experiment(experiment_key)
- experiment.feature_toggle_enabled? && experiment.enabled_for_environment?
+ experiment.enabled? && experiment.enabled_for_environment?
end
def enabled_for_user?(experiment_key, experimentation_subject_index)
@@ -153,23 +158,28 @@ module Gitlab
end
end
- Experiment = Struct.new(:key, :feature_toggle, :environment, :enabled_ratio, :tracking_category, keyword_init: true) do
- def feature_toggle_enabled?
- return Feature.enabled?(key, default_enabled: true) if feature_toggle.nil?
-
- Feature.enabled?(feature_toggle)
+ Experiment = Struct.new(:key, :environment, :tracking_category, keyword_init: true) do
+ def enabled?
+ experiment_percentage.positive?
end
def enabled_for_environment?
- return true if environment.nil?
+ return ::Gitlab.dev_env_or_com? if environment.nil?
environment
end
def enabled_for_experimentation_subject?(experimentation_subject_index)
- return false if enabled_ratio.nil? || experimentation_subject_index.blank?
+ return false if experimentation_subject_index.blank?
+
+ experimentation_subject_index <= experiment_percentage
+ end
+
+ private
- experimentation_subject_index <= enabled_ratio * 100
+ # When a feature does not exist, the `percentage_of_time_value` method will return 0
+ def experiment_percentage
+ @experiment_percentage ||= Feature.get(:"#{key}_experiment_percentage").percentage_of_time_value
end
end
end