unleash 4.2.1 → 4.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c185b4a8d20c33f221a482a9f2b58fbf028c019513a89b528a491f738ec1308b
4
- data.tar.gz: 8283a887720d6c8f9a72719a8ff4ff800fd88f3941d5f7d5cea83e4ea079a414
3
+ metadata.gz: f05a01bdf6013184b6948fb5c38f6b1da1cde9d18f9a0eeecd69b54cbed8ff18
4
+ data.tar.gz: 6343830fd945d00decd331acade205d605e0d496ed1d4afd4736affcb2f538ca
5
5
  SHA512:
6
- metadata.gz: 614df5b819537826bc575a1b6b061ca17561d2108c12e9b32581e458f37ca24beccc83046b1b59c9be0d2f2904087b92f6410f3d31bfa57b176228611a55d96e
7
- data.tar.gz: 35528c4f4f5d39db50c13c7266ac620dec6cdb21154b6f0736dea2946e22b81270737d9085144894d7c1b96c858364ce44f5f948ba24f731e2f033ee0677d67c
6
+ metadata.gz: 1ac4a4b89f787b5ae27acda02865def0eb68f261da10b83c01a6b34f6706b1b29443375eb82418b9834db555fbe54c1a1dfe49e9bf4c761556145edce88f76c9
7
+ data.tar.gz: c7a2332c7e6ab54872b08432af4c5c2cf092b7586664eb0267e45e416fb9a72c46246dd6cdedf68b4a9421678e4cb9f9507365e40fc5c2113b9fba8e703a19dd
@@ -0,0 +1,14 @@
1
+ name: Add new item to project board
2
+
3
+ on:
4
+ issues:
5
+ types:
6
+ - opened
7
+ pull_request_target:
8
+ types:
9
+ - opened
10
+
11
+ jobs:
12
+ add-to-project:
13
+ uses: unleash/.github/.github/workflows/add-item-to-project.yml@main
14
+ secrets: inherit
@@ -5,8 +5,21 @@ on:
5
5
  pull_request:
6
6
 
7
7
  jobs:
8
- test:
8
+ lint:
9
+ name: RuboCop
10
+ timeout-minutes: 30
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v2
14
+ - name: Set up Ruby
15
+ uses: ruby/setup-ruby@v1
16
+ with:
17
+ ruby-version: "2.7"
18
+ bundler-cache: true
19
+ - name: Run RuboCop
20
+ run: bundle exec rubocop
9
21
 
22
+ test:
10
23
  runs-on: ${{ matrix.os }}-latest
11
24
 
12
25
  strategy:
@@ -18,7 +31,7 @@ jobs:
18
31
  - jruby-9.2
19
32
  - jruby-9.3
20
33
  - 3.1
21
- - 3.0
34
+ - '3.0'
22
35
  - 2.7
23
36
  - 2.6
24
37
  - 2.5
@@ -34,13 +47,6 @@ jobs:
34
47
  run: bundle install
35
48
  - name: Download test cases
36
49
  run: git clone --depth 5 --branch v4.1.0 https://github.com/Unleash/client-specification.git client-specification
37
- - name: rubocop
38
- uses: reviewdog/action-rubocop@v2
39
- with:
40
- github_token: ${{ secrets.GITHUB_TOKEN }}
41
- rubocop_version: gemfile
42
- rubocop_extensions: rubocop-rspec:gemfile
43
- reporter: github-pr-review # Default is github-pr-check
44
50
  - name: Run tests
45
51
  run: bundle exec rake
46
52
  env:
data/.gitignore CHANGED
@@ -1,6 +1,5 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
- /Gemfile.lock
4
3
  /_yardoc/
5
4
  /coverage/
6
5
  /doc/
@@ -14,6 +13,7 @@
14
13
 
15
14
  # rspec failure tracking
16
15
  .rspec_status
16
+ Gemfile.lock
17
17
 
18
18
  # Clone of the client-specification
19
19
  /client-specification/
data/README.md CHANGED
@@ -41,7 +41,7 @@ It is **required** to configure:
41
41
  - `app_name` with the name of the runninng application.
42
42
  - `custom_http_headers` with `{'Authorization': '<API token>'}` when using Unleash v4.0.0 and later.
