promoted-ruby-client 0.1.17 → 0.1.21
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/.github/workflows/push-pull-requests_check.yml +16 -0
- data/Gemfile.lock +1 -1
- data/README.md +70 -0
- data/dev.md +1 -1
- data/lib/promoted/ruby/client/constants.rb +7 -0
- data/lib/promoted/ruby/client/pager.rb +4 -4
- data/lib/promoted/ruby/client/request_builder.rb +25 -6
- data/lib/promoted/ruby/client/version.rb +1 -1
- data/lib/promoted/ruby/client.rb +30 -12
- data/promoted-ruby-client.gemspec +1 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 526e2104c5f4658b67b971a1a2f19639ea383ddcee8556dd496c906c7aed8d86
|
4
|
+
data.tar.gz: f3e6afce46a2995b8497f8426d7fcccda89e9a0c533d270a55dd72598c6a0287
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3b5e39490f8ceac8c261cfd6a7b3c9264980b98306bf7ac520fcc4f4855600329f43fc1eee55a22f4c8968c1d44eaa1ae47fa1ed737d61fbce6b8e5064eabb8
|
7
|
+
data.tar.gz: 94fe93237603bc0be26b54a5a7ecbd39f45065d2e878610e240079a946ecde5697b39894a6c7b2fd2817b51fdc60462d5edc66c279be3038e79618e14c9e6deb
|
@@ -0,0 +1,16 @@
|
|
1
|
+
name: Pull-Requests Check
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
Test:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
steps:
|
9
|
+
- uses: actions/checkout@v2
|
10
|
+
- uses: ruby/setup-ruby@v1
|
11
|
+
with:
|
12
|
+
ruby-version: 2.5.1
|
13
|
+
bundler-cache: true
|
14
|
+
|
15
|
+
- name: Build and test with rspec
|
16
|
+
run: bundle exec rspec spec
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -49,6 +49,7 @@ Name | Type | Description
|
|
49
49
|
```:perform_checks``` | Boolean | Whether or not to perform detailed input validation, defaults to true but may be disabled for performance
|
50
50
|
```:logger``` | Ruby Logger-compatible logger | Defaults to nil (no logging). Example: ```Logger.new(STDERR, :progname => 'promotedai')```
|
51
51
|
```:shadow_traffic_delivery_percent``` | Number between 0 and 1 | % of ```prepare_for_logging``` traffic that gets directed to Delivery API as "shadow traffic". Defaults to 0 (no shadow traffic).
|
52
|
+
```:send_shadow_traffic_for_control``` | Boolean | If true, the ```deliver``` method will send shadow traffic for users in the CONTROL arm of an experiment. Defaults to true.
|
52
53
|
```:default_request_headers``` | Hash | Additional headers to send on the request beyond ```x-api-key```. Defaults to {}
|
53
54
|
```:default_only_log``` | Boolean | If true, the ```deliver``` method will not direct traffic to Delivery API but rather return a request suitable for logging. Defaults to false.
|
54
55
|
```:should_apply_treatment_func``` | Proc | Called during delivery, accepts an experiment and returns a Boolean indicating whether the request should be considered part of the control group (false) or in the experiment (true). If nil, the default behavior of checking the experiement ```:arm``` is applied.
|
@@ -94,7 +95,73 @@ Field Name | Type | Optional? | Description
|
|
94
95
|
```:request_id``` | String | Yes | Generated by the SDK when needed (*do not set*)
|
95
96
|
```:content_id``` | String | No | Identifier for the content to be shown, must be set.
|
96
97
|
```:properties``` | Properties | Yes | Any additional custom properties to associate. For v1 integrations, it is fine not to fill in all the properties.
|
98
|
+
---
|
99
|
+
### Size
|
100
|
+
User's screen dimensions.
|
101
|
+
Field Name | Type | Optional? | Description
|
102
|
+
---------- | ---- | --------- | -----------
|
103
|
+
```:width``` | Integer | No | Screen width
|
104
|
+
```:height``` | Integer | No | Screen height
|
105
|
+
---
|
97
106
|
|
107
|
+
### Screen
|
108
|
+
State of the screen including scaling.
|
109
|
+
Field Name | Type | Optional? | Description
|
110
|
+
---------- | ---- | --------- | -----------
|
111
|
+
```:size``` | Size | Yes | Screen size
|
112
|
+
```:scale``` | Float | Yes | Current screen scaling factor
|
113
|
+
---
|
114
|
+
|
115
|
+
### ClientHints
|
116
|
+
Alternative to user-agent strings. See https://raw.githubusercontent.com/snowplow/iglu-central/master/schemas/org.ietf/http_client_hints/jsonschema/1-0-0
|
117
|
+
Field Name | Type | Optional? | Description
|
118
|
+
---------- | ---- | --------- | -----------
|
119
|
+
```:is_mobile``` | Boolean | Yes | Mobile flag
|
120
|
+
```:brand``` | Array of ClientBrandHint | Yes |
|
121
|
+
```:architecture``` | String | Yes |
|
122
|
+
```:model``` | String | Yes |
|
123
|
+
```:platform``` | String | Yes |
|
124
|
+
```:platform_version``` | String | Yes |
|
125
|
+
```:ua_full_version``` | String | Yes |
|
126
|
+
|
127
|
+
---
|
128
|
+
### ClientBrandHint
|
129
|
+
See https://raw.githubusercontent.com/snowplow/iglu-central/master/schemas/org.ietf/http_client_hints/jsonschema/1-0-0
|
130
|
+
Field Name | Type | Optional? | Description
|
131
|
+
---------- | ---- | --------- | -----------
|
132
|
+
```:brand``` | String | Yes | Mobile flag
|
133
|
+
```:version``` | String | Yes |
|
134
|
+
|
135
|
+
---
|
136
|
+
### Location
|
137
|
+
Information about the user's location.
|
138
|
+
Field Name | Type | Optional? | Description
|
139
|
+
---------- | ---- | --------- | -----------
|
140
|
+
```:latitude``` | Float | No | Location latitude
|
141
|
+
```:longitude``` | Float | No | Location longitude
|
142
|
+
```:accuracy_in_meters``` | Integer | Yes | Location accuracy if available
|
143
|
+
---
|
144
|
+
|
145
|
+
### Browser
|
146
|
+
Information about the user's browser.
|
147
|
+
Field Name | Type | Optional? | Description
|
148
|
+
---------- | ---- | --------- | -----------
|
149
|
+
```:user_agent``` | String | Yes | Browser user agent string
|
150
|
+
```:viewport_size``` | Size | Yes | Size of the browser viewport
|
151
|
+
```:client_hints``` | ClientHints | Yes | HTTP client hints structure
|
152
|
+
---
|
153
|
+
### Device
|
154
|
+
Information about the user's device.
|
155
|
+
Field Name | Type | Optional? | Description
|
156
|
+
---------- | ---- | --------- | -----------
|
157
|
+
```:device_type``` | one of (`UNKNOWN_DEVICE_TYPE`, `DESKTOP`, `MOBILE`, `TABLET`) | Yes | Type of device
|
158
|
+
```:brand``` | String | Yes | "Apple, "google", Samsung", etc.
|
159
|
+
```:manufacturer``` | String | Yes | "Apple", "HTC", Motorola", "HUAWEI", etc.
|
160
|
+
```:identifier``` | String | Yes | Android: android.os.Build.MODEL; iOS: iPhoneXX,YY, etc.
|
161
|
+
```:screen``` | Screen | Yes | Screen dimensions
|
162
|
+
```:ip_address``` | String | Yes | Originating IP address
|
163
|
+
```:location``` | Location | Yes | Location information
|
164
|
+
```:browser``` | Browser | Yes | Browser information
|
98
165
|
---
|
99
166
|
### Paging
|
100
167
|
#### TODO
|
@@ -108,6 +175,7 @@ Field Name | Type | Optional? | Description
|
|
108
175
|
```:use_case``` | String | Yes | One of the use case values, i.e. 'FEED' (see [constants.rb](https://github.com/promotedai/promoted-ruby-client/blob/main/lib/promoted/ruby/client/constants.rb)).
|
109
176
|
```:properties``` | Properties | Yes | Any additional custom properties to associate.
|
110
177
|
```:paging``` | Paging | Yes | Paging parameters (see TODO)
|
178
|
+
```:device``` | Device | Yes | Device information (as available)
|
111
179
|
---
|
112
180
|
### MetricsRequest
|
113
181
|
Input to ```prepare_for_logging```
|
@@ -142,6 +210,8 @@ Field Name | Type | Optional? | Description
|
|
142
210
|
---------- | ---- | --------- | -----------
|
143
211
|
```:insertion``` | [] of Insertion | No | The insertions, which are from Delivery API (when ```deliver``` was called, i.e. we weren't either only-log or part of an experiment) or the input insertions (when the other conditions don't hold).
|
144
212
|
```:log_request``` | LogRequest | Yes | A message suitable for logging to Metrics API via ```send_log_request```. If the call to ```deliver``` was made (i.e. the request was not part of the CONTROL arm of an experiment or marked to only log), ```:log_request``` will not be set, as you can assume logging was performed on the server-side by Promoted.
|
213
|
+
```:client_request_id``` | String | Yes | Client-generated request id sent to Delivery API and may be useful for logging and debugging.
|
214
|
+
```:execution_server``` | one of 'API' or 'SDK' | Yes | Indicates if response insertions on a delivery request came from the API or the SDK.
|
145
215
|
---
|
146
216
|
|
147
217
|
### PromotedClient
|
data/dev.md
CHANGED
@@ -4,5 +4,5 @@
|
|
4
4
|
2. Get credentials for deployment from 1password.
|
5
5
|
3. Modify `promoted-ruby-client.gemspec`'s push block.
|
6
6
|
4. Run `gem build promoted-ruby-client.gemspec` to generate `gem`.
|
7
|
-
5. Run (using new output) `gem push promoted-ruby-client-0.1.
|
7
|
+
5. Run (using new output) `gem push promoted-ruby-client-0.1.21.gem`
|
8
8
|
6. Update README with new version.
|
@@ -32,6 +32,13 @@ module Promoted
|
|
32
32
|
CLIENT_TYPE = {'UNKNOWN_REQUEST_CLIENT' => 'UNKNOWN_REQUEST_CLIENT',
|
33
33
|
'PLATFORM_SERVER' => 'PLATFORM_SERVER',
|
34
34
|
'PLATFORM_CLIENT' => 'PLATFORM_CLIENT'}
|
35
|
+
|
36
|
+
EXECUTION_SERVER = {'API' => 'API', 'SDK' => 'SDK'}
|
37
|
+
|
38
|
+
DEVICE_TYPE = {'UNKNOWN_DEVICE_TYPE' => 'UNKNOWN_DEVICE_TYPE',
|
39
|
+
'DESKTOP' => 'DESKTOP',
|
40
|
+
'MOBILE' => 'MOBILE',
|
41
|
+
'TABLET' => 'TABLET'}
|
35
42
|
end
|
36
43
|
end
|
37
44
|
end
|
@@ -11,13 +11,13 @@ module Promoted
|
|
11
11
|
end
|
12
12
|
|
13
13
|
class Pager
|
14
|
-
def validate_paging
|
14
|
+
def validate_paging(insertions, paging)
|
15
15
|
if paging && paging[:offset] && paging[:offset] >= insertions.length
|
16
16
|
raise InvalidPagingError.new("Invalid page offset (insertion size #{insertions.length}, offset #{paging[:offset]})", [])
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
def apply_paging
|
20
|
+
def apply_paging(insertions, insertion_page_type, paging = nil)
|
21
21
|
begin
|
22
22
|
validate_paging(insertions, paging)
|
23
23
|
rescue InvalidPagingError => err
|
@@ -47,7 +47,7 @@ module Promoted
|
|
47
47
|
size = insertions.length
|
48
48
|
end
|
49
49
|
|
50
|
-
final_insertion_size = [size, insertions.length].min
|
50
|
+
final_insertion_size = [size, insertions.length - index].min
|
51
51
|
insertion_page = Array.new(final_insertion_size)
|
52
52
|
0.upto(final_insertion_size - 1) {|i|
|
53
53
|
insertion = insertions[index]
|
@@ -63,5 +63,5 @@ module Promoted
|
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
66
|
-
|
66
|
+
end
|
67
67
|
end
|
@@ -2,7 +2,7 @@ module Promoted
|
|
2
2
|
module Ruby
|
3
3
|
module Client
|
4
4
|
class RequestBuilder
|
5
|
-
attr_reader :session_id, :only_log, :experiment, :client_info,
|
5
|
+
attr_reader :session_id, :only_log, :experiment, :client_info, :device,
|
6
6
|
:view_id, :insertion, :to_compact_delivery_properties_func,
|
7
7
|
:request_id, :full_insertion, :use_case, :request, :to_compact_metrics_properties_func
|
8
8
|
|
@@ -24,6 +24,7 @@ module Promoted
|
|
24
24
|
@session_id = request[:session_id]
|
25
25
|
@platform_id = request[:platform_id]
|
26
26
|
@client_info = request[:client_info] || {}
|
27
|
+
@device = request[:device] || {}
|
27
28
|
@view_id = request[:view_id]
|
28
29
|
@use_case = Promoted::Ruby::Client::USE_CASES[request[:use_case]] || Promoted::Ruby::Client::USE_CASES['UNKNOWN_USE_CASE']
|
29
30
|
@full_insertion = args[:full_insertion]
|
@@ -56,7 +57,8 @@ module Promoted
|
|
56
57
|
params = {
|
57
58
|
user_info: user_info,
|
58
59
|
timing: timing,
|
59
|
-
client_info:
|
60
|
+
client_info: merge_client_info_defaults,
|
61
|
+
device: @device,
|
60
62
|
platform_id: @platform_id,
|
61
63
|
view_id: @view_id,
|
62
64
|
session_id: @session_id,
|
@@ -64,7 +66,7 @@ module Promoted
|
|
64
66
|
search_query: request[:search_query],
|
65
67
|
properties: request[:properties],
|
66
68
|
paging: request[:paging],
|
67
|
-
client_request_id:
|
69
|
+
client_request_id: client_request_id
|
68
70
|
}
|
69
71
|
params[:insertion] = insertions_with_compact_props(@to_compact_delivery_properties_func)
|
70
72
|
|
@@ -76,7 +78,7 @@ module Promoted
|
|
76
78
|
# to the responses.
|
77
79
|
def fill_details_from_response response_insertions
|
78
80
|
if !response_insertions then
|
79
|
-
response_insertions =
|
81
|
+
response_insertions = []
|
80
82
|
end
|
81
83
|
|
82
84
|
props = @full_insertion.each_with_object({}) do |insertion, hash|
|
@@ -102,7 +104,8 @@ module Promoted
|
|
102
104
|
params = {
|
103
105
|
user_info: user_info,
|
104
106
|
timing: timing,
|
105
|
-
client_info:
|
107
|
+
client_info: merge_client_info_defaults,
|
108
|
+
device: @device
|
106
109
|
}
|
107
110
|
|
108
111
|
if @experiment
|
@@ -128,7 +131,12 @@ module Promoted
|
|
128
131
|
|
129
132
|
# Only need a copy if there are properties to compact.
|
130
133
|
compact_insertion = insertion.dup
|
131
|
-
|
134
|
+
|
135
|
+
# Let the custom function work with a deep copy of the properties.
|
136
|
+
# There's really no way to work with a shallow copy and still be able
|
137
|
+
# to restore the correct insertion properties after a call to delivery.
|
138
|
+
new_props = Marshal.load(Marshal.dump(insertion[:properties]))
|
139
|
+
compact_insertion[:properties] = compact_func.call(new_props)
|
132
140
|
compact_insertion.clean!
|
133
141
|
return compact_insertion
|
134
142
|
end
|
@@ -179,8 +187,19 @@ module Promoted
|
|
179
187
|
@insertion
|
180
188
|
end
|
181
189
|
|
190
|
+
def client_request_id
|
191
|
+
request[:client_request_id]
|
192
|
+
end
|
193
|
+
|
182
194
|
private
|
183
195
|
|
196
|
+
def merge_client_info_defaults
|
197
|
+
return @client_info.merge({
|
198
|
+
:client_type => Promoted::Ruby::Client::CLIENT_TYPE['PLATFORM_SERVER'],
|
199
|
+
:traffic_type => Promoted::Ruby::Client::TRAFFIC_TYPE['PRODUCTION']
|
200
|
+
})
|
201
|
+
end
|
202
|
+
|
184
203
|
def add_missing_ids_on_insertions! request, insertions
|
185
204
|
insertions.each do |insertion|
|
186
205
|
insertion[:insertion_id] = @id_generator.newID if not insertion[:insertion_id]
|
data/lib/promoted/ruby/client.rb
CHANGED
@@ -19,7 +19,8 @@ module Promoted
|
|
19
19
|
class Error < StandardError; end
|
20
20
|
|
21
21
|
attr_reader :perform_checks, :default_only_log, :delivery_timeout_millis, :metrics_timeout_millis, :should_apply_treatment_func,
|
22
|
-
:default_request_headers, :http_client, :logger, :shadow_traffic_delivery_percent, :async_shadow_traffic
|
22
|
+
:default_request_headers, :http_client, :logger, :shadow_traffic_delivery_percent, :async_shadow_traffic,
|
23
|
+
:send_shadow_traffic_for_control
|
23
24
|
|
24
25
|
attr_accessor :request_logging_on, :enabled
|
25
26
|
|
@@ -39,7 +40,7 @@ module Promoted
|
|
39
40
|
|
40
41
|
##
|
41
42
|
# Create and configure a new Promoted client.
|
42
|
-
def initialize
|
43
|
+
def initialize(params={})
|
43
44
|
@perform_checks = true
|
44
45
|
if params[:perform_checks] != nil
|
45
46
|
@perform_checks = params[:perform_checks]
|
@@ -79,6 +80,11 @@ module Promoted
|
|
79
80
|
@async_shadow_traffic = params[:async_shadow_traffic] || false
|
80
81
|
end
|
81
82
|
|
83
|
+
@send_shadow_traffic_for_control = true
|
84
|
+
if params[:send_shadow_traffic_for_control] != nil
|
85
|
+
@send_shadow_traffic_for_control = params[:send_shadow_traffic_for_control] || false
|
86
|
+
end
|
87
|
+
|
82
88
|
@pool = nil
|
83
89
|
if @async_shadow_traffic
|
84
90
|
# Thread pool to process delivery of shadow traffic. Will silently drop excess requests beyond the queue
|
@@ -161,9 +167,8 @@ module Promoted
|
|
161
167
|
cohort_membership_to_log = delivery_request_builder.new_cohort_membership_to_log
|
162
168
|
|
163
169
|
if should_apply_treatment(cohort_membership_to_log)
|
164
|
-
|
165
|
-
|
166
|
-
# Call Delivery API
|
170
|
+
# Call Delivery API to get insertions to use
|
171
|
+
delivery_request_params = delivery_request_builder.delivery_request_params
|
167
172
|
begin
|
168
173
|
response = send_request(delivery_request_params, @delivery_endpoint, @delivery_timeout_millis, @delivery_api_key, headers)
|
169
174
|
rescue StandardError => err
|
@@ -172,11 +177,14 @@ module Promoted
|
|
172
177
|
deliver_err = true
|
173
178
|
@logger.error("Error calling delivery: " + err.message) if @logger
|
174
179
|
end
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
response ? response[:insertion] : [])
|
180
|
+
elsif @send_shadow_traffic_for_control
|
181
|
+
# Call Delivery API to send shadow traffic. This will create the request params with traffic type set.
|
182
|
+
deliver_shadow_traffic args, headers
|
179
183
|
end
|
184
|
+
|
185
|
+
insertions_from_delivery = (response != nil && !deliver_err);
|
186
|
+
response_insertions = delivery_request_builder.fill_details_from_response(
|
187
|
+
response && response[:insertion] || [])
|
180
188
|
end
|
181
189
|
|
182
190
|
request_to_log = nil
|
@@ -210,7 +218,9 @@ module Promoted
|
|
210
218
|
|
211
219
|
client_response = {
|
212
220
|
insertion: response_insertions,
|
213
|
-
log_request: log_req
|
221
|
+
log_request: log_req,
|
222
|
+
execution_server: insertions_from_delivery ? Promoted::Ruby::Client::EXECUTION_SERVER['API'] : Promoted::Ruby::Client::EXECUTION_SERVER['SDK'],
|
223
|
+
client_request_id: delivery_request_builder.client_request_id
|
214
224
|
}
|
215
225
|
return client_response
|
216
226
|
end
|
@@ -316,7 +326,7 @@ module Promoted
|
|
316
326
|
|
317
327
|
ellapsed_time = Time.now - start_time
|
318
328
|
@logger.debug("Sync send_request completed in #{ellapsed_time.to_f * 1000} ms") if @logger
|
319
|
-
|
329
|
+
end
|
320
330
|
|
321
331
|
return resp
|
322
332
|
end
|
@@ -335,6 +345,14 @@ module Promoted
|
|
335
345
|
delivery_request_params = delivery_request_builder.delivery_request_params
|
336
346
|
delivery_request_params[:client_info][:traffic_type] = Promoted::Ruby::Client::TRAFFIC_TYPE['SHADOW']
|
337
347
|
|
348
|
+
begin
|
349
|
+
@pager.validate_paging(delivery_request_builder.full_insertion, delivery_request_builder.request[:paging])
|
350
|
+
rescue InvalidPagingError => err
|
351
|
+
# Invalid input, log and skip.
|
352
|
+
@logger.warn("Shadow traffic call failed with invalid paging #{err}") if @logger
|
353
|
+
return
|
354
|
+
end
|
355
|
+
|
338
356
|
# Call Delivery API and log/ignore errors.
|
339
357
|
start_time = Time.now
|
340
358
|
response = nil
|
@@ -347,7 +365,7 @@ module Promoted
|
|
347
365
|
|
348
366
|
if !@async_shadow_traffic
|
349
367
|
ellapsed_time = Time.now - start_time
|
350
|
-
insertions = response
|
368
|
+
insertions = response && response[:insertion] || []
|
351
369
|
@logger.info("Shadow traffic call completed in #{ellapsed_time.to_f * 1000} ms with #{insertions.length} insertions") if @logger
|
352
370
|
end
|
353
371
|
end
|
@@ -14,6 +14,7 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.homepage = 'https://github.com/promotedai/promoted-ruby-client'
|
15
15
|
spec.license = 'MIT'
|
16
16
|
|
17
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org/"
|
17
18
|
spec.metadata["homepage_uri"] = spec.homepage
|
18
19
|
spec.metadata["source_code_uri"] = "https://github.com/promotedai/promoted-ruby-client"
|
19
20
|
spec.metadata["changelog_uri"] = "https://github.com/promotedai/promoted-ruby-client/blob/master/CHANGELOG.md"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: promoted-ruby-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- scottmcmaster
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -123,6 +123,7 @@ extensions: []
|
|
123
123
|
extra_rdoc_files:
|
124
124
|
- README.md
|
125
125
|
files:
|
126
|
+
- ".github/workflows/push-pull-requests_check.yml"
|
126
127
|
- ".gitignore"
|
127
128
|
- Gemfile
|
128
129
|
- Gemfile.lock
|
@@ -149,6 +150,7 @@ homepage: https://github.com/promotedai/promoted-ruby-client
|
|
149
150
|
licenses:
|
150
151
|
- MIT
|
151
152
|
metadata:
|
153
|
+
allowed_push_host: https://rubygems.org/
|
152
154
|
homepage_uri: https://github.com/promotedai/promoted-ruby-client
|
153
155
|
source_code_uri: https://github.com/promotedai/promoted-ruby-client
|
154
156
|
changelog_uri: https://github.com/promotedai/promoted-ruby-client/blob/master/CHANGELOG.md
|