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 +4 -4
- data/README.md +1 -4
- data/lib/generators/gitlab/experiment/experiment_generator.rb +3 -9
- data/lib/generators/gitlab/experiment/install/install_generator.rb +3 -8
- data/lib/generators/gitlab/experiment/install/templates/initializer.rb.tt +2 -5
- data/lib/gitlab/experiment/cache/redis_hash_store.rb +3 -3
- data/lib/gitlab/experiment/cache.rb +3 -1
- data/lib/gitlab/experiment/configuration.rb +7 -2
- data/lib/gitlab/experiment/context.rb +3 -1
- data/lib/gitlab/experiment/rollout/percent.rb +14 -4
- data/lib/gitlab/experiment/version.rb +1 -1
- metadata +177 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2ff3ecacc0f83a605ecaad79cef7368802307b9bc1c106eca1c74967ade3a00c
|
4
|
+
data.tar.gz: a72ceadbbcd689a290bdf7f85b9dababa7f7ae252bc3886a6fcd42170e561ee7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
12
|
-
|
13
|
-
|
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
|
-
|
15
|
-
|
16
|
-
|
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
|
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, **
|
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, **
|
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, **
|
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
|
-
|
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
|
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,
|
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
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
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.
|
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:
|
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
|
-
-
|
49
|
-
-
|
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
|
224
|
+
- lib/gitlab/experiment
|
62
225
|
- lib/gitlab/experiment/base_interface.rb
|
63
|
-
- lib/gitlab/experiment/cache
|
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
|
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.
|
270
|
+
rubygems_version: 3.3.26
|
102
271
|
signing_key:
|
103
272
|
specification_version: 4
|
104
273
|
summary: GitLab experimentation library.
|