gitlab-experiment 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/gitlab/experiment/install/templates/initializer.rb.tt +10 -0
- data/lib/gitlab/experiment.rb +7 -0
- data/lib/gitlab/experiment/base_interface.rb +1 -1
- data/lib/gitlab/experiment/configuration.rb +8 -5
- data/lib/gitlab/experiment/dsl.rb +4 -0
- data/lib/gitlab/experiment/engine.rb +27 -19
- data/lib/gitlab/experiment/middleware.rb +2 -2
- data/lib/gitlab/experiment/rspec.rb +1 -1
- data/lib/gitlab/experiment/version.rb +1 -1
- metadata +35 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd00eb06f769b8268e0e02e7d48b38dbef6be029c8f4d02b127e9f2b44f9dbc3
|
4
|
+
data.tar.gz: 7a3b9c5357489afd4b14bd6411536b1a2484c50f44934cc646b20abd1607ab0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '08ea7e0b62c92e7674a72271e388dd104878ad2b9328ad016fba758762e244b51da1a089cec0d74e1db11fba4da3e2bc59524ef2839424295fa3c7307c73cb87'
|
7
|
+
data.tar.gz: 7ecfc7bbaa0803b67ccfd642c7c06baec43cde54b41cc768a7c1a1537e5c6cae6e13a355bdf342d4cdaebef15f5a1b99e76676c87612d857affb865bb543e07d
|
@@ -56,6 +56,16 @@ Gitlab::Experiment.configure do |config|
|
|
56
56
|
# '/-/experiment', '/redirect', nil
|
57
57
|
config.mount_at = '/experiment'
|
58
58
|
|
59
|
+
# When using the middleware, links can be instrumented and redirected
|
60
|
+
# elsewhere. This can be exploited to make a harmful url look innocuous or
|
61
|
+
# that it's a valid url on your domain. To avoid this, you can provide your
|
62
|
+
# own logic for what urls will be considered valid and redirected to.
|
63
|
+
#
|
64
|
+
# Expected to return a boolean value.
|
65
|
+
config.redirect_url_validator = lambda do |redirect_url|
|
66
|
+
true
|
67
|
+
end
|
68
|
+
|
59
69
|
# Logic this project uses to determine inclusion in a given experiment.
|
60
70
|
#
|
61
71
|
# Expected to return a boolean value.
|
data/lib/gitlab/experiment.rb
CHANGED
@@ -120,6 +120,13 @@ module Gitlab
|
|
120
120
|
instance_exec(action, event_args, &Configuration.tracking_behavior)
|
121
121
|
end
|
122
122
|
|
123
|
+
def process_redirect_url(url)
|
124
|
+
return unless Configuration.redirect_url_validator&.call(url)
|
125
|
+
|
126
|
+
track('visited', url: url)
|
127
|
+
url # return the url, which allows for mutation
|
128
|
+
end
|
129
|
+
|
123
130
|
def enabled?
|
124
131
|
true
|
125
132
|
end
|
@@ -39,17 +39,19 @@ module Gitlab
|
|
39
39
|
|
40
40
|
# The default base path that the middleware (or rails engine) will be
|
41
41
|
# mounted.
|
42
|
-
@mount_at =
|
42
|
+
@mount_at = nil
|
43
|
+
|
44
|
+
# The middleware won't redirect to urls that aren't considered valid.
|
45
|
+
# Expected to return a boolean value.
|
46
|
+
@redirect_url_validator = ->(_redirect_url) { true }
|
43
47
|
|
44
48
|
# Logic this project uses to determine inclusion in a given experiment.
|
45
49
|
# Expected to return a boolean value.
|
46
|
-
@inclusion_resolver =
|
47
|
-
false
|
48
|
-
end
|
50
|
+
@inclusion_resolver = ->(_requested_variant) { false }
|
49
51
|
|
50
52
|
# Tracking behavior can be implemented to link an event to an experiment.
|
51
53
|
@tracking_behavior = lambda do |event, args|
|
52
|
-
Configuration.logger.info
|
54
|
+
Configuration.logger.info("#{self.class.name}[#{name}] #{event}: #{args.merge(signature: signature)}")
|
53
55
|
end
|
54
56
|
|
55
57
|
# Called at the end of every experiment run, with the result.
|
@@ -88,6 +90,7 @@ module Gitlab
|
|
88
90
|
:context_key_bit_length,
|
89
91
|
:mount_at,
|
90
92
|
:default_rollout,
|
93
|
+
:redirect_url_validator,
|
91
94
|
:inclusion_resolver,
|
92
95
|
:tracking_behavior,
|
93
96
|
:publishing_behavior
|
@@ -3,6 +3,10 @@
|
|
3
3
|
module Gitlab
|
4
4
|
class Experiment
|
5
5
|
module Dsl
|
6
|
+
def self.include_in(klass, with_helper: false)
|
7
|
+
klass.include(self).tap { |base| base.helper_method(:experiment) if with_helper }
|
8
|
+
end
|
9
|
+
|
6
10
|
def experiment(name, variant_name = nil, **context, &block)
|
7
11
|
raise ArgumentError, 'name is required' if name.nil?
|
8
12
|
|
@@ -1,34 +1,42 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'active_model'
|
4
|
+
|
3
5
|
module Gitlab
|
4
6
|
class Experiment
|
7
|
+
include ActiveModel::Model
|
8
|
+
|
9
|
+
# used for generating routes
|
10
|
+
def self.model_name
|
11
|
+
ActiveModel::Name.new(self, Gitlab)
|
12
|
+
end
|
13
|
+
|
5
14
|
class Engine < ::Rails::Engine
|
6
|
-
|
7
|
-
if defined?(ActionController)
|
8
|
-
ActionController::Base.include(Dsl)
|
9
|
-
ActionController::Base.helper_method(:experiment)
|
10
|
-
end
|
15
|
+
isolate_namespace Experiment
|
11
16
|
|
12
|
-
|
17
|
+
initializer('gitlab_experiment.include_dsl') { include_dsl }
|
18
|
+
initializer('gitlab_experiment.mount_engine') { |app| mount_engine(app, Configuration.mount_at) }
|
13
19
|
|
14
|
-
|
15
|
-
|
20
|
+
private
|
21
|
+
|
22
|
+
def include_dsl
|
23
|
+
Dsl.include_in(ActionController::Base, with_helper: true) if defined?(ActionController)
|
24
|
+
Dsl.include_in(ActionMailer::Base, with_helper: true) if defined?(ActionMailer)
|
16
25
|
end
|
17
26
|
|
18
|
-
def
|
19
|
-
return if
|
27
|
+
def mount_engine(app, mount_at)
|
28
|
+
return if mount_at.blank?
|
20
29
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
[base_path, experiment.to_param].join('/') + "?#{to_url}"
|
25
|
-
end
|
30
|
+
engine = routes do
|
31
|
+
default_url_options app.routes.default_url_options
|
32
|
+
resources :experiments, path: '/', only: :show
|
26
33
|
end
|
27
|
-
end
|
28
34
|
|
29
|
-
|
30
|
-
|
31
|
-
|
35
|
+
app.config.middleware.use(Middleware, mount_at)
|
36
|
+
app.routes.append do
|
37
|
+
mount Engine, at: mount_at, as: :experiment_engine
|
38
|
+
direct(:experiment_redirect) { |ex, url:| "#{engine.url_helpers.experiment_url(ex)}?#{url}" }
|
39
|
+
end
|
32
40
|
end
|
33
41
|
end
|
34
42
|
end
|
@@ -6,8 +6,8 @@ module Gitlab
|
|
6
6
|
def self.redirect(id, url)
|
7
7
|
raise Error, 'no url to redirect to' if url.blank?
|
8
8
|
|
9
|
-
Gitlab::Experiment.from_param(id)
|
10
|
-
[303, { 'Location' => url }, []]
|
9
|
+
experiment = Gitlab::Experiment.from_param(id)
|
10
|
+
[303, { 'Location' => experiment.process_redirect_url(url) || raise(Error, 'not redirecting') }, []]
|
11
11
|
end
|
12
12
|
|
13
13
|
def initialize(app, base_path)
|
@@ -82,7 +82,7 @@ module Gitlab
|
|
82
82
|
extend RSpec::Matchers::DSL
|
83
83
|
|
84
84
|
def require_experiment(experiment, matcher_name, classes: false)
|
85
|
-
klass = experiment.
|
85
|
+
klass = experiment.instance_of?(Class) ? experiment : experiment.class
|
86
86
|
unless klass <= Gitlab::Experiment
|
87
87
|
raise(
|
88
88
|
ArgumentError,
|
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.6.
|
4
|
+
version: 0.6.2
|
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
|
@@ -65,38 +65,52 @@ executables: []
|
|
65
65
|
extensions: []
|
66
66
|
extra_rdoc_files: []
|
67
67
|
files:
|
68
|
-
-
|
69
|
-
-
|
70
|
-
- lib/generators/gitlab/experiment/
|
71
|
-
- lib/generators/gitlab/experiment/experiment_generator.rb
|
68
|
+
- lib/generators/gitlab
|
69
|
+
- lib/generators/gitlab/experiment
|
70
|
+
- lib/generators/gitlab/experiment/install
|
72
71
|
- lib/generators/gitlab/experiment/install/install_generator.rb
|
73
|
-
- lib/generators/gitlab/experiment/install/templates
|
72
|
+
- lib/generators/gitlab/experiment/install/templates
|
74
73
|
- lib/generators/gitlab/experiment/install/templates/application_experiment.rb.tt
|
75
74
|
- lib/generators/gitlab/experiment/install/templates/initializer.rb.tt
|
75
|
+
- lib/generators/gitlab/experiment/install/templates/POST_INSTALL
|
76
|
+
- lib/generators/gitlab/experiment/USAGE
|
77
|
+
- lib/generators/gitlab/experiment/experiment_generator.rb
|
78
|
+
- lib/generators/gitlab/experiment/templates
|
76
79
|
- lib/generators/gitlab/experiment/templates/experiment.rb.tt
|
77
|
-
- lib/generators/
|
78
|
-
- lib/generators/
|
80
|
+
- lib/generators/test_unit
|
81
|
+
- lib/generators/test_unit/experiment
|
79
82
|
- lib/generators/test_unit/experiment/experiment_generator.rb
|
83
|
+
- lib/generators/test_unit/experiment/templates
|
80
84
|
- lib/generators/test_unit/experiment/templates/experiment_test.rb.tt
|
85
|
+
- lib/generators/rspec
|
86
|
+
- lib/generators/rspec/experiment
|
87
|
+
- lib/generators/rspec/experiment/experiment_generator.rb
|
88
|
+
- lib/generators/rspec/experiment/templates
|
89
|
+
- lib/generators/rspec/experiment/templates/experiment_spec.rb.tt
|
81
90
|
- lib/gitlab/experiment.rb
|
82
|
-
- lib/gitlab/experiment
|
83
|
-
- lib/gitlab/experiment/
|
91
|
+
- lib/gitlab/experiment
|
92
|
+
- lib/gitlab/experiment/variant.rb
|
93
|
+
- lib/gitlab/experiment/middleware.rb
|
94
|
+
- lib/gitlab/experiment/cache
|
84
95
|
- lib/gitlab/experiment/cache/redis_hash_store.rb
|
96
|
+
- lib/gitlab/experiment/errors.rb
|
85
97
|
- lib/gitlab/experiment/callbacks.rb
|
86
|
-
- lib/gitlab/experiment/
|
98
|
+
- lib/gitlab/experiment/rollout.rb
|
99
|
+
- lib/gitlab/experiment/base_interface.rb
|
87
100
|
- lib/gitlab/experiment/context.rb
|
88
|
-
- lib/gitlab/experiment/cookies.rb
|
89
|
-
- lib/gitlab/experiment/dsl.rb
|
90
101
|
- lib/gitlab/experiment/engine.rb
|
91
|
-
- lib/gitlab/experiment/
|
92
|
-
- lib/gitlab/experiment/
|
93
|
-
- lib/gitlab/experiment/rollout.rb
|
94
|
-
- lib/gitlab/experiment/rollout/percent.rb
|
102
|
+
- lib/gitlab/experiment/rspec.rb
|
103
|
+
- lib/gitlab/experiment/rollout
|
95
104
|
- lib/gitlab/experiment/rollout/random.rb
|
96
105
|
- lib/gitlab/experiment/rollout/round_robin.rb
|
97
|
-
- lib/gitlab/experiment/
|
98
|
-
- lib/gitlab/experiment/
|
106
|
+
- lib/gitlab/experiment/rollout/percent.rb
|
107
|
+
- lib/gitlab/experiment/cache.rb
|
99
108
|
- lib/gitlab/experiment/version.rb
|
109
|
+
- lib/gitlab/experiment/cookies.rb
|
110
|
+
- lib/gitlab/experiment/configuration.rb
|
111
|
+
- lib/gitlab/experiment/dsl.rb
|
112
|
+
- LICENSE.txt
|
113
|
+
- README.md
|
100
114
|
homepage: https://gitlab.com/gitlab-org/gitlab-experiment
|
101
115
|
licenses:
|
102
116
|
- MIT
|
@@ -116,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
130
|
- !ruby/object:Gem::Version
|
117
131
|
version: '0'
|
118
132
|
requirements: []
|
119
|
-
rubygems_version: 3.
|
133
|
+
rubygems_version: 3.1.4
|
120
134
|
signing_key:
|
121
135
|
specification_version: 4
|
122
136
|
summary: GitLab experiment library built on top of scientist.
|