43
43
 
44
- Please substitute the example `'http://unleash.herokuapp.com/api'` for the url of your own instance.
44
+ Please substitute the example `'https://unleash.herokuapp.com/api'` for the url of your own instance.
45
45
 
46
46
  It is **highly recommended** to configure:
47
47
  - `instance_id` parameter with a unique identifier for the running instance.
@@ -50,7 +50,7 @@ It is **highly recommended** to configure:
50
50
  ```ruby
51
51
  Unleash.configure do |config|
52
52
  config.app_name = 'my_ruby_app'
53
- config.url = 'http://unleash.herokuapp.com/api'
53
+ config.url = 'https://unleash.herokuapp.com/api'
54
54
  config.custom_http_headers = {'Authorization': '<API token>'}
55
55
  end
56
56
  ```
@@ -58,7 +58,23 @@ end
58
58
  or instantiate the client with the valid configuration:
59
59
 
60
60
  ```ruby
61
- UNLEASH = Unleash::Client.new(url: 'http://unleash.herokuapp.com/api', app_name: 'my_ruby_app', custom_http_headers: {'Authorization': '<API token>'})
61
+ UNLEASH = Unleash::Client.new(url: 'https://unleash.herokuapp.com/api', app_name: 'my_ruby_app', custom_http_headers: {'Authorization': '<API token>'})
62
+ ```
63
+
64
+ ## Dynamic custom HTTP headers
65
+ If you need custom HTTP headers that change during the lifetime of the client, the `custom_http_headers` can be given as a `Proc`.
66
+
67
+ ```ruby
68
+ Unleash.configure do |config|
69
+ config.app_name = 'my_ruby_app'
70
+ config.url = 'https://unleash.herokuapp.com/api'
71
+ config.custom_http_headers = proc do
72
+ {
73
+ 'Authorization': '<API token>',
74
+ 'X-Client-Request-Time': Time.now.iso8601
75
+ }
76
+ end
77
+ end
62
78
  ```
63
79
 
64
80
  #### List of Arguments
@@ -74,7 +90,7 @@ Argument | Description | Required? | Type | Default Value|
74
90
  `metrics_interval` | How often the unleash client should send metrics to server. | N | Integer | 60 |
75
91
  `disable_client` | Disables all communication with the Unleash server, effectively taking it *offline*. If set, `is_enabled?` will always answer with the `default_value` and configuration validation is skipped. Defeats the entire purpose of using unleash, but can be useful in when running tests. | N | Boolean | `false` |
76
92
  `disable_metrics` | Disables sending metrics to Unleash server. | N | Boolean | `false` |
77
- `custom_http_headers` | Custom headers to send to Unleash. As of Unleash v4.0.0, the `Authorization` header is required. For example: `{'Authorization': '<API token>'}` | N | Hash | {} |
93
+ `custom_http_headers` | Custom headers to send to Unleash. As of Unleash v4.0.0, the `Authorization` header is required. For example: `{'Authorization': '<API token>'}` | N | Hash/Proc | {} |
78
94
  `timeout` | How long to wait for the connection to be established or wait in reading state (open_timeout/read_timeout) | N | Integer | 30 |
79
95
  `retry_limit` | How many consecutive failures in connecting to the Unleash server are allowed before giving up. The default is to retry indefinitely. | N | Float::INFINITY | 5 |
80
96
  `backup_file` | Filename to store the last known state from the Unleash server. Best to not change this from the default. | N | String | `Dir.tmpdir + "/unleash-#{app_name}-repo.json` |
@@ -95,7 +111,7 @@ Environment Variable | Description
95
111
  require 'unleash'
96
112
  require 'unleash/context'
97
113
 
98
- @unleash = Unleash::Client.new(app_name: 'my_ruby_app', url: 'http://unleash.herokuapp.com/api', custom_http_headers: { 'Authorization': '<API token>' })
114
+ @unleash = Unleash::Client.new(app_name: 'my_ruby_app', url: 'https://unleash.herokuapp.com/api', custom_http_headers: { 'Authorization': '<API token>' })
99
115
 
100
116
  feature_name = "AwesomeFeature"
101
117
  unleash_context = Unleash::Context.new
