sift 4.5.0 → 4.6.0
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/ci.yml +49 -0
- data/HISTORY +9 -0
- data/README.md +1 -1
- data/lib/sift/client/decision/apply_to.rb +7 -3
- data/lib/sift/client/decision.rb +7 -6
- data/lib/sift/client.rb +56 -39
- data/lib/sift/router.rb +7 -4
- data/lib/sift/version.rb +2 -1
- data/lib/sift.rb +3 -3
- data/sift.gemspec +7 -5
- data/spec/unit/client/decision/apply_to_spec.rb +1 -1
- data/spec/unit/client/decision_spec.rb +1 -1
- data/spec/unit/client_validationapi_spec.rb +46 -0
- data/spec/unit/configuration_spec.rb +67 -0
- data/test_integration_app/verification_api/test_verification_api.rb +3 -3
- metadata +14 -14
- data/.circleci/config.yml +0 -105
- data/.jenkins/Jenkinsfile +0 -103
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f52238626726ed4acc2b903b57bc393b46b2e8df162a021abd0b94d084631acc
|
|
4
|
+
data.tar.gz: 4576e4a7bb68d34b9687a8cea83d7e767cb9d10aacbf354d6dcf6167cd0de89b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3b7c07547207731c7592c0a08f229adde8400511855ad54ed7ae86de0b891acbb7b4fa91b7666df2e4927a7f9483898554daa8658f28ed9d5e0a49875139a011
|
|
7
|
+
data.tar.gz: 3d3fd96f0ed512504cdd4f52f353ef9264ee74395b1c1af58c6d583c17114e3cdd971ec577397d28339ceea68e0d69c495e817bdb42dc16aac61a7b6e348f7a5
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Ruby-ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
- master
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
ACCOUNT_ID: ${{ secrets.ACCOUNT_ID }}
|
|
13
|
+
API_KEY: ${{ secrets.API_KEY }}
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
build:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
strategy:
|
|
22
|
+
matrix:
|
|
23
|
+
ruby-version: ['2.7', '3.1', '3.2', '3.3']
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
- name: Set up Ruby
|
|
27
|
+
uses: ruby/setup-ruby@v1
|
|
28
|
+
with:
|
|
29
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
30
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
|
31
|
+
- name: Run tests
|
|
32
|
+
run: bundle exec rspec --format RspecJunitFormatter --out test_results/rspec.xml --format progress
|
|
33
|
+
|
|
34
|
+
run_integration_tests:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
if: ${{ github.ref == 'refs/heads/master' }}
|
|
37
|
+
strategy:
|
|
38
|
+
matrix:
|
|
39
|
+
ruby-version: ['2.7', '3.1', '3.2', '3.3']
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@v4
|
|
42
|
+
- name: Set up Ruby
|
|
43
|
+
uses: ruby/setup-ruby@v1
|
|
44
|
+
with:
|
|
45
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
46
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
|
47
|
+
- name: Run tests
|
|
48
|
+
run: |
|
|
49
|
+
bundle exec ruby test_integration_app/main.rb
|
data/HISTORY
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
=== 4.6.0 2026-02-10
|
|
2
|
+
- Bump the minimum version of httparty to 0.23.3 to ensure protection against CVE-2025-68696
|
|
3
|
+
- Refactor Client to use dedicated internal HTTP clients for different API endpoints
|
|
4
|
+
- Fix Verification API methods to use correct version parameter
|
|
5
|
+
- Increase minimum required version for Ruby to 2.7.0
|
|
6
|
+
|
|
7
|
+
=== 4.5.1 2025-04-07
|
|
8
|
+
- Fix Verification URLs
|
|
9
|
+
|
|
1
10
|
=== 4.5.0 2024-05-16
|
|
2
11
|
- Support for warnings in Events API
|
|
3
12
|
|
data/README.md
CHANGED
|
@@ -21,7 +21,7 @@ module Sift
|
|
|
21
21
|
time
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
attr_reader :decision_id, :configs, :getter, :api_key
|
|
24
|
+
attr_reader :decision_id, :configs, :getter, :api_key, :client_class
|
|
25
25
|
|
|
26
26
|
PROPERTIES.each do |attribute|
|
|
27
27
|
class_eval %{
|
|
@@ -31,11 +31,12 @@ module Sift
|
|
|
31
31
|
}
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
def initialize(api_key, decision_id, configs)
|
|
34
|
+
def initialize(api_key, decision_id, configs, client_class = Sift::Client)
|
|
35
35
|
@api_key = api_key
|
|
36
36
|
@decision_id = decision_id
|
|
37
37
|
@configs = configs
|
|
38
38
|
@getter = Utils::HashGetter.new(configs)
|
|
39
|
+
@client_class = client_class
|
|
39
40
|
end
|
|
40
41
|
|
|
41
42
|
def run
|
|
@@ -58,7 +59,8 @@ module Sift
|
|
|
58
59
|
def send_request
|
|
59
60
|
Router.post(path, {
|
|
60
61
|
body: request_body,
|
|
61
|
-
headers: headers
|
|
62
|
+
headers: headers,
|
|
63
|
+
client_class: client_class
|
|
62
64
|
})
|
|
63
65
|
end
|
|
64
66
|
|
|
@@ -79,6 +81,8 @@ module Sift
|
|
|
79
81
|
validator.valid_order?
|
|
80
82
|
elsif applying_to_session?
|
|
81
83
|
validator.valid_session?
|
|
84
|
+
elsif applying_to_content?
|
|
85
|
+
validator.valid_content?
|
|
82
86
|
else
|
|
83
87
|
validator.valid_user?
|
|
84
88
|
end
|
data/lib/sift/client/decision.rb
CHANGED
|
@@ -10,11 +10,12 @@ module Sift
|
|
|
10
10
|
class Decision
|
|
11
11
|
FILTER_PARAMS = %w{ limit entity_type abuse_types from }
|
|
12
12
|
|
|
13
|
-
attr_reader :account_id, :api_key
|
|
13
|
+
attr_reader :account_id, :api_key, :client_class
|
|
14
14
|
|
|
15
|
-
def initialize(api_key, account_id)
|
|
15
|
+
def initialize(api_key, account_id, client_class = Sift::Client)
|
|
16
16
|
@account_id = account_id
|
|
17
17
|
@api_key = api_key
|
|
18
|
+
@client_class = client_class
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
def list(options = {})
|
|
@@ -25,7 +26,8 @@ module Sift
|
|
|
25
26
|
else
|
|
26
27
|
Router.get(index_path, {
|
|
27
28
|
query: build_query(getter),
|
|
28
|
-
headers: auth_header
|
|
29
|
+
headers: auth_header,
|
|
30
|
+
client_class: client_class
|
|
29
31
|
})
|
|
30
32
|
end
|
|
31
33
|
end
|
|
@@ -44,7 +46,7 @@ module Sift
|
|
|
44
46
|
getter = Utils::HashGetter.new(configs)
|
|
45
47
|
configs[:account_id] = account_id
|
|
46
48
|
|
|
47
|
-
ApplyTo.new(api_key, getter.get(:decision_id), configs).run
|
|
49
|
+
ApplyTo.new(api_key, getter.get(:decision_id), configs, client_class).run
|
|
48
50
|
end
|
|
49
51
|
|
|
50
52
|
def index_path
|
|
@@ -54,7 +56,7 @@ module Sift
|
|
|
54
56
|
private
|
|
55
57
|
|
|
56
58
|
def request_next_page(path)
|
|
57
|
-
Router.get(path, headers: auth_header)
|
|
59
|
+
Router.get(path, headers: auth_header, client_class: client_class)
|
|
58
60
|
end
|
|
59
61
|
|
|
60
62
|
def auth_header
|
|
@@ -63,4 +65,3 @@ module Sift
|
|
|
63
65
|
end
|
|
64
66
|
end
|
|
65
67
|
end
|
|
66
|
-
|
data/lib/sift/client.rb
CHANGED
|
@@ -2,9 +2,6 @@ require "httparty"
|
|
|
2
2
|
require "multi_json"
|
|
3
3
|
require "base64"
|
|
4
4
|
|
|
5
|
-
require_relative "./client/decision"
|
|
6
|
-
require_relative "./error"
|
|
7
|
-
|
|
8
5
|
module Sift
|
|
9
6
|
|
|
10
7
|
# Represents the payload returned from a call through the track API
|
|
@@ -94,17 +91,36 @@ module Sift
|
|
|
94
91
|
API_ENDPOINT = ENV["SIFT_RUBY_API_URL"] || 'https://api.siftscience.com'
|
|
95
92
|
API3_ENDPOINT = ENV["SIFT_RUBY_API3_URL"] || 'https://api3.siftscience.com'
|
|
96
93
|
|
|
94
|
+
# Maintain backward compatibility for users who may rely on HTTParty methods
|
|
97
95
|
include HTTParty
|
|
98
96
|
base_uri API_ENDPOINT
|
|
99
97
|
|
|
100
98
|
attr_reader :api_key, :account_id
|
|
101
99
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
100
|
+
class << self
|
|
101
|
+
def build_auth_header(api_key)
|
|
102
|
+
{ "Authorization" => "Basic #{Base64.strict_encode64(api_key + ":")}" }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def user_agent
|
|
106
|
+
"sift-ruby/#{VERSION}"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Factory methods for internal API executors that inherit from the current class context.
|
|
110
|
+
# This ensures that subclasses of Client propagate their HTTParty configuration
|
|
111
|
+
# to these internal clients.
|
|
105
112
|
|
|
106
|
-
|
|
107
|
-
|
|
113
|
+
def api_client
|
|
114
|
+
@api_client ||= Class.new(self) do
|
|
115
|
+
base_uri API_ENDPOINT
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def api3_client
|
|
120
|
+
@api3_client ||= Class.new(self) do
|
|
121
|
+
base_uri API3_ENDPOINT
|
|
122
|
+
end
|
|
123
|
+
end
|
|
108
124
|
end
|
|
109
125
|
|
|
110
126
|
# Constructor
|
|
@@ -139,6 +155,7 @@ module Sift
|
|
|
139
155
|
@api_key = opts[:api_key] || Sift.api_key
|
|
140
156
|
@account_id = opts[:account_id] || Sift.account_id
|
|
141
157
|
@version = opts[:version] || API_VERSION
|
|
158
|
+
@verification_version = opts[:verification_version] || VERIFICATION_API_VERSION
|
|
142
159
|
@timeout = opts[:timeout] || 2 # 2-second timeout by default
|
|
143
160
|
@path = opts[:path] || Sift.rest_api_path(@version)
|
|
144
161
|
|
|
@@ -201,7 +218,7 @@ module Sift
|
|
|
201
218
|
#
|
|
202
219
|
# :path::
|
|
203
220
|
# Overrides the URI path for this API call.
|
|
204
|
-
#
|
|
221
|
+
#
|
|
205
222
|
# :include_score_percentiles::
|
|
206
223
|
# include_score_percentiles(optional) : Whether to add new parameter in the query parameter.
|
|
207
224
|
#
|
|
@@ -255,7 +272,7 @@ module Sift
|
|
|
255
272
|
}
|
|
256
273
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
257
274
|
|
|
258
|
-
response = self.class.post(path, options)
|
|
275
|
+
response = self.class.api_client.post(path, options)
|
|
259
276
|
Response.new(response.body, response.code, response.response)
|
|
260
277
|
end
|
|
261
278
|
|
|
@@ -286,7 +303,7 @@ module Sift
|
|
|
286
303
|
#
|
|
287
304
|
# :version::
|
|
288
305
|
# Overrides the version of the Events API to call.
|
|
289
|
-
#
|
|
306
|
+
#
|
|
290
307
|
# :include_score_percentiles::
|
|
291
308
|
# include_score_percentiles(optional) : Whether to add new parameter in the query parameter.
|
|
292
309
|
#
|
|
@@ -318,7 +335,7 @@ module Sift
|
|
|
318
335
|
}
|
|
319
336
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
320
337
|
|
|
321
|
-
response = self.class.get(Sift.score_api_path(user_id, version), options)
|
|
338
|
+
response = self.class.api_client.get(Sift.score_api_path(user_id, version), options)
|
|
322
339
|
Response.new(response.body, response.code, response.response)
|
|
323
340
|
end
|
|
324
341
|
|
|
@@ -350,7 +367,7 @@ module Sift
|
|
|
350
367
|
#
|
|
351
368
|
# :timeout::
|
|
352
369
|
# Overrides the timeout (in seconds) for this call.
|
|
353
|
-
#
|
|
370
|
+
#
|
|
354
371
|
# :include_score_percentiles::
|
|
355
372
|
# include_score_percentiles(optional) : Whether to add new parameter in the query parameter.
|
|
356
373
|
#
|
|
@@ -363,6 +380,7 @@ module Sift
|
|
|
363
380
|
abuse_types = opts[:abuse_types]
|
|
364
381
|
api_key = opts[:api_key] || @api_key
|
|
365
382
|
timeout = opts[:timeout] || @timeout
|
|
383
|
+
version = opts[:version] || @version
|
|
366
384
|
include_score_percentiles = opts[:include_score_percentiles]
|
|
367
385
|
|
|
368
386
|
raise("user_id must be a non-empty string") if (!user_id.is_a? String) || user_id.to_s.empty?
|
|
@@ -381,7 +399,7 @@ module Sift
|
|
|
381
399
|
}
|
|
382
400
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
383
401
|
|
|
384
|
-
response = self.class.get(Sift.user_score_api_path(user_id,
|
|
402
|
+
response = self.class.api_client.get(Sift.user_score_api_path(user_id, version), options)
|
|
385
403
|
Response.new(response.body, response.code, response.response)
|
|
386
404
|
end
|
|
387
405
|
|
|
@@ -419,6 +437,7 @@ module Sift
|
|
|
419
437
|
abuse_types = opts[:abuse_types]
|
|
420
438
|
api_key = opts[:api_key] || @api_key
|
|
421
439
|
timeout = opts[:timeout] || @timeout
|
|
440
|
+
version = opts[:version] || @version
|
|
422
441
|
|
|
423
442
|
raise("user_id must be a non-empty string") if (!user_id.is_a? String) || user_id.to_s.empty?
|
|
424
443
|
raise("Bad api_key parameter") if api_key.empty?
|
|
@@ -433,7 +452,7 @@ module Sift
|
|
|
433
452
|
}
|
|
434
453
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
435
454
|
|
|
436
|
-
response = self.class.post(Sift.user_score_api_path(user_id,
|
|
455
|
+
response = self.class.api_client.post(Sift.user_score_api_path(user_id, version), options)
|
|
437
456
|
Response.new(response.body, response.code, response.response)
|
|
438
457
|
end
|
|
439
458
|
|
|
@@ -531,7 +550,7 @@ module Sift
|
|
|
531
550
|
}
|
|
532
551
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
533
552
|
|
|
534
|
-
response = self.class.delete(Sift.users_label_api_path(user_id, version), options)
|
|
553
|
+
response = self.class.api_client.delete(Sift.users_label_api_path(user_id, version), options)
|
|
535
554
|
Response.new(response.body, response.code, response.response)
|
|
536
555
|
end
|
|
537
556
|
|
|
@@ -568,8 +587,7 @@ module Sift
|
|
|
568
587
|
}
|
|
569
588
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
570
589
|
|
|
571
|
-
|
|
572
|
-
response = self.class.get(uri, options)
|
|
590
|
+
response = self.class.api3_client.get(Sift.workflow_status_path(account_id, run_id), options)
|
|
573
591
|
Response.new(response.body, response.code, response.response)
|
|
574
592
|
end
|
|
575
593
|
|
|
@@ -606,8 +624,7 @@ module Sift
|
|
|
606
624
|
}
|
|
607
625
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
608
626
|
|
|
609
|
-
|
|
610
|
-
response = self.class.get(uri, options)
|
|
627
|
+
response = self.class.api3_client.get(Sift.user_decisions_api_path(account_id, user_id), options)
|
|
611
628
|
Response.new(response.body, response.code, response.response)
|
|
612
629
|
end
|
|
613
630
|
|
|
@@ -644,8 +661,7 @@ module Sift
|
|
|
644
661
|
}
|
|
645
662
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
646
663
|
|
|
647
|
-
|
|
648
|
-
response = self.class.get(uri, options)
|
|
664
|
+
response = self.class.api3_client.get(Sift.order_decisions_api_path(account_id, order_id), options)
|
|
649
665
|
Response.new(response.body, response.code, response.response)
|
|
650
666
|
end
|
|
651
667
|
|
|
@@ -684,8 +700,7 @@ module Sift
|
|
|
684
700
|
}
|
|
685
701
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
686
702
|
|
|
687
|
-
|
|
688
|
-
response = self.class.get(uri, options)
|
|
703
|
+
response = self.class.api3_client.get(Sift.session_decisions_api_path(account_id, user_id, session_id), options)
|
|
689
704
|
Response.new(response.body, response.code, response.response)
|
|
690
705
|
end
|
|
691
706
|
|
|
@@ -724,8 +739,7 @@ module Sift
|
|
|
724
739
|
}
|
|
725
740
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
726
741
|
|
|
727
|
-
|
|
728
|
-
response = self.class.get(uri, options)
|
|
742
|
+
response = self.class.api3_client.get(Sift.content_decisions_api_path(account_id, user_id, content_id), options)
|
|
729
743
|
Response.new(response.body, response.code, response.response)
|
|
730
744
|
end
|
|
731
745
|
|
|
@@ -747,7 +761,7 @@ module Sift
|
|
|
747
761
|
|
|
748
762
|
def build_default_headers_post(api_key)
|
|
749
763
|
{
|
|
750
|
-
"Authorization" => "Basic #{Base64.
|
|
764
|
+
"Authorization" => "Basic #{Base64.strict_encode64(api_key+":")}",
|
|
751
765
|
"User-Agent" => "SiftScience/v#{@version} sift-ruby/#{VERSION}",
|
|
752
766
|
"Content-Type" => "application/json"
|
|
753
767
|
}
|
|
@@ -755,7 +769,7 @@ module Sift
|
|
|
755
769
|
|
|
756
770
|
def verification_send(properties = {}, opts = {})
|
|
757
771
|
api_key = opts[:api_key] || @api_key
|
|
758
|
-
version = opts[:
|
|
772
|
+
version = opts[:verification_version] || @verification_version
|
|
759
773
|
timeout = opts[:timeout] || @timeout
|
|
760
774
|
|
|
761
775
|
raise("properties cannot be empty") if properties.empty?
|
|
@@ -767,14 +781,13 @@ module Sift
|
|
|
767
781
|
:headers => build_default_headers_post(api_key)
|
|
768
782
|
}
|
|
769
783
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
770
|
-
|
|
771
|
-
response = self.class.post(Sift.verification_api_send_path(@version), options)
|
|
784
|
+
response = self.class.api_client.post(Sift.verification_api_send_path(version), options)
|
|
772
785
|
Response.new(response.body, response.code, response.response)
|
|
773
786
|
end
|
|
774
787
|
|
|
775
788
|
def verification_resend(properties = {}, opts = {})
|
|
776
789
|
api_key = opts[:api_key] || @api_key
|
|
777
|
-
version = opts[:
|
|
790
|
+
version = opts[:verification_version] || @verification_version
|
|
778
791
|
timeout = opts[:timeout] || @timeout
|
|
779
792
|
|
|
780
793
|
raise("properties cannot be empty") if properties.empty?
|
|
@@ -787,13 +800,13 @@ module Sift
|
|
|
787
800
|
}
|
|
788
801
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
789
802
|
|
|
790
|
-
response = self.class.post(Sift.verification_api_resend_path(
|
|
803
|
+
response = self.class.api_client.post(Sift.verification_api_resend_path(version), options)
|
|
791
804
|
Response.new(response.body, response.code, response.response)
|
|
792
805
|
end
|
|
793
806
|
|
|
794
807
|
def verification_check(properties = {}, opts = {})
|
|
795
808
|
api_key = opts[:api_key] || @api_key
|
|
796
|
-
version = opts[:
|
|
809
|
+
version = opts[:verification_version] || @verification_version
|
|
797
810
|
timeout = opts[:timeout] || @timeout
|
|
798
811
|
|
|
799
812
|
raise("properties cannot be empty") if properties.empty?
|
|
@@ -806,7 +819,7 @@ module Sift
|
|
|
806
819
|
}
|
|
807
820
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
808
821
|
|
|
809
|
-
response = self.class.post(Sift.verification_api_check_path(
|
|
822
|
+
response = self.class.api_client.post(Sift.verification_api_check_path(version), options)
|
|
810
823
|
Response.new(response.body, response.code, response.response)
|
|
811
824
|
end
|
|
812
825
|
|
|
@@ -831,7 +844,7 @@ module Sift
|
|
|
831
844
|
:basic_auth => { :username => api_key, :password => "" }
|
|
832
845
|
}
|
|
833
846
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
834
|
-
response = self.class.post(
|
|
847
|
+
response = self.class.api_client.post(Sift.psp_merchant_api_path(account_id), options)
|
|
835
848
|
Response.new(response.body, response.code, response.response)
|
|
836
849
|
end
|
|
837
850
|
|
|
@@ -858,7 +871,7 @@ module Sift
|
|
|
858
871
|
:basic_auth => { :username => api_key, :password => "" }
|
|
859
872
|
}
|
|
860
873
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
861
|
-
response = self.class.put(
|
|
874
|
+
response = self.class.api_client.put(Sift.psp_merchant_id_api_path(account_id, merchant_id), options)
|
|
862
875
|
Response.new(response.body, response.code, response.response)
|
|
863
876
|
end
|
|
864
877
|
|
|
@@ -882,7 +895,7 @@ module Sift
|
|
|
882
895
|
:basic_auth => { :username => api_key, :password => "" }
|
|
883
896
|
}
|
|
884
897
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
885
|
-
response = self.class.get(
|
|
898
|
+
response = self.class.api_client.get(Sift.psp_merchant_id_api_path(account_id, merchant_id), options)
|
|
886
899
|
Response.new(response.body, response.code, response.response)
|
|
887
900
|
end
|
|
888
901
|
|
|
@@ -911,7 +924,7 @@ module Sift
|
|
|
911
924
|
:query => query
|
|
912
925
|
}
|
|
913
926
|
options.merge!(:timeout => timeout) unless timeout.nil?
|
|
914
|
-
response = self.class.get(
|
|
927
|
+
response = self.class.api_client.get(Sift.psp_merchant_api_path(account_id), options)
|
|
915
928
|
Response.new(response.body, response.code, response.response)
|
|
916
929
|
end
|
|
917
930
|
|
|
@@ -926,7 +939,7 @@ module Sift
|
|
|
926
939
|
end
|
|
927
940
|
|
|
928
941
|
def decision_instance
|
|
929
|
-
@decision_instance ||= Decision.new(api_key, account_id)
|
|
942
|
+
@decision_instance ||= Decision.new(api_key, account_id, self.class)
|
|
930
943
|
end
|
|
931
944
|
|
|
932
945
|
def delete_nils(properties)
|
|
@@ -943,4 +956,8 @@ module Sift
|
|
|
943
956
|
end
|
|
944
957
|
end
|
|
945
958
|
end
|
|
959
|
+
|
|
960
|
+
require_relative "./client/decision"
|
|
961
|
+
require_relative "./error"
|
|
962
|
+
|
|
946
963
|
end
|
data/lib/sift/router.rb
CHANGED
|
@@ -2,20 +2,23 @@ require_relative "./version"
|
|
|
2
2
|
require_relative "./client"
|
|
3
3
|
|
|
4
4
|
module Sift
|
|
5
|
-
class Router
|
|
6
|
-
include HTTParty
|
|
5
|
+
class Router < Client
|
|
7
6
|
|
|
8
7
|
class << self
|
|
9
8
|
def get(path, options = {})
|
|
9
|
+
client_class = options.delete(:client_class) || Sift::Client
|
|
10
|
+
options[:base_uri] = nil
|
|
10
11
|
serialize_body(options)
|
|
11
12
|
add_default_headers(options)
|
|
12
|
-
wrap_response(
|
|
13
|
+
wrap_response(client_class.api3_client.get(path, options))
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
def post(path, options = {})
|
|
17
|
+
client_class = options.delete(:client_class) || Sift::Client
|
|
18
|
+
options[:base_uri] = nil
|
|
16
19
|
serialize_body(options)
|
|
17
20
|
add_default_headers(options)
|
|
18
|
-
wrap_response(
|
|
21
|
+
wrap_response(client_class.api3_client.post(path, options))
|
|
19
22
|
end
|
|
20
23
|
|
|
21
24
|
def serialize_body(options)
|
data/lib/sift/version.rb
CHANGED
data/lib/sift.rb
CHANGED
|
@@ -10,17 +10,17 @@ module Sift
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
# Returns the path for the specified API version
|
|
13
|
-
def self.verification_api_send_path(version=
|
|
13
|
+
def self.verification_api_send_path(version=VERIFICATION_API_VERSION)
|
|
14
14
|
"/v#{version}/verification/send"
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
# Returns the path for the specified API version
|
|
18
|
-
def self.verification_api_resend_path(version=
|
|
18
|
+
def self.verification_api_resend_path(version=VERIFICATION_API_VERSION)
|
|
19
19
|
"/v#{version}/verification/resend"
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
# Returns the path for the specified API version
|
|
23
|
-
def self.verification_api_check_path(version=
|
|
23
|
+
def self.verification_api_check_path(version=VERIFICATION_API_VERSION)
|
|
24
24
|
"/v#{version}/verification/check"
|
|
25
25
|
end
|
|
26
26
|
|
data/sift.gemspec
CHANGED
|
@@ -7,10 +7,10 @@ Gem::Specification.new do |s|
|
|
|
7
7
|
s.version = Sift::VERSION
|
|
8
8
|
s.platform = Gem::Platform::RUBY
|
|
9
9
|
s.authors = ["Fred Sadaghiani", "Yoav Schatzberg", "Jacob Burnim"]
|
|
10
|
-
s.email = ["support@
|
|
11
|
-
s.homepage = "http://
|
|
12
|
-
s.summary = %q{Sift
|
|
13
|
-
s.description = %q{Sift
|
|
10
|
+
s.email = ["support@sift.com"]
|
|
11
|
+
s.homepage = "http://sift.com"
|
|
12
|
+
s.summary = %q{Sift Ruby API Gem}
|
|
13
|
+
s.description = %q{Sift Ruby API. Please see http://sift.com for more details.}
|
|
14
14
|
|
|
15
15
|
s.rubyforge_project = "sift"
|
|
16
16
|
|
|
@@ -19,6 +19,8 @@ Gem::Specification.new do |s|
|
|
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
20
20
|
s.require_paths = ["lib"]
|
|
21
21
|
|
|
22
|
+
s.required_ruby_version = '>= 2.7.0'
|
|
23
|
+
|
|
22
24
|
# Gems that must be intalled for sift to compile and build
|
|
23
25
|
s.add_development_dependency "rspec", "~> 3.5"
|
|
24
26
|
s.add_development_dependency "rspec_junit_formatter"
|
|
@@ -26,7 +28,7 @@ Gem::Specification.new do |s|
|
|
|
26
28
|
s.add_development_dependency "webmock", ">= 1.16.0", "< 2"
|
|
27
29
|
|
|
28
30
|
# Gems that must be intalled for sift to work
|
|
29
|
-
s.add_dependency "httparty", ">= 0.
|
|
31
|
+
s.add_dependency "httparty", ">= 0.23.3"
|
|
30
32
|
s.add_dependency "multi_json", ">= 1.0"
|
|
31
33
|
|
|
32
34
|
s.add_development_dependency("rake")
|
|
@@ -88,4 +88,50 @@ describe Sift::Client do
|
|
|
88
88
|
|
|
89
89
|
end
|
|
90
90
|
|
|
91
|
+
# Regression tests for verification API version bug fix
|
|
92
|
+
# These tests ensure verification methods use verification_version (1.1)
|
|
93
|
+
# instead of the events API version (205)
|
|
94
|
+
|
|
95
|
+
it "Uses verification API version (1.1) not events API version (205) for verification_send" do
|
|
96
|
+
api_key = "test_key"
|
|
97
|
+
response_json = { :status => 0, :error_message => "OK"}
|
|
98
|
+
|
|
99
|
+
# Should call v1.1, NOT v205
|
|
100
|
+
stub_request(:post, "https://test_key:@api.siftscience.com/v1.1/verification/send")
|
|
101
|
+
.to_return(:status => 200, :body => MultiJson.dump(response_json))
|
|
102
|
+
|
|
103
|
+
# Client defaults: version=205 (events), verification_version=1.1
|
|
104
|
+
response = Sift::Client.new(:api_key => api_key).verification_send(valid_send_properties)
|
|
105
|
+
|
|
106
|
+
expect(response.ok?).to eq(true)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "Uses verification API version (1.1) not events API version (205) for verification_resend" do
|
|
110
|
+
api_key = "test_key"
|
|
111
|
+
response_json = { :status => 0, :error_message => "OK"}
|
|
112
|
+
|
|
113
|
+
# Should call v1.1, NOT v205
|
|
114
|
+
stub_request(:post, "https://test_key:@api.siftscience.com/v1.1/verification/resend")
|
|
115
|
+
.to_return(:status => 200, :body => MultiJson.dump(response_json))
|
|
116
|
+
|
|
117
|
+
# Client defaults: version=205 (events), verification_version=1.1
|
|
118
|
+
response = Sift::Client.new(:api_key => api_key).verification_resend(valid_resend_properties)
|
|
119
|
+
|
|
120
|
+
expect(response.ok?).to eq(true)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "Uses verification API version (1.1) not events API version (205) for verification_check" do
|
|
124
|
+
api_key = "test_key"
|
|
125
|
+
response_json = { :status => 0, :error_message => "OK"}
|
|
126
|
+
|
|
127
|
+
# Should call v1.1, NOT v205
|
|
128
|
+
stub_request(:post, "https://test_key:@api.siftscience.com/v1.1/verification/check")
|
|
129
|
+
.to_return(:status => 200, :body => MultiJson.dump(response_json))
|
|
130
|
+
|
|
131
|
+
# Client defaults: version=205 (events), verification_version=1.1
|
|
132
|
+
response = Sift::Client.new(:api_key => api_key).verification_check(valid_check_properties)
|
|
133
|
+
|
|
134
|
+
expect(response.ok?).to eq(true)
|
|
135
|
+
end
|
|
136
|
+
|
|
91
137
|
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require_relative "../spec_helper"
|
|
2
|
+
require "sift"
|
|
3
|
+
require "logger"
|
|
4
|
+
|
|
5
|
+
describe "Sift::Client Configuration Patterns" do
|
|
6
|
+
let(:api_key) { "test_api_key" }
|
|
7
|
+
|
|
8
|
+
it "propagates global Sift::Client configuration to internal clients" do
|
|
9
|
+
Sift::Client.default_timeout 5
|
|
10
|
+
|
|
11
|
+
# Internal executors should inherit this
|
|
12
|
+
expect(Sift::Client.api_client.default_options[:timeout]).to eq(5)
|
|
13
|
+
expect(Sift::Client.api3_client.default_options[:timeout]).to eq(5)
|
|
14
|
+
|
|
15
|
+
# Reset
|
|
16
|
+
Sift::Client.default_timeout 2
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "allows independent subclass configurations" do
|
|
20
|
+
class SubclassA < Sift::Client; end
|
|
21
|
+
class SubclassB < Sift::Client; end
|
|
22
|
+
|
|
23
|
+
SubclassA.default_timeout 10
|
|
24
|
+
SubclassB.default_timeout 20
|
|
25
|
+
|
|
26
|
+
expect(SubclassA.api_client.default_options[:timeout]).to eq(10)
|
|
27
|
+
expect(SubclassB.api_client.default_options[:timeout]).to eq(20)
|
|
28
|
+
|
|
29
|
+
# Ensure they didn't leak to parent
|
|
30
|
+
expect(Sift::Client.api_client.default_options[:timeout]).to be <= 5
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "propagates complex settings like loggers to subclasses" do
|
|
34
|
+
class LoggingClient < Sift::Client; end
|
|
35
|
+
|
|
36
|
+
logger = Logger.new(nil)
|
|
37
|
+
LoggingClient.logger logger, :debug, :curl
|
|
38
|
+
|
|
39
|
+
expect(LoggingClient.api_client.default_options[:logger]).to eq(logger)
|
|
40
|
+
expect(LoggingClient.api_client.default_options[:log_level]).to eq(:debug)
|
|
41
|
+
expect(LoggingClient.api_client.default_options[:log_format]).to eq(:curl)
|
|
42
|
+
|
|
43
|
+
# Ensure Sift::Client remains untouched
|
|
44
|
+
expect(Sift::Client.api_client.default_options[:logger]).to be_nil
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "respects inheritance chain for Decisions and Router" do
|
|
48
|
+
class DecisionClient < Sift::Client; end
|
|
49
|
+
DecisionClient.default_timeout 15
|
|
50
|
+
|
|
51
|
+
client = DecisionClient.new(api_key: api_key, account_id: "acc")
|
|
52
|
+
|
|
53
|
+
# Verify the executor used by the Router is the one from DecisionClient
|
|
54
|
+
expect(DecisionClient.api3_client.default_options[:timeout]).to eq(15)
|
|
55
|
+
|
|
56
|
+
# We want to ensure that when Router.get is called, it uses DecisionClient.api3_client
|
|
57
|
+
# In lib/sift/router.rb, we have:
|
|
58
|
+
# wrap_response(client_class.api3_client.get(path, options))
|
|
59
|
+
|
|
60
|
+
expect(DecisionClient.api3_client).to receive(:get).and_call_original
|
|
61
|
+
|
|
62
|
+
# Mock the request to avoid network calls
|
|
63
|
+
stub_request(:get, /api3.siftscience.com/)
|
|
64
|
+
|
|
65
|
+
client.get_user_decisions("user_1")
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -2,13 +2,13 @@ require "sift"
|
|
|
2
2
|
|
|
3
3
|
class VerificationAPI
|
|
4
4
|
|
|
5
|
-
@@client = Sift::Client.new(:api_key => ENV["API_KEY"], :version=>1.1)
|
|
5
|
+
@@client = Sift::Client.new(:api_key => ENV["API_KEY"], :version => 1.1)
|
|
6
6
|
|
|
7
7
|
def send()
|
|
8
8
|
properties = {
|
|
9
9
|
"$user_id" => $user_id,
|
|
10
10
|
"$send_to" => $user_email,
|
|
11
|
-
"$verification_type"
|
|
11
|
+
"$verification_type" => "$email",
|
|
12
12
|
"$brand_name" => "MyTopBrand",
|
|
13
13
|
"$language" => "en",
|
|
14
14
|
"$site_country" => "IN",
|
|
@@ -28,5 +28,5 @@ class VerificationAPI
|
|
|
28
28
|
|
|
29
29
|
return @@client.verification_send(properties)
|
|
30
30
|
end
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
end
|
metadata
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sift
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Fred Sadaghiani
|
|
8
8
|
- Yoav Schatzberg
|
|
9
9
|
- Jacob Burnim
|
|
10
|
-
autorequire:
|
|
10
|
+
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date:
|
|
13
|
+
date: 2026-03-02 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: rspec
|
|
@@ -80,14 +80,14 @@ dependencies:
|
|
|
80
80
|
requirements:
|
|
81
81
|
- - ">="
|
|
82
82
|
- !ruby/object:Gem::Version
|
|
83
|
-
version: 0.
|
|
83
|
+
version: 0.23.3
|
|
84
84
|
type: :runtime
|
|
85
85
|
prerelease: false
|
|
86
86
|
version_requirements: !ruby/object:Gem::Requirement
|
|
87
87
|
requirements:
|
|
88
88
|
- - ">="
|
|
89
89
|
- !ruby/object:Gem::Version
|
|
90
|
-
version: 0.
|
|
90
|
+
version: 0.23.3
|
|
91
91
|
- !ruby/object:Gem::Dependency
|
|
92
92
|
name: multi_json
|
|
93
93
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -116,18 +116,17 @@ dependencies:
|
|
|
116
116
|
- - ">="
|
|
117
117
|
- !ruby/object:Gem::Version
|
|
118
118
|
version: '0'
|
|
119
|
-
description: Sift
|
|
119
|
+
description: Sift Ruby API. Please see http://sift.com for more details.
|
|
120
120
|
email:
|
|
121
|
-
- support@
|
|
121
|
+
- support@sift.com
|
|
122
122
|
executables: []
|
|
123
123
|
extensions: []
|
|
124
124
|
extra_rdoc_files: []
|
|
125
125
|
files:
|
|
126
|
-
- ".circleci/config.yml"
|
|
127
126
|
- ".github/pull_request_template.md"
|
|
127
|
+
- ".github/workflows/ci.yml"
|
|
128
128
|
- ".github/workflows/publishing_sift_ruby.yml"
|
|
129
129
|
- ".gitignore"
|
|
130
|
-
- ".jenkins/Jenkinsfile"
|
|
131
130
|
- Gemfile
|
|
132
131
|
- HISTORY
|
|
133
132
|
- LICENSE
|
|
@@ -158,6 +157,7 @@ files:
|
|
|
158
157
|
- spec/unit/client_psp_merchant_spec.rb
|
|
159
158
|
- spec/unit/client_spec.rb
|
|
160
159
|
- spec/unit/client_validationapi_spec.rb
|
|
160
|
+
- spec/unit/configuration_spec.rb
|
|
161
161
|
- spec/unit/router_spec.rb
|
|
162
162
|
- spec/unit/validate/decision_spec.rb
|
|
163
163
|
- spec/unit/validate/primitive_spec.rb
|
|
@@ -168,10 +168,10 @@ files:
|
|
|
168
168
|
- test_integration_app/psp_merchants_api/test_psp_merchant_api.rb
|
|
169
169
|
- test_integration_app/score_api/test_score_api.rb
|
|
170
170
|
- test_integration_app/verification_api/test_verification_api.rb
|
|
171
|
-
homepage: http://
|
|
171
|
+
homepage: http://sift.com
|
|
172
172
|
licenses: []
|
|
173
173
|
metadata: {}
|
|
174
|
-
post_install_message:
|
|
174
|
+
post_install_message:
|
|
175
175
|
rdoc_options: []
|
|
176
176
|
require_paths:
|
|
177
177
|
- lib
|
|
@@ -179,7 +179,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
179
179
|
requirements:
|
|
180
180
|
- - ">="
|
|
181
181
|
- !ruby/object:Gem::Version
|
|
182
|
-
version:
|
|
182
|
+
version: 2.7.0
|
|
183
183
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
184
184
|
requirements:
|
|
185
185
|
- - ">="
|
|
@@ -187,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
187
187
|
version: '0'
|
|
188
188
|
requirements: []
|
|
189
189
|
rubygems_version: 3.1.6
|
|
190
|
-
signing_key:
|
|
190
|
+
signing_key:
|
|
191
191
|
specification_version: 4
|
|
192
|
-
summary: Sift
|
|
192
|
+
summary: Sift Ruby API Gem
|
|
193
193
|
test_files: []
|
data/.circleci/config.yml
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
version: 2.1
|
|
2
|
-
|
|
3
|
-
orbs:
|
|
4
|
-
slack: circleci/slack@4.4.2
|
|
5
|
-
|
|
6
|
-
commands:
|
|
7
|
-
export_slack_id:
|
|
8
|
-
steps:
|
|
9
|
-
- run:
|
|
10
|
-
name : Exporting circleci username as slack id.
|
|
11
|
-
command: echo 'export SLACK_PARAM_MENTIONS="$CIRCLE_USERNAME"' >> "$BASH_ENV"
|
|
12
|
-
- run:
|
|
13
|
-
name : CircleCi To Slack user mapping.
|
|
14
|
-
command: |
|
|
15
|
-
echo $GITHUB_SLACK_USERMAPPING | base64 --decode > github_slack
|
|
16
|
-
while read -r line || [[ -n $line ]];
|
|
17
|
-
do
|
|
18
|
-
[[ ${line//[[:space:]]/} =~ ^#.* || -z "$line" ]] && continue
|
|
19
|
-
echo "$line" | tr "=" "\n" | while read -r key; do
|
|
20
|
-
read -r value
|
|
21
|
-
if [ "$CIRCLE_USERNAME" = "${key}" ]; then
|
|
22
|
-
echo "export SLACK_PARAM_MENTIONS='<@${value}>'" >> $BASH_ENV
|
|
23
|
-
fi
|
|
24
|
-
done
|
|
25
|
-
done < github_slack
|
|
26
|
-
rm github_slack
|
|
27
|
-
|
|
28
|
-
slack/notify: &slack_notify
|
|
29
|
-
branch_pattern: master
|
|
30
|
-
event: fail
|
|
31
|
-
channel: ci-build-status
|
|
32
|
-
template: SLACK_TAG_CI_FAILURE_TEMPLATE
|
|
33
|
-
|
|
34
|
-
context: &context
|
|
35
|
-
- slack-templates
|
|
36
|
-
- slack_Oauth
|
|
37
|
-
- Github_Slack_UserMapping
|
|
38
|
-
|
|
39
|
-
jobs:
|
|
40
|
-
build:
|
|
41
|
-
parallelism: 3 # run three instances of this job in parallel
|
|
42
|
-
docker:
|
|
43
|
-
- image: circleci/ruby:2.4.2-jessie-node
|
|
44
|
-
environment:
|
|
45
|
-
BUNDLE_JOBS: 3
|
|
46
|
-
BUNDLE_RETRY: 3
|
|
47
|
-
BUNDLE_PATH: vendor/bundle
|
|
48
|
-
steps:
|
|
49
|
-
- checkout
|
|
50
|
-
- export_slack_id
|
|
51
|
-
|
|
52
|
-
- run:
|
|
53
|
-
name: Which bundler?
|
|
54
|
-
command: bundle -v
|
|
55
|
-
|
|
56
|
-
- restore_cache:
|
|
57
|
-
keys:
|
|
58
|
-
- sift-bundle-{{ checksum "sift.gemspec" }}
|
|
59
|
-
- sift-bundle-
|
|
60
|
-
|
|
61
|
-
- run:
|
|
62
|
-
name: Bundle Install
|
|
63
|
-
command: bundle check || bundle install
|
|
64
|
-
|
|
65
|
-
- save_cache:
|
|
66
|
-
key: sift-bundle-{{ checksum "sift.gemspec" }}
|
|
67
|
-
paths:
|
|
68
|
-
- vendor/bundle
|
|
69
|
-
|
|
70
|
-
- run:
|
|
71
|
-
name: Run rspec in parallel
|
|
72
|
-
command: |
|
|
73
|
-
bundle exec rspec --profile 10 \
|
|
74
|
-
--format RspecJunitFormatter \
|
|
75
|
-
--out test_results/rspec.xml \
|
|
76
|
-
--format progress \
|
|
77
|
-
$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)
|
|
78
|
-
|
|
79
|
-
- store_test_results:
|
|
80
|
-
path: test_results
|
|
81
|
-
- slack/notify:
|
|
82
|
-
<<: *slack_notify
|
|
83
|
-
|
|
84
|
-
run_integration_tests:
|
|
85
|
-
docker:
|
|
86
|
-
- image: circleci/ruby:2.4.2-jessie-node
|
|
87
|
-
steps:
|
|
88
|
-
- checkout
|
|
89
|
-
- run:
|
|
90
|
-
name: Install bundle and run the tests
|
|
91
|
-
command: |
|
|
92
|
-
bundle check || bundle install
|
|
93
|
-
bundle exec ruby test_integration_app/main.rb
|
|
94
|
-
|
|
95
|
-
workflows:
|
|
96
|
-
ruby-test:
|
|
97
|
-
jobs:
|
|
98
|
-
- build:
|
|
99
|
-
context: *context
|
|
100
|
-
ruby-integration-tests:
|
|
101
|
-
jobs:
|
|
102
|
-
- run_integration_tests:
|
|
103
|
-
filters:
|
|
104
|
-
branches:
|
|
105
|
-
only: master
|
data/.jenkins/Jenkinsfile
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
// Load Jenkins shared library
|
|
2
|
-
jenkinsBranch = 'v0.37.0'
|
|
3
|
-
sharedLib = library("shared-lib@${jenkinsBranch}")
|
|
4
|
-
|
|
5
|
-
def siftRubyWorkflow = sharedLib.com.sift.ci.SiftRubyWorkflow.new()
|
|
6
|
-
def ciUtil = sharedLib.com.sift.ci.CIUtil.new()
|
|
7
|
-
def stackdriver = sharedLib.com.sift.ci.StackDriverMetrics.new()
|
|
8
|
-
|
|
9
|
-
// Default GitHub status context for automatically triggered builds
|
|
10
|
-
def defaultStatusContext = 'Jenkins:auto'
|
|
11
|
-
|
|
12
|
-
// Pod template file for Jenkins agent pod
|
|
13
|
-
// Pod template yaml file is defined in https://github.com/SiftScience/jenkins/tree/master/resources/jenkins-k8s-pod-templates
|
|
14
|
-
def ruby2PodTemplateFile = 'ruby-2-4-2-pod-template.yaml'
|
|
15
|
-
def ruby2PodLabel = "ruby2-${BUILD_TAG}"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
// GitHub repo name
|
|
19
|
-
def repoName = 'sift-ruby'
|
|
20
|
-
|
|
21
|
-
pipeline {
|
|
22
|
-
agent none
|
|
23
|
-
options {
|
|
24
|
-
timestamps()
|
|
25
|
-
skipDefaultCheckout()
|
|
26
|
-
disableConcurrentBuilds()
|
|
27
|
-
disableRestartFromStage()
|
|
28
|
-
parallelsAlwaysFailFast()
|
|
29
|
-
buildDiscarder logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '30', numToKeepStr: '')
|
|
30
|
-
timeout(time: 1, unit: 'HOURS')
|
|
31
|
-
}
|
|
32
|
-
environment {
|
|
33
|
-
GIT_BRANCH = "${env.CHANGE_BRANCH != null? env.CHANGE_BRANCH : env.BRANCH_NAME}"
|
|
34
|
-
}
|
|
35
|
-
stages {
|
|
36
|
-
stage('Initialize') {
|
|
37
|
-
steps {
|
|
38
|
-
script {
|
|
39
|
-
statusContext = defaultStatusContext
|
|
40
|
-
// Get the commit sha for the build
|
|
41
|
-
commitSha = ciUtil.commitHashForBuild()
|
|
42
|
-
ciUtil.updateGithubCommitStatus(repoName, statusContext, 'Started', 'pending', commitSha)
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
stage ('Build and Test Workflows') {
|
|
47
|
-
steps {
|
|
48
|
-
script {
|
|
49
|
-
def workflows = [:]
|
|
50
|
-
def stage1 = 'Run Integration Tests - ruby'
|
|
51
|
-
workflows[stage1] = {
|
|
52
|
-
stage(stage1) {
|
|
53
|
-
if (env.GIT_BRANCH.equals('master')) {
|
|
54
|
-
ciUtil.updateGithubCommitStatus(repoName, stage1, 'Started', 'pending', commitSha)
|
|
55
|
-
try {
|
|
56
|
-
siftRubyWorkflow.runSiftRubyIntegration(ruby2PodTemplateFile, ruby2PodLabel)
|
|
57
|
-
ciUtil.updateGithubCommitStatus(repoName, stage1, 'SUCCESS', 'success', commitSha)
|
|
58
|
-
} catch (Exception e) {
|
|
59
|
-
ciUtil.updateGithubCommitStatus(repoName, stage1, 'FAILURE', 'failure', commitSha)
|
|
60
|
-
print("${stage1} failed")
|
|
61
|
-
throw e
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
def stage2 = 'Test - ruby'
|
|
67
|
-
workflows[stage2] = {
|
|
68
|
-
stage(stage2) {
|
|
69
|
-
ciUtil.updateGithubCommitStatus(repoName, stage2, 'Started', 'pending', commitSha)
|
|
70
|
-
try {
|
|
71
|
-
siftRubyWorkflow.runSiftRubyTest(ruby2PodTemplateFile, ruby2PodLabel)
|
|
72
|
-
ciUtil.updateGithubCommitStatus(repoName, stage2, 'SUCCESS', 'success', commitSha)
|
|
73
|
-
} catch (Exception e) {
|
|
74
|
-
ciUtil.updateGithubCommitStatus(repoName, stage2, 'FAILURE', 'failure', commitSha)
|
|
75
|
-
print("${stage2} failed")
|
|
76
|
-
throw e
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
parallel workflows
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
post {
|
|
86
|
-
success {
|
|
87
|
-
script {
|
|
88
|
-
ciUtil.updateGithubCommitStatus(repoName, statusContext, currentBuild.currentResult, 'success', commitSha)
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
unsuccessful {
|
|
92
|
-
script {
|
|
93
|
-
ciUtil.updateGithubCommitStatus(repoName, statusContext, currentBuild.currentResult, 'failure', commitSha)
|
|
94
|
-
ciUtil.notifySlack(repoName, commitSha)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
always {
|
|
98
|
-
script {
|
|
99
|
-
stackdriver.updatePipelineStatistics(this)
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|