gitlab-experiment 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c92b7e2d77e534a23b8233f11539fa9c2767b21adab9c247e916933724dd7f5d
4
- data.tar.gz: 7a1144676a16835f64eaefb9ea7bac2b7055c5cf8e329d55dba6c115be17eb50
3
+ metadata.gz: 2ff3ecacc0f83a605ecaad79cef7368802307b9bc1c106eca1c74967ade3a00c
4
+ data.tar.gz: a72ceadbbcd689a290bdf7f85b9dababa7f7ae252bc3886a6fcd42170e561ee7
5
5
  SHA512:
6
- metadata.gz: b7a645b7d2c3cf13d7031fc61dfdaef2626d0092661093a19ff5e21d346adda8cbe031b5c360de21fda3ecee828eaa7bda0a6afe839b6c5ce7ba57f9e10232eb
7
- data.tar.gz: 1a8e4672a903746f5f31f2cf5dcf815bb6e2c3cb8c8fa73430c93462977310fcd6ed2f6f8676d5e2ccf856289c6befde6469e9f29715341c4bde7fd0b14fa51b
6
+ metadata.gz: 6d7f1804cf3503fd0fcf5be75ca6c4d3bfebcdccd3baf5aa3937a7c080e8336c15491a3476a9a7aef30060d0a526f4f71c6803d0a8ae8c08b0192e1401e1070c
7
+ data.tar.gz: 4f739b5852733e789ab23ce0b96215d023e4483ef32ae055373bfe3083d212fb5f01aa8b45ee55bfbac0a8a734e5ec429eac175a49a0219256d6f8f62151027a
data/README.md CHANGED
@@ -499,9 +499,7 @@ Anyway, now you can use your custom `Flipper` rollout strategy by instantiating
499
499
 
500
500
  ```ruby
501
501
  Gitlab::Experiment.configure do |config|
502
- config.default_rollout = Gitlab::Experiment::Rollout::Flipper.new(
503
- include_control: true # specify to include control, which we want to do
504
- )
502
+ config.default_rollout = Gitlab::Experiment::Rollout::Flipper.new
505
503
  end
506
504
  ```
507
505
 
@@ -512,7 +510,6 @@ class PillColorExperiment < Gitlab::Experiment # OR ApplicationExperiment
512
510
  # ...registered behaviors
513
511
 
514
512
  default_rollout :flipper,
515
- include_control: true, # optionally specify to include control
516
513
  distribution: { control: 26, red: 37, blue: 37 } # optionally specify distribution
517
514
  end
