fastlane 2.126.0.beta.20190606200048 → 2.126.0.beta.20190607200028

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +1 -1
  3. data/fastlane/lib/fastlane/version.rb +1 -1
  4. data/fastlane_core/lib/fastlane_core/build_watcher.rb +3 -4
  5. data/pilot/lib/pilot/build_manager.rb +7 -7
  6. data/pilot/lib/pilot/manager.rb +2 -2
  7. data/pilot/lib/pilot/tester_exporter.rb +3 -3
  8. data/pilot/lib/pilot/tester_manager.rb +2 -2
  9. data/spaceship/lib/spaceship/connect_api.rb +2 -17
  10. data/spaceship/lib/spaceship/connect_api/{models/model.rb → model.rb} +5 -4
  11. data/spaceship/lib/spaceship/connect_api/response.rb +4 -7
  12. data/spaceship/lib/spaceship/connect_api/testflight/base.rb +41 -0
  13. data/spaceship/lib/spaceship/connect_api/testflight/client.rb +553 -0
  14. data/spaceship/lib/spaceship/connect_api/testflight/models/app.rb +99 -0
  15. data/spaceship/lib/spaceship/connect_api/testflight/models/beta_app_localization.rb +30 -0
  16. data/spaceship/lib/spaceship/connect_api/testflight/models/beta_app_review_detail.rb +34 -0
  17. data/spaceship/lib/spaceship/connect_api/testflight/models/beta_app_review_submission.rb +28 -0
  18. data/spaceship/lib/spaceship/connect_api/testflight/models/beta_build_localization.rb +22 -0
  19. data/spaceship/lib/spaceship/connect_api/testflight/models/beta_build_metric.rb +26 -0
  20. data/spaceship/lib/spaceship/connect_api/testflight/models/beta_group.rb +43 -0
  21. data/spaceship/lib/spaceship/connect_api/testflight/models/beta_tester.rb +58 -0
  22. data/spaceship/lib/spaceship/connect_api/testflight/models/beta_tester_metric.rb +45 -0
  23. data/spaceship/lib/spaceship/connect_api/testflight/models/build.rb +146 -0
  24. data/spaceship/lib/spaceship/connect_api/testflight/models/build_beta_detail.rb +58 -0
  25. data/spaceship/lib/spaceship/connect_api/testflight/models/build_delivery.rb +38 -0
  26. data/spaceship/lib/spaceship/connect_api/testflight/models/pre_release_version.rb +22 -0
  27. data/spaceship/lib/spaceship/connect_api/testflight/models/user.rb +52 -0
  28. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +27 -0
  29. data/spaceship/lib/spaceship/test_flight/build.rb +3 -3
  30. data/spaceship/lib/spaceship/test_flight/build_trains.rb +1 -1
  31. metadata +34 -33
  32. data/spaceship/lib/spaceship/connect_api/base.rb +0 -39
  33. data/spaceship/lib/spaceship/connect_api/client.rb +0 -551
  34. data/spaceship/lib/spaceship/connect_api/models/app.rb +0 -97
  35. data/spaceship/lib/spaceship/connect_api/models/beta_app_localization.rb +0 -28
  36. data/spaceship/lib/spaceship/connect_api/models/beta_app_review_detail.rb +0 -32
  37. data/spaceship/lib/spaceship/connect_api/models/beta_app_review_submission.rb +0 -26
  38. data/spaceship/lib/spaceship/connect_api/models/beta_build_localization.rb +0 -20
  39. data/spaceship/lib/spaceship/connect_api/models/beta_build_metric.rb +0 -24
  40. data/spaceship/lib/spaceship/connect_api/models/beta_group.rb +0 -41
  41. data/spaceship/lib/spaceship/connect_api/models/beta_tester.rb +0 -56
  42. data/spaceship/lib/spaceship/connect_api/models/beta_tester_metric.rb +0 -43
  43. data/spaceship/lib/spaceship/connect_api/models/build.rb +0 -144
  44. data/spaceship/lib/spaceship/connect_api/models/build_beta_detail.rb +0 -56
  45. data/spaceship/lib/spaceship/connect_api/models/build_delivery.rb +0 -36
  46. data/spaceship/lib/spaceship/connect_api/models/pre_release_version.rb +0 -20
  47. data/spaceship/lib/spaceship/connect_api/models/user.rb +0 -50
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 61b4101d42b906b61eca04fa40634b785bc3422b
4
- data.tar.gz: dc2d90be2d1fd77826e2f9ae2b4d024191743cf0
3
+ metadata.gz: d91d9d80b7f521a1830910eb7fd026640a56a698
4
+ data.tar.gz: 7dccfc7b62dabaa8a56885ca65f0b074817f0157
5
5
  SHA512:
6
- metadata.gz: b6e4dcc9647440b2a8aab7ae69f2db28fb20ed0b3f27af3e416505261fc1bbd03da1576f51960a8909da5be60eb01ff0d8f4a96d57c99b2fb7c9a0014a53be51
7
- data.tar.gz: dd1d9d09003164e0e7c97d7d733f7c9e8bdd803c7c793f627db1ac08e2b5a2a24ed9c15a7199b7c74b6ad27a1b965c9c7e6986ecc6e7400125f6bf5518ee3868
6
+ metadata.gz: 040c1029f885f87674fd9d817bfc2bea1ec7dd3580c7470b4b6850d537802016ef96af40e3f8ecddff63662699e946758229dbda4c4856cfcd8630d49e5b4ffc
7
+ data.tar.gz: f33329bc76c620f62268bf5c02b638913904d85659e88bba29cf3341291d3d079be08261dabf48b162e3d8a4e177b9cded99f6d0fe0f51cc9ee23ff37de0c443
@@ -49,7 +49,7 @@ module Fastlane
49
49
  UI.message("Fetching the latest build number for #{version_number_message}")
50
50
 
51
51
  # Get latest build for optional version number and return build number if found
52
- client = Spaceship::ConnectAPI::Base.client
52
+ client = Spaceship::ConnectAPI::TestFlight.client
53
53
  build = client.get_builds(filter: filter, sort: "-version", includes: "preReleaseVersion", limit: 1).first
54
54
  if build
55
55
  build_nr = build.version
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
- VERSION = '2.126.0.beta.20190606200048'.freeze
2
+ VERSION = '2.126.0.beta.20190607200028'.freeze
3
3
  DESCRIPTION = "The easiest way to automate beta deployments and releases for your iOS and Android apps".freeze
4
4
  MINIMUM_XCODE_RELEASE = "7.0".freeze
5
5
  RUBOCOP_REQUIREMENT = '0.49.1'.freeze
@@ -1,5 +1,4 @@
1
- require 'spaceship/connect_api/models/build'
2
- require 'spaceship/connect_api/models/build_delivery'
1
+ require 'spaceship/connect_api'
3
2
 
4
3
  require_relative 'ui/ui'
5
4
 
@@ -48,12 +47,12 @@ module FastlaneCore
48
47
  watched_app_version = remove_version_leading_zeros(version: watched_app_version)
49
48
  watched_build_version = remove_version_leading_zeros(version: watched_build_version)
50
49
 
51
- build_deliveries = Spaceship::ConnectAPI::BuildDelivery.all(app_id: app_id, version: watched_app_version, build_number: watched_build_version)
50
+ build_deliveries = Spaceship::ConnectAPI::TestFlight::BuildDelivery.all(app_id: app_id, version: watched_app_version, build_number: watched_build_version)
52
51
  build_delivery = build_deliveries.first
53
52
 
54
53
  # Get processed builds when no longer in build deliveries
55
54
  if build_delivery.nil?