@@ -117,7 +133,7 @@ Put in `config/initializers/unleash.rb`:
117
133
  ```ruby
118
134
  Unleash.configure do |config|
119
135
  config.app_name = Rails.application.class.parent.to_s
120
- config.url = 'http://unleash.herokuapp.com/api'
136
+ config.url = 'https://unleash.herokuapp.com/api'
121
137
  # config.instance_id = "#{Socket.gethostname}"
122
138
  config.logger = Rails.logger
123
139
  config.environment = Rails.env
@@ -156,7 +172,7 @@ Then you may keep the client configuration still in `config/initializers/unleash
156
172
  Unleash.configure do |config|
157
173
  config.app_name = Rails.application.class.parent.to_s
158
174
  config.environment = Rails.env
159
- config.url = 'http://unleash.herokuapp.com/api'
175
+ config.url = 'https://unleash.herokuapp.com/api'
160
176
  config.custom_http_headers = {'Authorization': '<API token>'}
161
177
  end
162
178
  ```
@@ -204,7 +220,7 @@ on_worker_boot do
204
220
  ::UNLEASH = Unleash::Client.new(
205
221
  app_name: 'my_rails_app',
206
222
  environment: 'development',
207
- url: 'http://unleash.herokuapp.com/api',
223
+ url: 'https://unleash.herokuapp.com/api',
208
224
  custom_http_headers: {'Authorization': '<API token>'},
209
225
  )
210
226
  end
@@ -230,7 +246,7 @@ PhusionPassenger.on_event(:starting_worker_process) do |forked|
230
246
  # config.instance_id = "#{Socket.gethostname}"
231
247
  config.logger = Rails.logger
232
248
  config.environment = Rails.env
233
- config.url = 'http://unleash.herokuapp.com/api'
249
+ config.url = 'https://unleash.herokuapp.com/api'
234
250
  config.custom_http_headers = {'Authorization': '<API token>'}
235
251
  end
236
252
 
@@ -365,11 +381,11 @@ Bootstrap configuration allows the client to be initialized with a predefined se
365
381
  Bootstrapping can be configured by providing a bootstrap configuration when initializing the client.
366
382
  ```ruby
367
383
  @unleash = Unleash::Client.new(
368
- url: 'http://unleash.herokuapp.com/api',
384
+ url: 'https://unleash.herokuapp.com/api',
369
385
  app_name: 'my_ruby_app',
370
386
  custom_http_headers: { 'Authorization': '<API token>' },
371
387
  bootstrap_config: Unleash::Bootstrap::Configuration.new({
372
- url: "http://unleash.herokuapp.com/api/client/features",
388
+ url: "https://unleash.herokuapp.com/api/client/features",
373
389
  url_headers: {'Authorization': '<API token>'}
374
390
  })
375
391
  )
@@ -395,7 +411,7 @@ Example usage:
395
411
 
396
412
  First saving the toggles locally:
397
413
  ```shell
398
- curl -H 'Authorization: <API token>' -XGET 'http://unleash.herokuapp.com/api' > ./default-toggles.json
414
+ curl -H 'Authorization: <API token>' -XGET 'https://unleash.herokuapp.com/api' > ./default-toggles.json
399
415
  ```
400
416
 
401
417
  Now using them on start up:
@@ -408,7 +424,7 @@ custom_boostrapper = lambda {
408
424
 
409
425
  @unleash = Unleash::Client.new(
410
426
  app_name: 'my_ruby_app',
411
- url: 'http://unleash.herokuapp.com/api',
427
+ url: 'https://unleash.herokuapp.com/api',
412
428
  custom_http_headers: { 'Authorization': '<API token>' },
413
429
  bootstrap_config: Unleash::Bootstrap::Configuration.new({
414
430
  block: custom_boostrapper
@@ -7,7 +7,7 @@ require 'unleash/bootstrap/configuration'
7
7
  puts ">> START bootstrap.rb"
8
8
 
9
9
  @unleash = Unleash::Client.new(
10
- url: 'http://unleash.herokuapp.com/api',
10
+ url: 'https://unleash.herokuapp.com/api',
11
11
  custom_http_headers: { 'Authorization': '943ca9171e2c884c545c5d82417a655fb77cec970cc3b78a8ff87f4406b495d0' },
12
12
  app_name: 'bootstrap-test',
13
13
  instance_id: 'local-test-cli',
data/examples/simple.rb CHANGED
@@ -6,7 +6,7 @@ require 'unleash/context'
6
6
  puts ">> START simple.rb"
7
7
 
8
8
  # Unleash.configure do |config|
9
- # config.url = 'http://unleash.herokuapp.com/api'
9
+ # config.url = 'https://unleash.herokuapp.com/api'
10
10
  # config.custom_http_headers = { 'Authorization': '943ca9171e2c884c545c5d82417a655fb77cec970cc3b78a8ff87f4406b495d0' }
11
11
  # config.app_name = 'simple-test'
12
12
  # config.refresh_interval = 2
@@ -18,7 +18,7 @@ puts ">> START simple.rb"
18
18
  # or:
19
19
 
20
20
  @unleash = Unleash::Client.new(
21
- url: 'http://unleash.herokuapp.com/api',
21
+ url: 'https://unleash.herokuapp.com/api',
22
22
  custom_http_headers: { 'Authorization': '943ca9171e2c884c545c5d82417a655fb77cec970cc3b78a8ff87f4406b495d0' },
23
23
  app_name: 'simple-test',
24
24
  instance_id: 'local-test-cli',
@@ -23,7 +23,7 @@ module Unleash
23
23
  :bootstrap_config
24
24
 
25
25
  def initialize(opts = {})
26
- ensure_valid_opts(opts)
26
+ validate_custom_http_headers!(opts[:custom_http_headers]) if opts.has_key?(:custom_http_headers)
27
27
  set_defaults
28
28
 
29
29
  initialize_default_logger if opts[:logger].nil?
@@ -40,7 +40,8 @@ module Unleash
40
40
  return if self.disable_client
41
41
 
42
42
  raise ArgumentError, "URL and app_name are required parameters." if self.app_name.nil? || self.url.nil?
43
- raise ArgumentError, "custom_http_headers must be a hash." unless self.custom_http_headers.is_a?(Hash)
43
+
44
+ validate_custom_http_headers!(self.custom_http_headers)
44
45
  end
45
46
 
46
47
  def refresh_backup_file!
@@ -51,7 +52,7 @@ module Unleash
51
52
  {
52
53
  'UNLEASH-INSTANCEID' => self.instance_id,
53
54
  'UNLEASH-APPNAME' => self.app_name
54
- }.merge(custom_http_headers.dup)
55
+ }.merge!(generate_custom_http_headers)
55
56
  end
56
57
 
57
58
  def fetch_toggles_uri
@@ -78,12 +79,6 @@ module Unleash
78
79
 
79
80
  private
80
81
 
81
- def ensure_valid_opts(opts)
82
- unless opts[:custom_http_headers].is_a?(Hash) || opts[:custom_http_headers].nil?
83
- raise ArgumentError, "custom_http_headers must be a hash."
84
- end
85
- end
86
-
87
82
  def set_defaults
88
83
  self.app_name = nil
89
84
  self.environment = 'default'
@@ -118,6 +113,18 @@ module Unleash
118
113
  self
119
114
  end
120
115
 
116
+ def validate_custom_http_headers!(custom_http_headers)
117
+ return if custom_http_headers.is_a?(Hash) || custom_http_headers.respond_to?(:call)
118
+
119
+ raise ArgumentError, "custom_http_headers must be a Hash or a Proc."
120
+ end
121
+
122
+ def generate_custom_http_headers
123
+ return self.custom_http_headers.call if self.custom_http_headers.respond_to?(:call)
124
+
125
+ self.custom_http_headers
126
+ end
127
+
121
128
  def set_option(opt, val)
122
129
  __send__("#{opt}=", val)
123
130
  rescue NoMethodError
@@ -65,24 +65,20 @@ module Unleash
65
65
 
66
66
  def save!
67
67
  Unleash.logger.debug "Will save toggles to disk now"
68
- begin
69
- backup_file = Unleash.configuration.backup_file
70
- backup_file_tmp = "#{backup_file}.tmp"
71
68
 
72
- self.toggle_lock.synchronize do
73
- file = File.open(backup_file_tmp, "w")
69
+ backup_file = Unleash.configuration.backup_file
70
+ backup_file_tmp = "#{backup_file}.tmp"
71
+
72
+ self.toggle_lock.synchronize do
73
+ File.open(backup_file_tmp, "w") do |file|
74
74
  file.write(self.toggle_cache.to_json)
75
- file.close
76
- File.rename(backup_file_tmp, backup_file)
77
75
  end
78
- rescue StandardError => e
79
- # This is not really the end of the world. Swallowing the exception.
80
- Unleash.logger.error "Unable to save backup file. Exception thrown #{e.class}:'#{e}'"
81
- Unleash.logger.error "stacktrace: #{e.backtrace}"
82
- ensure
83
- file&.close if defined?(file)
84
- self.toggle_lock.unlock if self.toggle_lock.locked?
76
+ File.rename(backup_file_tmp, backup_file)
85
77
  end
78
+ rescue StandardError => e
79
+ # This is not really the end of the world. Swallowing the exception.
80
+ Unleash.logger.error "Unable to save backup file. Exception thrown #{e.class}:'#{e}'"
81
+ Unleash.logger.error "stacktrace: #{e.backtrace}"
86
82
  end
87
83
 
88
84
  private
@@ -110,22 +106,15 @@ module Unleash
110
106
  backup_file = Unleash.configuration.backup_file
111
107
  return nil unless File.exist?(backup_file)
112
108
 
113
- begin
114
- file = File.new(backup_file, "r")
115
- file_content = file.read
116
-
117
- backup_as_hash = JSON.parse(file_content)
118
- synchronize_with_local_cache!(backup_as_hash)
119
- update_running_client!
120
- rescue IOError => e
121
- Unleash.logger.error "Unable to read the backup_file: #{e}"
122
- rescue JSON::ParserError => e
123
- Unleash.logger.error "Unable to parse JSON from existing backup_file: #{e}"
124
- rescue StandardError => e
125
- Unleash.logger.error "Unable to extract valid data from backup_file. Exception thrown: #{e}"
126
- ensure
127
- file&.close
128
- end
109
+ backup_as_hash = JSON.parse(File.read(backup_file))
110
+ synchronize_with_local_cache!(backup_as_hash)
111
+ update_running_client!
112
+ rescue IOError => e
113
+ Unleash.logger.error "Unable to read the backup_file: #{e}"
114
+ rescue JSON::ParserError => e
115
+ Unleash.logger.error "Unable to parse JSON from existing backup_file: #{e}"
116
+ rescue StandardError => e
117
+ Unleash.logger.error "Unable to extract valid data from backup_file. Exception thrown: #{e}"
129
118
  end
130
119
 
131
120
  def bootstrap
@@ -1,3 +1,3 @@
1
1
  module Unleash
2
- VERSION = "4.2.1".freeze
2
+ VERSION = "4.3.0".freeze
3
3
  end
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency "rspec-json_expectations", "~> 2.2"
32
32
  spec.add_development_dependency "webmock", "~> 3.8"
33
33
 
34
- spec.add_development_dependency "rubocop", "~> 0.80"
34
+ spec.add_development_dependency "rubocop", "< 1.0.0"
35
35
  spec.add_development_dependency "simplecov", "~> 0.21.2"
36
36
  spec.add_development_dependency "simplecov-lcov", "~> 0.8.0"
37
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unleash
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.1
4
+ version: 4.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Renato Arruda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-29 00:00:00.000000000 Z
11
+ date: 2022-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: murmurhash3
@@ -98,16 +98,16 @@ dependencies:
98
98
  name: rubocop
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - "<"
102
102
  - !ruby/object:Gem::Version
103
- version: '0.80'
103
+ version: 1.0.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - "<"
109
109
  - !ruby/object:Gem::Version
110
- version: '0.80'
110
+ version: 1.0.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: simplecov
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -146,6 +146,7 @@ executables:
146
146
  extensions: []
147
147
  extra_rdoc_files: []
148
148
  files:
149
+ - ".github/workflows/add-to-project.yml"
149
150
  - ".github/workflows/pull_request.yml"
150
151
  - ".gitignore"
151
152
  - ".rspec"