518
515
  ```
@@ -8,15 +8,9 @@ module Gitlab
8
8
  source_root File.expand_path('templates/', __dir__)
9
9
  check_class_collision suffix: 'Experiment'
10
10
 
11
- argument :variants,
12
- type: :array,
13
- default: %w[control candidate],
14
- banner: 'variant variant'
15
-
16
- class_option :skip_comments,
17
- type: :boolean,
18
- default: false,
19
- desc: 'Omit helpful comments from generated files'
11
+ argument :variants, type: :array, default: %w[control candidate], banner: 'variant variant'
12
+
13
+ class_option :skip_comments, type: :boolean, default: false, desc: 'Omit helpful comments from generated files'
20
14
 
21
15
  def create_experiment
22
16
  template 'experiment.rb', File.join('app/experiments', class_path, "#{file_name}_experiment.rb")
@@ -11,14 +11,9 @@ module Gitlab
11
11
  desc 'Installs the Gitlab::Experiment initializer and optional ApplicationExperiment into your application.'
12
12
 
13
13
  class_option :skip_initializer,
14
- type: :boolean,
15
- default: false,
16
- desc: 'Skip the initializer with default configuration'
17
-
18
- class_option :skip_baseclass,
19
- type: :boolean,
20
- default: false,
21
- desc: 'Skip the ApplicationExperiment base class'
14
+ type: :boolean, default: false, desc: 'Skip the initializer with default configuration'
15
+
16
+ class_option :skip_baseclass, type: :boolean, default: false, desc: 'Skip the ApplicationExperiment base class'
22
17
 
23
18
  def create_initializer
24
19
  return if options[:skip_initializer]
@@ -43,15 +43,12 @@ Gitlab::Experiment.configure do |config|
43
43
  # Each experiment can specify its own rollout strategy:
44
44
  #
45
45
  # class ExampleExperiment < ApplicationExperiment
46
- # default_rollout :random, # :percent, :round_robin,
47
- # include_control: true # or MyCustomRollout
46
+ # default_rollout :random # :percent, :round_robin, or MyCustomRollout
48
47
  # end
49
48
  #
50
49
  # Included rollout strategies:
51
50
  # :percent (recommended), :round_robin, or :random
52
- config.default_rollout = :percent, {
53
- include_control: true # include control in possible assignments
54
- }
51
+ config.default_rollout = :percent
55
52
 
56
53
  # Secret seed used in generating context keys.
57
54
  #
@@ -48,18 +48,18 @@ module Gitlab
48
48
  key.to_s.split(':') # this assumes the default strategy in gitlab-experiment
49
49
  end
50
50
 
51
- def read_entry(key, **options)
51
+ def read_entry(key, **_options)
52
52
  value = pool { |redis| redis.hget(*hkey(key)) }
53
53
  value.nil? ? nil : ActiveSupport::Cache::Entry.new(value)
54
54
  end
55
55
 
56
- def write_entry(key, entry, **options)
56
+ def write_entry(key, entry, **_options)
57
57
  return false if entry.value.blank? # don't cache any empty values
58
58
 
59
59
  pool { |redis| redis.hset(*hkey(key), entry.value) }
60
60
  end
61
61
 
62
- def delete_entry(key, **options)
62
+ def delete_entry(key, **_options)
63
63
  pool { |redis| redis.hdel(*hkey(key)) }
64
64
  end
65
65
  end
@@ -62,7 +62,9 @@ module Gitlab
62
62
  def migrated_cache_fetch(store, &block)
63
63
  migrations = context.signature[:migration_keys]&.map { |key| cache_key(key) } || []
64
64
  migrations.find do |old_key|
65
- next unless (value = store.read(old_key))
65
+ value = store.read(old_key)
66
+
67
+ next unless value
66
68
 
67
69
  store.write(cache_key, value)
68
70
  store.delete(old_key)
@@ -39,6 +39,11 @@ module Gitlab
39
39
  # nil, :all, or ['www.gitlab.com', '.gitlab.com']
40
40
  @cookie_domain = :all
41
41
 
42
+ # The cookie name for an experiment.
43
+ @cookie_name = lambda do |experiment|
44
+ "#{experiment.name}_id"
45
+ end
46
+
42
47
  # The default rollout strategy.
43
48
  #
44
49
  # The recommended default rollout strategy when not using caching would
@@ -51,8 +56,7 @@ module Gitlab
51
56
  # Each experiment can specify its own rollout strategy:
52
57
  #
53
58
  # class ExampleExperiment < ApplicationExperiment
54
- # default_rollout :random, # :percent, :round_robin,
55
- # include_control: true # or MyCustomRollout
59
+ # default_rollout :random # :percent, :round_robin, or MyCustomRollout
56
60
  # end
57
61
  #
58
62
  # Included rollout strategies:
@@ -172,6 +176,7 @@ module Gitlab
172
176
  :strict_registration,
173
177
  :cache,
174
178
  :cookie_domain,
179
+ :cookie_name,
175
180
  :context_key_secret,
176
181
  :context_key_bit_length,
177
182
  :mount_at,
@@ -7,6 +7,8 @@ module Gitlab
7
7
 
8
8
  DNT_REGEXP = /^(true|t|yes|y|1|on)$/i.freeze
9
9
 
10
+ attr_reader :request
11
+
10
12
  def initialize(experiment, **initial_value)
11
13
  @experiment = experiment
12
14
  @value = {}
@@ -63,7 +65,7 @@ module Gitlab
63
65
  add_unmerged_migration(value.delete(:migrated_from))
64
66
  add_merged_migration(value.delete(:migrated_with))
65
67
 
66
- migrate_cookie(value, "#{@experiment.name}_id")
68
+ migrate_cookie(value, @experiment.instance_exec(@experiment, &Configuration.cookie_name))
67
69
  end
68
70
 
69
71
  def add_unmerged_migration(value = {})
@@ -34,10 +34,10 @@ module Gitlab
34
34
  def validate!
35
35
  case distribution_rules
36
36
  when nil then nil
37
- when Array, Hash
38
- if distribution_rules.length != behavior_names.length
39
- raise InvalidRolloutRules, "the distribution rules don't match the number of behaviors defined"
40
- end
37
+ when Array
38
+ validate_distribution_rules(distribution_rules)
39
+ when Hash
40
+ validate_distribution_rules(distribution_rules.values)
41
41
  else
42
42
  raise InvalidRolloutRules, 'unknown distribution options type'
43
43
  end
@@ -66,6 +66,16 @@ module Gitlab
66
66
  def distribution_rules
67
67
  options[:distribution]
68
68
  end
69
+
70
+ def validate_distribution_rules(distributions)
71
+ if distributions.length != behavior_names.length
72
+ raise InvalidRolloutRules, "the distribution rules don't match the number of behaviors defined"
73
+ end
74
+
75
+ return if distributions.sum == 100
76
+
77
+ raise InvalidRolloutRules, 'the distribution percentages should add up to 100'
78
+ end
69
79
  end
70
80
  end
71
81
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Gitlab
4
4
  class Experiment
5
- VERSION = '0.8.0'
5
+ VERSION = '0.9.1'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-experiment
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-07 00:00:00.000000000 Z
11
+ date:
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -38,6 +38,160 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: gitlab-dangerfiles
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 4.1.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 4.1.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: gitlab-styles
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 10.1.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 10.1.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: lefthook
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.4.7
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.4.7
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 3.10.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 3.10.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-rails
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 2.20.2
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 2.20.2
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 2.22.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 2.22.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: flipper
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 0.26.2
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 0.26.2
139
+ - !ruby/object:Gem::Dependency
140
+ name: generator_spec
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.9.4
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.9.4
153
+ - !ruby/object:Gem::Dependency
154
+ name: rspec-parameterized-table_syntax
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 1.0.0
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 1.0.0
167
+ - !ruby/object:Gem::Dependency
168
+ name: rspec-rails
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: 6.0.3
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: 6.0.3
181
+ - !ruby/object:Gem::Dependency
182
+ name: simplecov-cobertura
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: 2.1.0
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: 2.1.0
41
195
  description:
42
196
  email:
43
197
  - gitlab_rubygems@gitlab.com
@@ -45,23 +199,33 @@ executables: []
45
199
  extensions: []
46
200
  extra_rdoc_files: []
47
201
  files:
48
- - LICENSE.txt
49
- - README.md
202
+ - lib/generators/gitlab
203
+ - lib/generators/gitlab/experiment
50
204
  - lib/generators/gitlab/experiment/USAGE
51
205
  - lib/generators/gitlab/experiment/experiment_generator.rb
206
+ - lib/generators/gitlab/experiment/install
52
207
  - lib/generators/gitlab/experiment/install/install_generator.rb
208
+ - lib/generators/gitlab/experiment/install/templates
53
209
  - lib/generators/gitlab/experiment/install/templates/POST_INSTALL
54
210
  - lib/generators/gitlab/experiment/install/templates/application_experiment.rb.tt
55
211
  - lib/generators/gitlab/experiment/install/templates/initializer.rb.tt
212
+ - lib/generators/gitlab/experiment/templates
56
213
  - lib/generators/gitlab/experiment/templates/experiment.rb.tt
214
+ - lib/generators/rspec
215
+ - lib/generators/rspec/experiment
57
216
  - lib/generators/rspec/experiment/experiment_generator.rb
217
+ - lib/generators/rspec/experiment/templates
58
218
  - lib/generators/rspec/experiment/templates/experiment_spec.rb.tt
219
+ - lib/generators/test_unit
220
+ - lib/generators/test_unit/experiment
59
221
  - lib/generators/test_unit/experiment/experiment_generator.rb
222
+ - lib/generators/test_unit/experiment/templates
60
223
  - lib/generators/test_unit/experiment/templates/experiment_test.rb.tt
61
- - lib/gitlab/experiment.rb
224
+ - lib/gitlab/experiment
62
225
  - lib/gitlab/experiment/base_interface.rb
63
- - lib/gitlab/experiment/cache.rb
226
+ - lib/gitlab/experiment/cache
64
227
  - lib/gitlab/experiment/cache/redis_hash_store.rb
228
+ - lib/gitlab/experiment/cache.rb
65
229
  - lib/gitlab/experiment/callbacks.rb
66
230
  - lib/gitlab/experiment/configuration.rb
67
231
  - lib/gitlab/experiment/context.rb
@@ -71,14 +235,19 @@ files:
71
235
  - lib/gitlab/experiment/errors.rb
72
236
  - lib/gitlab/experiment/middleware.rb
73
237
  - lib/gitlab/experiment/nestable.rb
74
- - lib/gitlab/experiment/rollout.rb
238
+ - lib/gitlab/experiment/rollout
75
239
  - lib/gitlab/experiment/rollout/percent.rb
76
240
  - lib/gitlab/experiment/rollout/random.rb
77
241
  - lib/gitlab/experiment/rollout/round_robin.rb
242
+ - lib/gitlab/experiment/rollout.rb
78
243
  - lib/gitlab/experiment/rspec.rb
244
+ - lib/gitlab/experiment/test_behaviors
79
245
  - lib/gitlab/experiment/test_behaviors/trackable.rb
80
246
  - lib/gitlab/experiment/variant.rb
81
247
  - lib/gitlab/experiment/version.rb
248
+ - lib/gitlab/experiment.rb
249
+ - LICENSE.txt
250
+ - README.md
82
251
  homepage: https://gitlab.com/gitlab-org/ruby/gems/gitlab-experiment
83
252
  licenses:
84
253
  - MIT
@@ -98,7 +267,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
267
  - !ruby/object:Gem::Version
99
268
  version: '0'
100
269
  requirements: []
101
- rubygems_version: 3.4.7
270
+ rubygems_version: 3.3.26
102
271
  signing_key:
103
272
  specification_version: 4
104
273
  summary: GitLab experimentation library.