56
- matched_builds = Spaceship::ConnectAPI::Build.all(
55
+ matched_builds = Spaceship::ConnectAPI::TestFlight::Build.all(
57
56
  app_id: app_id,
58
57
  version: watched_app_version,
59
58
  build_number: watched_build_version,
@@ -100,14 +100,14 @@ module Pilot
100
100
  end
101
101
 
102
102
  # Get latest uploaded build if no build specified
103
- build ||= Spaceship::ConnectAPI::Build.all(app_id: app.id, sort: "-uploadedDate", limit: 1).first
103
+ build ||= Spaceship::ConnectAPI::TestFlight::Build.all(app_id: app.id, sort: "-uploadedDate", limit: 1).first
104
104
 
105
105
  # Verify the build has all the includes that we need
106
106
  # and fetch a new build if not
107
107
  if build && (!build.app || !build.build_beta_detail || !build.pre_release_version)
108
108
  UI.important("Build did include information for app, build beta detail and pre release version")
109
109
  UI.important("Fetching a new build with all the information needed")
110
- build = Spaceship::ConnectAPI::Build.get(build_id: build.id)
110
+ build = Spaceship::ConnectAPI::TestFlight::Build.get(build_id: build.id)
111
111
  end
112
112
 
113
113
  # Error out if no build
@@ -328,7 +328,7 @@ module Pilot
328
328
  uses_non_exempt_encryption = options[:uses_non_exempt_encryption]
329
329
  attributes = { usesNonExemptEncryption: uses_non_exempt_encryption }
330
330
 
331
- client = Spaceship::ConnectAPI::Base.client
331
+ client = Spaceship::ConnectAPI::TestFlight.client
332
332
  client.patch_builds(build_id: uploaded_build.id, attributes: attributes)
333
333
 
334
334
  UI.important("Export compliance has been set to '#{uses_non_exempt_encryption}'. Need to wait for build to finishing processing again...")
@@ -350,7 +350,7 @@ module Pilot
350
350
  attributes[:demoAccountRequired] = info[:demo_account_required] if info.key?(:demo_account_required)
351
351
  attributes[:notes] = info[:notes] if info.key?(:notes)
352
352
 
353
- client = Spaceship::ConnectAPI::Base.client
353
+ client = Spaceship::ConnectAPI::TestFlight.client
354
354
  client.patch_beta_app_review_detail(app_id: build.app.id, attributes: attributes)
355
355
  end
356
356
 
@@ -392,7 +392,7 @@ module Pilot
392
392
  attributes[:tvOsPrivacyPolicy] = info[:tv_os_privacy_policy_url] if info.key?(:tv_os_privacy_policy_url)
393
393
  attributes[:description] = info[:description] if info.key?(:description)
394
394
 
395
- client = Spaceship::ConnectAPI::Base.client
395
+ client = Spaceship::ConnectAPI::TestFlight.client
396
396
  if localization
397
397
  client.patch_beta_app_localizations(localization_id: localization.id, attributes: attributes)
398
398
  else
@@ -435,7 +435,7 @@ module Pilot
435
435
  attributes = {}
436
436
  attributes[:whatsNew] = self.class.sanitize_changelog(info[:whats_new]) if info.key?(:whats_new)
437
437
 
438
- client = Spaceship::ConnectAPI::Base.client
438
+ client = Spaceship::ConnectAPI::TestFlight.client
439
439
  if localization
440
440
  client.patch_beta_build_localizations(localization_id: localization.id, attributes: attributes)
441
441
  else
@@ -450,7 +450,7 @@ module Pilot
450
450
  attributes = {}
451
451
  attributes[:autoNotifyEnabled] = info[:auto_notify_enabled] if info.key?(:auto_notify_enabled)
452
452
 
453
- client = Spaceship::ConnectAPI::Base.client
453
+ client = Spaceship::ConnectAPI::TestFlight.client
454
454
  client.patch_build_beta_details(build_beta_details_id: build_beta_detail.id, attributes: attributes)
455
455
  end
456
456
  end
@@ -29,7 +29,7 @@ module Pilot
29
29
  def app
30
30
  @app_id ||= fetch_app_id
31
31
 
32
- @app ||= Spaceship::ConnectAPI::App.get(app_id: @app_id)
32
+ @app ||= Spaceship::ConnectAPI::TestFlight::App.get(app_id: @app_id)
33
33
  unless @app
34
34
  UI.user_error!("Could not find app with #{(config[:apple_id] || config[:app_identifier])}")
35
35
  end
@@ -48,7 +48,7 @@ module Pilot
48
48
  config[:app_identifier] = fetch_app_identifier
49
49
 
50
50
  if config[:app_identifier]
51
- @app ||= Spaceship::ConnectAPI::App.find(config[:app_identifier])
51
+ @app ||= Spaceship::ConnectAPI::TestFlight::App.find(config[:app_identifier])
52
52
  UI.user_error!("Couldn't find app '#{config[:app_identifier]}' on the account of '#{config[:username]}' on App Store Connect") unless @app
53
53
  @app_id ||= @app.id
54
54
  end
@@ -15,7 +15,7 @@ module Pilot
15
15
  if app
16
16
  testers = app.get_beta_testers(includes: "apps,betaTesterMetrics,betaGroups")
17
17
  else
18
- testers = Spaceship::ConnectAPI::BetaTester.all(includes: "apps,betaTesterMetrics,betaGroups")
18
+ testers = Spaceship::ConnectAPI::TestFlight::BetaTester.all(includes: "apps,betaTesterMetrics,betaGroups")
19
19
  end
20
20
 
21
21
  file = config[:testers_file_path]
@@ -41,13 +41,13 @@ module Pilot
41
41
 
42
42
  def find_app(apple_id: nil, app_identifier: nil)
43
43
  if app_identifier
44
- app = Spaceship::ConnectAPI::App.find(app_identifier)
44
+ app = Spaceship::ConnectAPI::TestFlight::App.find(app_identifier)
45
45
  UI.user_error!("Could not find an app by #{app_identifier}") unless app
46
46
  return app
47
47
  end
48
48
 
49
49
  if apple_id
50
- app = Spaceship::ConnectAPI::App.get(app_id: apple_id)
50
+ app = Spaceship::ConnectAPI::TestFlight::App.get(app_id: apple_id)
51
51
  UI.user_error!("Could not find an app by #{apple_id}") unless app
52
52
  return app
53
53
  end
@@ -83,13 +83,13 @@ module Pilot
83
83
 
84
84
  def find_app(apple_id: nil, app_identifier: nil)
85
85
  if app_identifier
86
- app = Spaceship::ConnectAPI::App.find(app_identifier)
86
+ app = Spaceship::ConnectAPI::TestFlight::App.find(app_identifier)
87
87
  UI.user_error!("Could not find an app by #{app_identifier}") unless app
88
88
  return app
89
89
  end
90
90
 
91
91
  if apple_id
92
- app = Spaceship::ConnectAPI::App.get(app_id: apple_id)
92
+ app = Spaceship::ConnectAPI::TestFlight::App.get(app_id: apple_id)
93
93
  UI.user_error!("Could not find an app by #{apple_id}") unless app
94
94
  return app
95
95
  end
@@ -1,20 +1,5 @@
1
- require 'spaceship/connect_api/client'
2
- require 'spaceship/connect_api/base'
1
+ require 'spaceship/connect_api/model'
3
2
  require 'spaceship/connect_api/response'
4
3
  require 'spaceship/connect_api/token'
5
4
 
6
- require 'spaceship/connect_api/models/model'
7
- require 'spaceship/connect_api/models/app'
8
- require 'spaceship/connect_api/models/beta_app_localization'
9
- require 'spaceship/connect_api/models/beta_build_localization'
10
- require 'spaceship/connect_api/models/beta_build_metric'
11
- require 'spaceship/connect_api/models/beta_app_review_detail'
12
- require 'spaceship/connect_api/models/beta_app_review_submission'
13
- require 'spaceship/connect_api/models/beta_group'
14
- require 'spaceship/connect_api/models/beta_tester'
15
- require 'spaceship/connect_api/models/beta_tester_metric'
16
- require 'spaceship/connect_api/models/build'
17
- require 'spaceship/connect_api/models/build_delivery'
18
- require 'spaceship/connect_api/models/build_beta_detail'
19
- require 'spaceship/connect_api/models/pre_release_version'
20
- require 'spaceship/connect_api/models/user'
5
+ require 'spaceship/connect_api/testflight/testflight'
@@ -1,4 +1,5 @@
1
1
  require_relative '../base'
2
+ require_relative './testflight/base'
2
3
 
3
4
  module Spaceship
4
5
  module ConnectAPI
@@ -11,8 +12,8 @@ module Spaceship
11
12
  end
12
13
 
13
14
  module ClassMethods
14
- def client
15
- return Spaceship::ConnectAPI::Base.client
15
+ def testflight_client
16
+ return Spaceship::ConnectAPI::TestFlight::Base.client
16
17
  end
17
18
  end
18
19
 
@@ -30,8 +31,8 @@ module Spaceship
30
31
  end
31
32
  end
32
33
 
33
- def client
34
- return Spaceship::ConnectAPI::Base.client
34
+ def testflight_client
35
+ return Spaceship::ConnectAPI::TestFlight::Base.client
35
36
  end
36
37
 
37
38
  #
@@ -1,5 +1,4 @@
1
- require_relative './base'
2
- require_relative './models/model'
1
+ require_relative './model'
3
2
 
4
3
  module Spaceship
5
4
  module ConnectAPI
@@ -7,14 +6,12 @@ module Spaceship
7
6
  include Enumerable
8
7
  attr_reader :body
9
8
  attr_reader :status
9
+ attr_reader :client
10
10
 
11
- def initialize(body: nil, status: nil)
11
+ def initialize(body: nil, status: nil, client: nil)
12
12
  @body = body
13
13
  @status = status
14
- end
15
-
16
- def client
17
- return Spaceship::ConnectAPI::Base.client
14
+ @client = client
18
15
  end
19
16
 
20
17
  def next_url
@@ -0,0 +1,41 @@
1
+ require_relative '../../base'
2
+ require_relative '../../tunes/tunes_client'
3
+
4
+ module Spaceship
5
+ module ConnectAPI
6
+ module TestFlight
7
+ class Base < Spaceship::Base
8
+ def self.client
9
+ # Verify there is a client that can be used
10
+ if Spaceship::Tunes.client
11
+ # Initialize new client if new or if team changed
12
+ if @client.nil? || @client.team_id != Spaceship::Tunes.client.team_id
13
+ @client = Client.client_with_authorization_from(Spaceship::Tunes.client)
14
+ end
15
+ end
16
+
17
+ # Need to handle not having a client but this shouldn't ever happen
18
+ raise "Please login using `Spaceship::Tunes.login('user', 'password')`" unless @client
19
+
20
+ @client
21
+ end
22
+
23
+ ##
24
+ # Have subclasses inherit the client from their superclass
25
+ #
26
+ # Essentially, we are making a class-inheritable-accessor as described here:
27
+ # https://apidock.com/rails/v4.2.7/Class/class_attribute
28
+ def self.inherited(subclass)
29
+ this_class = self
30
+ subclass.define_singleton_method(:client) do
31
+ this_class.client
32
+ end
33
+ end
34
+
35
+ def to_json
36
+ raw_data.to_json
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,553 @@
1
+ require_relative '../../client'
2
+ require_relative '../response'
3
+
4
+ module Spaceship
5
+ # rubocop:disable Metrics/ClassLength
6
+ module ConnectAPI
7
+ module TestFlight
8
+ class Client < Spaceship::Client
9
+ ##
10
+ # Spaceship HTTP client for the App Store Connect API.
11
+ #
12
+ # This client is solely responsible for the making HTTP requests and
13
+ # parsing their responses. Parameters should be either named parameters, or
14
+ # for large request data bodies, pass in anything that can resond to
15
+ # `to_json`.
16
+ #
17
+ # Each request method should validate the required parameters. A required parameter is one that would result in 400-range response if it is not supplied.
18
+ # Each request method should make only one request. For more high-level logic, put code in the data models.
19
+
20
+ def self.hostname
21
+ 'https://appstoreconnect.apple.com/iris/v1/'
22
+ end
23
+
24
+ #
25
+ # Helpers
26
+ #
27
+
28
+ def build_params(filter: nil, includes: nil, limit: nil, sort: nil, cursor: nil)
29
+ params = {}
30
+
31
+ filter = filter.delete_if { |k, v| v.nil? } if filter
32
+
33
+ params[:filter] = filter if filter && !filter.empty?
34
+ params[:include] = includes if includes
35
+ params[:limit] = limit if limit
36
+ params[:sort] = sort if sort
37
+ params[:cursor] = cursor if cursor
38
+
39
+ return params
40
+ end
41
+
42
+ def get(url_or_path, params = nil)
43
+ response = request(:get) do |req|
44
+ req.url(url_or_path)
45
+ req.options.params_encoder = Faraday::NestedParamsEncoder
46
+ req.params = params if params
47
+ end
48
+ handle_response(response)
49
+ end
50
+
51
+ def post(url_or_path, body)
52
+ response = request(:post) do |req|
53
+ req.url(url_or_path)
54
+ req.body = body.to_json
55
+ req.headers['Content-Type'] = 'application/json'
56
+ end
57
+ handle_response(response)
58
+ end
59
+
60
+ def patch(url_or_path, body)
61
+ response = request(:patch) do |req|
62
+ req.url(url_or_path)
63
+ req.body = body.to_json
64
+ req.headers['Content-Type'] = 'application/json'
65
+ end
66
+ handle_response(response)
67
+ end
68
+
69
+ def delete(url_or_path, params = nil, body = nil)
70
+ response = request(:delete) do |req|
71
+ req.url(url_or_path)
72
+ req.options.params_encoder = Faraday::NestedParamsEncoder if params
73
+ req.params = params if params
74
+ req.body = body.to_json if body
75
+ req.headers['Content-Type'] = 'application/json' if body
76
+ end
77
+ handle_response(response)
78
+ end
79
+
80
+ #
81
+ # apps
82
+ #
83
+
84
+ def get_apps(filter: {}, includes: nil, limit: nil, sort: nil)
85
+ # GET
86
+ # https://appstoreconnect.apple.com/iris/v1/apps
87
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort)
88
+ get("apps", params)
89
+ end
90
+
91
+ def get_app(app_id: nil, includes: nil)
92
+ # GET
93
+ # https://appstoreconnect.apple.com/iris/v1/apps/<app_id>
94
+ params = build_params(filter: nil, includes: includes, limit: nil, sort: nil)
95
+ get("apps/#{app_id}", params)
96
+ end
97
+
98
+ #
99
+ # betaAppLocalizations
100
+ #
101
+
102
+ def get_beta_app_localizations(filter: {}, includes: nil, limit: nil, sort: nil)
103
+ # GET
104
+ # https://appstoreconnect.apple.com/iris/v1/betaAppLocalizations?filter[app]=<app_id>
105
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort)
106
+ get("betaAppLocalizations", params)
107
+ end
108
+
109
+ def post_beta_app_localizations(app_id: nil, attributes: {})
110
+ # POST
111
+ # https://appstoreconnect.apple.com/iris/v1/betaAppLocalizations
112
+ path = "betaAppLocalizations"
113
+
114
+ body = {
115
+ data: {
116
+ attributes: attributes,
117
+ type: "betaAppLocalizations",
118
+ relationships: {
119
+ app: {
120
+ data: {
121
+ type: "apps",
122
+ id: app_id
123
+ }
124
+ }
125
+ }
126
+ }
127
+ }
128
+
129
+ post(path, body)
130
+ end
131
+
132
+ def patch_beta_app_localizations(localization_id: nil, attributes: {})
133
+ # PATCH
134
+ # https://appstoreconnect.apple.com/iris/v1/apps/<app_id>/betaAppLocalizations/<localization_id>
135
+ path = "betaAppLocalizations/#{localization_id}"
136
+
137
+ body = {
138
+ data: {
139
+ attributes: attributes,
140
+ id: localization_id,
141
+ type: "betaAppLocalizations"
142
+ }
143
+ }
144
+
145
+ patch(path, body)
146
+ end
147
+
148
+ #
149
+ # betaAppReviewDetails
150
+ #
151
+
152
+ def get_beta_app_review_detail(filter: {}, includes: nil, limit: nil, sort: nil)
153
+ # GET
154
+ # https://appstoreconnect.apple.com/iris/v1/betaAppReviewDetails?filter[app]=<app_id>
155
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort)
156
+ get("betaAppReviewDetails", params)
157
+ end
158
+
159
+ def patch_beta_app_review_detail(app_id: nil, attributes: {})
160
+ # PATCH
161
+ # https://appstoreconnect.apple.com/iris/v1/apps/<app_id>/betaAppReviewDetails
162
+ path = "betaAppReviewDetails/#{app_id}"
163
+
164
+ body = {
165
+ data: {
166
+ attributes: attributes,
167
+ id: app_id,
168
+ type: "betaAppReviewDetails"
169
+ }
170
+ }
171
+
172
+ patch(path, body)
173
+ end
174
+
175
+ #
176
+ # betaAppReviewSubmissions
177
+ #
178
+
179
+ def get_beta_app_review_submissions(filter: {}, includes: nil, limit: nil, sort: nil, cursor: nil)
180
+ # GET
181
+ # https://appstoreconnect.apple.com/iris/v1/betaAppReviewSubmissions
182
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort, cursor: cursor)
183
+ get("betaAppReviewSubmissions", params)
184
+ end
185
+
186
+ def post_beta_app_review_submissions(build_id: nil)
187
+ # POST
188
+ # https://appstoreconnect.apple.com/iris/v1/betaAppReviewSubmissions
189
+ path = "betaAppReviewSubmissions"
190
+ body = {
191
+ data: {
192
+ type: "betaAppReviewSubmissions",
193
+ relationships: {
194
+ build: {
195
+ data: {
196
+ type: "builds",
197
+ id: build_id
198
+ }
199
+ }
200
+ }
201
+ }
202
+ }
203
+
204
+ post(path, body)
205
+ end
206
+
207
+ def delete_beta_app_review_submission(beta_app_review_submission_id: nil)
208
+ # DELETE
209
+ # https://appstoreconnect.apple.com/iris/v1/betaAppReviewSubmissions/<beta_app_review_submission_id>
210
+ params = build_params(filter: nil, includes: nil, limit: nil, sort: nil, cursor: nil)
211
+ delete("betaAppReviewSubmissions/#{beta_app_review_submission_id}", params)
212
+ end
213
+
214
+ #
215
+ # betaBuildLocalizations
216
+ #
217
+
218
+ def get_beta_build_localizations(filter: {}, includes: nil, limit: nil, sort: nil)
219
+ # GET
220
+ # https://appstoreconnect.apple.com/iris/v1/betaBuildLocalizations
221
+ path = "betaBuildLocalizations"
222
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort)
223
+ get(path, params)
224
+ end
225
+
226
+ def post_beta_build_localizations(build_id: nil, attributes: {})
227
+ # POST
228
+ # https://appstoreconnect.apple.com/iris/v1/betaBuildLocalizations
229
+ path = "betaBuildLocalizations"
230
+
231
+ body = {
232
+ data: {
233
+ attributes: attributes,
234
+ type: "betaBuildLocalizations",
235
+ relationships: {
236
+ build: {
237
+ data: {
238
+ type: "builds",
239
+ id: build_id
240
+ }
241
+ }
242
+ }
243
+ }
244
+ }
245
+
246
+ post(path, body)
247
+ end
248
+
249
+ def patch_beta_build_localizations(localization_id: nil, feedbackEmail: nil, attributes: {})
250
+ # PATCH
251
+ # https://appstoreconnect.apple.com/iris/v1/apps/<app_id>/betaBuildLocalizations
252
+ path = "betaBuildLocalizations/#{localization_id}"
253
+
254
+ body = {
255
+ data: {
256
+ attributes: attributes,
257
+ id: localization_id,
258
+ type: "betaBuildLocalizations"
259
+ }
260
+ }
261
+
262
+ patch(path, body)
263
+ end
264
+
265
+ #
266
+ # betaBuildMetrics
267
+ #
268
+
269
+ def get_beta_build_metrics(filter: {}, includes: nil, limit: nil, sort: nil)
270
+ # GET
271
+ # https://appstoreconnect.apple.com/iris/v1/betaBuildMetrics
272
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort)
273
+ get("betaBuildMetrics", params)
274
+ end
275
+
276
+ #
277
+ # betaGroups
278
+ #
279
+
280
+ def get_beta_groups(filter: {}, includes: nil, limit: nil, sort: nil)
281
+ # GET
282
+ # https://appstoreconnect.apple.com/iris/v1/betaGroups
283
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort)
284
+ get("betaGroups", params)
285
+ end
286
+
287
+ def add_beta_groups_to_build(build_id: nil, beta_group_ids: [])
288
+ # POST
289
+ # https://appstoreconnect.apple.com/iris/v1/builds/<build_id>/relationships/betaGroups
290
+ path = "builds/#{build_id}/relationships/betaGroups"
291
+ body = {
292
+ data: beta_group_ids.map do |id|
293
+ {
294
+ type: "betaGroups",
295
+ id: id
296
+ }
297
+ end
298
+ }
299
+
300
+ post(path, body)
301
+ end
302
+
303
+ #
304
+ # betaTesters
305
+ #
306
+
307
+ def get_beta_testers(filter: {}, includes: nil, limit: nil, sort: nil)
308
+ # GET
309
+ # https://appstoreconnect.apple.com/iris/v1/betaTesters
310
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort)
311
+ get("betaTesters", params)
312
+ end
313
+
314
+ # beta_testers - [{email: "", firstName: "", lastName: ""}]
315
+ def post_bulk_beta_tester_assignments(beta_group_id: nil, beta_testers: nil)
316
+ # POST
317
+ # https://appstoreconnect.apple.com/iris/v1/bulkBetaTesterAssignments
318
+ beta_testers || []
319
+
320
+ beta_testers.map do |tester|
321
+ tester[:errors] = []
322
+ end
323
+
324
+ body = {
325
+ data: {
326
+ attributes: {
327
+ betaTesters: beta_testers
328
+ },
329
+ relationships: {
330
+ betaGroup: {
331
+ data: {
332
+ type: "betaGroups",
333
+ id: beta_group_id
334
+ }
335
+ }
336
+ },
337
+ type: "bulkBetaTesterAssignments"
338
+ }
339
+ }
340
+
341
+ post("bulkBetaTesterAssignments", body)
342
+ end
343
+
344
+ def delete_beta_tester_from_apps(beta_tester_id: nil, app_ids: [])
345
+ # DELETE
346
+ # https://appstoreconnect.apple.com/iris/v1/betaTesters/<beta_tester_id>/relationships/apps
347
+ path = "betaTesters/#{beta_tester_id}/relationships/apps"
348
+ body = {
349
+ data: app_ids.map do |id|
350
+ {
351
+ type: "apps",
352
+ id: id
353
+ }
354
+ end
355
+ }
356
+
357
+ delete(path, nil, body)
358
+ end
359
+
360
+ def delete_beta_tester_from_beta_groups(beta_tester_id: nil, beta_group_ids: [])
361
+ # DELETE
362
+ # https://appstoreconnect.apple.com/iris/v1/betaTesters/<beta_tester_id>/relationships/betaGroups
363
+ path = "betaTesters/#{beta_tester_id}/relationships/betaGroups"
364
+ body = {
365
+ data: beta_group_ids.map do |id|
366
+ {
367
+ type: "betaGroups",
368
+ id: id
369
+ }
370
+ end
371
+ }
372
+
373
+ delete(path, nil, body)
374
+ end
375
+
376
+ #
377
+ # betaTesterMetrics
378
+ #
379
+
380
+ def get_beta_tester_metrics(filter: {}, includes: nil, limit: nil, sort: nil)
381
+ # GET
382
+ # https://appstoreconnect.apple.com/iris/v1/betaTesterMetrics
383
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort)
384
+ get("betaTesterMetrics", params)
385
+ end
386
+
387
+ #
388
+ # builds
389
+ #
390
+
391
+ def get_builds(filter: {}, includes: "buildBetaDetail,betaBuildMetrics", limit: 10, sort: "uploadedDate", cursor: nil)
392
+ # GET
393
+ # https://appstoreconnect.apple.com/iris/v1/builds
394
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort, cursor: cursor)
395
+ get("builds", params)
396
+ end
397
+
398
+ def get_build(build_id: nil, includes: nil)
399
+ # GET
400
+ # https://appstoreconnect.apple.com/iris/v1/builds/<build_id>?
401
+ params = build_params(filter: nil, includes: includes, limit: nil, sort: nil, cursor: nil)
402
+ get("builds/#{build_id}", params)
403
+ end
404
+
405
+ def patch_builds(build_id: nil, attributes: {})
406
+ # PATCH
407
+ # https://appstoreconnect.apple.com/iris/v1/builds/<build_id>
408
+ path = "builds/#{build_id}"
409
+
410
+ body = {
411
+ data: {
412
+ attributes: attributes,
413
+ id: build_id,
414
+ type: "builds"
415
+ }
416
+ }
417
+
418
+ patch(path, body)
419
+ end
420
+
421
+ #
422
+ # buildBetaDetails
423
+ #
424
+
425
+ def get_build_beta_details(filter: {}, includes: nil, limit: nil, sort: nil)
426
+ # GET
427
+ # https://appstoreconnect.apple.com/iris/v1/buildBetaDetails
428
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort)
429
+ get("buildBetaDetails", params)
430
+ end
431
+
432
+ def patch_build_beta_details(build_beta_details_id: nil, attributes: {})
433
+ # PATCH
434
+ # https://appstoreconnect.apple.com/iris/v1/buildBetaDetails/<build_beta_details_id>
435
+ path = "buildBetaDetails/#{build_beta_details_id}"
436
+
437
+ body = {
438
+ data: {
439
+ attributes: attributes,
440
+ id: build_beta_details_id,
441
+ type: "buildBetaDetails"
442
+ }
443
+ }
444
+
445
+ patch(path, body)
446
+ end
447
+
448
+ #
449
+ # buildDeliveries
450
+ #
451
+
452
+ def get_build_deliveries(filter: {}, includes: nil, limit: nil, sort: nil)
453
+ # GET
454
+ # https://appstoreconnect.apple.com/iris/v1/buildDeliveries
455
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort)
456
+ get("buildDeliveries", params)
457
+ end
458
+
459
+ #
460
+ # preReleaseVersions
461
+ #
462
+
463
+ def get_pre_release_versions(filter: {}, includes: nil, limit: nil, sort: nil)
464
+ # GET
465
+ # https://appstoreconnect.apple.com/iris/v1/preReleaseVersions
466
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort)
467
+ get("preReleaseVersions", params)
468
+ end
469
+
470
+ #
471
+ # users
472
+ #
473
+
474
+ def get_users(filter: {}, includes: nil, limit: nil, sort: nil)
475
+ # GET
476
+ # https://appstoreconnect.apple.com/iris/v1/users
477
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort)
478
+ get("users", params)
479
+ end
480
+
481
+ protected
482
+
483
+ def handle_response(response)
484
+ if (200...300).cover?(response.status) && (response.body.nil? || response.body.empty?)
485
+ return
486
+ end
487
+
488
+ raise InternalServerError, "Server error got #{response.status}" if (500...600).cover?(response.status)
489
+
490
+ unless response.body.kind_of?(Hash)
491
+ raise UnexpectedResponse, response.body
492
+ end
493
+
494
+ raise UnexpectedResponse, response.body['error'] if response.body['error']
495
+
496
+ raise UnexpectedResponse, handle_errors(response) if response.body['errors']
497
+
498
+ raise UnexpectedResponse, "Temporary App Store Connect error: #{response.body}" if response.body['statusCode'] == 'ERROR'
499
+
500
+ return Spaceship::ConnectAPI::Response.new(body: response.body, status: response.status, client: self)
501
+ end
502
+
503
+ def handle_errors(response)
504
+ # Example error format
505
+ # {
506
+ # "errors" : [ {
507
+ # "id" : "ce8c391e-f858-411b-a14b-5aa26e0915f2",
508
+ # "status" : "400",
509
+ # "code" : "PARAMETER_ERROR.INVALID",
510
+ # "title" : "A parameter has an invalid value",
511
+ # "detail" : "'uploadedDate3' is not a valid field name",
512
+ # "source" : {
513
+ # "parameter" : "sort"
514
+ # }
515
+ # } ]
516
+ # }
517
+
518
+ return response.body['errors'].map do |error|
519
+ "#{error['title']} - #{error['detail']}"
520
+ end.join(" ")
521
+ end
522
+
523
+ private
524
+
525
+ # used to assert all of the named parameters are supplied values
526
+ #
527
+ # @raises NameError if the values are nil
528
+ def assert_required_params(method_name, binding)
529
+ parameter_names = method(method_name).parameters.map { |_, v| v }
530
+ parameter_names.each do |name|
531
+ if local_variable_get(binding, name).nil?
532
+ raise NameError, "`#{name}' is a required parameter"
533
+ end
534
+ end
535
+ end
536
+
537
+ def local_variable_get(binding, name)
538
+ if binding.respond_to?(:local_variable_get)
539
+ binding.local_variable_get(name)
540
+ else
541
+ binding.eval(name.to_s)
542
+ end
543
+ end
544
+
545
+ def provider_id
546
+ return team_id if self.provider.nil?
547
+ self.provider.provider_id
548
+ end
549
+ end
550
+ end
551
+ end
552
+ # rubocop:enable Metrics/ClassLength
553
+ end