fastlane 2.155.2 → 2.157.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +74 -74
- data/deliver/lib/deliver.rb +1 -0
- data/deliver/lib/deliver/app_screenshot_iterator.rb +95 -0
- data/deliver/lib/deliver/detect_values.rb +4 -1
- data/deliver/lib/deliver/languages.rb +7 -0
- data/deliver/lib/deliver/loader.rb +4 -5
- data/deliver/lib/deliver/queue_worker.rb +64 -0
- data/deliver/lib/deliver/runner.rb +7 -5
- data/deliver/lib/deliver/upload_screenshots.rb +143 -128
- data/fastlane/lib/fastlane/actions/app_store_connect_api_key.rb +120 -0
- data/fastlane/lib/fastlane/actions/commit_version_bump.rb +1 -1
- data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +2 -0
- data/fastlane/lib/fastlane/actions/docs/upload_to_testflight.md +17 -1
- data/fastlane/lib/fastlane/actions/set_changelog.rb +2 -2
- data/fastlane/lib/fastlane/actions/sonar.rb +5 -0
- data/fastlane/lib/fastlane/actions/spaceship_stats.rb +73 -0
- data/fastlane/lib/fastlane/actions/upload_to_testflight.rb +4 -0
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Deliverfile.swift +1 -1
- data/fastlane/swift/DeliverfileProtocol.swift +1 -1
- data/fastlane/swift/Fastlane.swift +67 -7
- data/fastlane/swift/Gymfile.swift +1 -1
- data/fastlane/swift/GymfileProtocol.swift +1 -1
- data/fastlane/swift/Matchfile.swift +1 -1
- data/fastlane/swift/MatchfileProtocol.swift +1 -1
- data/fastlane/swift/Precheckfile.swift +1 -1
- data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
- data/fastlane/swift/Scanfile.swift +1 -1
- data/fastlane/swift/ScanfileProtocol.swift +1 -1
- data/fastlane/swift/Screengrabfile.swift +1 -1
- data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
- data/fastlane/swift/Snapshotfile.swift +1 -1
- data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
- data/fastlane_core/lib/fastlane_core/command_executor.rb +1 -0
- data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +71 -42
- data/fastlane_core/lib/fastlane_core/project.rb +1 -0
- data/gym/lib/gym/error_handler.rb +1 -1
- data/gym/lib/gym/generators/build_command_generator.rb +0 -1
- data/pilot/lib/pilot/build_manager.rb +18 -4
- data/pilot/lib/pilot/manager.rb +16 -5
- data/pilot/lib/pilot/options.rb +16 -0
- data/produce/lib/produce/itunes_connect.rb +2 -2
- data/scan/lib/scan/test_command_generator.rb +3 -1
- data/screengrab/lib/screengrab/runner.rb +36 -17
- data/sigh/lib/sigh/runner.rb +6 -5
- data/snapshot/lib/snapshot/test_command_generator_base.rb +3 -1
- data/spaceship/lib/spaceship.rb +4 -0
- data/spaceship/lib/spaceship/client.rb +2 -0
- data/spaceship/lib/spaceship/connect_api.rb +0 -15
- data/spaceship/lib/spaceship/connect_api/api_client.rb +270 -0
- data/spaceship/lib/spaceship/connect_api/client.rb +144 -213
- data/spaceship/lib/spaceship/connect_api/models/profile.rb +3 -2
- data/spaceship/lib/spaceship/connect_api/provisioning/client.rb +8 -17
- data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +75 -64
- data/spaceship/lib/spaceship/connect_api/spaceship.rb +98 -0
- data/spaceship/lib/spaceship/connect_api/testflight/client.rb +8 -17
- data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +288 -277
- data/spaceship/lib/spaceship/connect_api/token.rb +46 -5
- data/spaceship/lib/spaceship/connect_api/token_refresh_middleware.rb +24 -0
- data/spaceship/lib/spaceship/connect_api/tunes/client.rb +8 -17
- data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +717 -706
- data/spaceship/lib/spaceship/connect_api/users/client.rb +8 -17
- data/spaceship/lib/spaceship/connect_api/users/users.rb +28 -17
- data/spaceship/lib/spaceship/stats_middleware.rb +65 -0
- metadata +25 -19
- data/sigh/lib/sigh/.module.rb.swp +0 -0
- data/sigh/lib/sigh/.options.rb.swp +0 -0
- data/sigh/lib/sigh/.runner.rb.swp +0 -0
@@ -1,245 +1,176 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative './
|
1
|
+
require_relative './token'
|
2
|
+
require_relative './provisioning/provisioning'
|
3
|
+
require_relative './testflight/testflight'
|
4
|
+
require_relative './tunes/tunes'
|
5
|
+
require_relative './users/users'
|
3
6
|
|
4
7
|
module Spaceship
|
5
8
|
class ConnectAPI
|
6
|
-
class Client
|
9
|
+
class Client
|
7
10
|
attr_accessor :token
|
11
|
+
attr_accessor :tunes_client
|
12
|
+
attr_accessor :portal_client
|
8
13
|
|
9
|
-
|
10
|
-
# @!group Client Init
|
11
|
-
#####################################################
|
12
|
-
|
13
|
-
# Instantiates a client with cookie session or a JWT token.
|
14
|
-
def initialize(cookie: nil, current_team_id: nil, token: nil)
|
15
|
-
if token.nil?
|
16
|
-
super(cookie: cookie, current_team_id: current_team_id, timeout: 1200)
|
17
|
-
else
|
18
|
-
options = {
|
19
|
-
request: {
|
20
|
-
timeout: (ENV["SPACESHIP_TIMEOUT"] || 300).to_i,
|
21
|
-
open_timeout: (ENV["SPACESHIP_TIMEOUT"] || 300).to_i
|
22
|
-
}
|
23
|
-
}
|
24
|
-
@token = token
|
25
|
-
@current_team_id = current_team_id
|
26
|
-
|
27
|
-
hostname = "https://api.appstoreconnect.apple.com/v1/"
|
28
|
-
|
29
|
-
@client = Faraday.new(hostname, options) do |c|
|
30
|
-
c.response(:json, content_type: /\bjson$/)
|
31
|
-
c.response(:plist, content_type: /\bplist$/)
|
32
|
-
c.use(FaradayMiddleware::RelsMiddleware)
|
33
|
-
c.adapter(Faraday.default_adapter)
|
34
|
-
c.headers["Authorization"] = "Bearer #{token.text}"
|
35
|
-
|
36
|
-
if ENV['SPACESHIP_DEBUG']
|
37
|
-
# for debugging only
|
38
|
-
# This enables tracking of networking requests using Charles Web Proxy
|
39
|
-
c.proxy = "https://127.0.0.1:8888"
|
40
|
-
c.ssl[:verify_mode] = OpenSSL::SSL::VERIFY_NONE
|
41
|
-
elsif ENV["SPACESHIP_PROXY"]
|
42
|
-
c.proxy = ENV["SPACESHIP_PROXY"]
|
43
|
-
c.ssl[:verify_mode] = OpenSSL::SSL::VERIFY_NONE if ENV["SPACESHIP_PROXY_SSL_VERIFY_NONE"]
|
44
|
-
end
|
45
|
-
|
46
|
-
if ENV["DEBUG"]
|
47
|
-
puts("To run spaceship through a local proxy, use SPACESHIP_DEBUG")
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.hostname
|
54
|
-
return nil
|
55
|
-
end
|
56
|
-
|
14
|
+
# Initializes client with Apple's App Store Connect JWT auth key.
|
57
15
|
#
|
58
|
-
#
|
16
|
+
# This method will automatically use the key id, issuer id, and filepath from environment
|
17
|
+
# variables if not given.
|
59
18
|
#
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
params[:limit] = limit if limit
|
73
|
-
params[:sort] = sort if sort
|
74
|
-
params[:cursor] = cursor if cursor
|
75
|
-
|
76
|
-
return params
|
19
|
+
# All three parameters are needed to authenticate.
|
20
|
+
#
|
21
|
+
# @param key_id (String) (optional): The key id
|
22
|
+
# @param issuer_id (String) (optional): The issuer id
|
23
|
+
# @param filepath (String) (optional): The filepath
|
24
|
+
#
|
25
|
+
# @raise InvalidUserCredentialsError: raised if authentication failed
|
26
|
+
#
|
27
|
+
# @return (Spaceship::ConnectAPI::Client) The client the login method was called for
|
28
|
+
def self.auth(key_id: nil, issuer_id: nil, filepath: nil)
|
29
|
+
token = Spaceship::ConnectAPI::Token.create(key_id: key_id, issuer_id: issuer_id, filepath: filepath)
|
30
|
+
return ConnectAPI::Client.new(token: token)
|
77
31
|
end
|
78
32
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
33
|
+
# Authenticates with Apple's web services. This method has to be called once
|
34
|
+
# to generate a valid session.
|
35
|
+
#
|
36
|
+
# This method will automatically use the username from the Appfile (if available)
|
37
|
+
# and fetch the password from the Keychain (if available)
|
38
|
+
#
|
39
|
+
# @param user (String) (optional): The username (usually the email address)
|
40
|
+
# @param password (String) (optional): The password
|
41
|
+
# @param use_portal (Boolean) (optional): Whether to log in to Spaceship::Portal or not
|
42
|
+
# @param use_tunes (Boolean) (optional): Whether to log in to Spaceship::Tunes or not
|
43
|
+
# @param portal_team_id (String) (optional): The Spaceship::Portal team id
|
44
|
+
# @param tunes_team_id (String) (optional): The Spaceship::Tunes team id
|
45
|
+
# @param team_name (String) (optional): The team name
|
46
|
+
#
|
47
|
+
# @raise InvalidUserCredentialsError: raised if authentication failed
|
48
|
+
#
|
49
|
+
# @return (Spaceship::ConnectAPI::Client) The client the login method was called for
|
50
|
+
def self.login(user = nil, password = nil, use_portal: true, use_tunes: true, portal_team_id: nil, tunes_team_id: nil, team_name: nil)
|
51
|
+
portal_client = PortalClient.login(user, password) if use_portal
|
52
|
+
tunes_client = TunesClient.login(user, password) if use_tunes
|
53
|
+
|
54
|
+
# The clients will automatically select the first team if none is given
|
55
|
+
if portal_client && (!portal_team_id.nil? || !team_name.nil?)
|
56
|
+
portal_client.select_team(team_id: portal_team_id, team_name: team_name)
|
87
57
|
end
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
def post(url_or_path, body, tries: 5)
|
92
|
-
response = with_asc_retry(tries) do
|
93
|
-
request(:post) do |req|
|
94
|
-
req.url(url_or_path)
|
95
|
-
req.body = body.to_json
|
96
|
-
req.headers['Content-Type'] = 'application/json'
|
97
|
-
end
|
58
|
+
if tunes_client && (!tunes_team_id.nil? || !team_name.nil?)
|
59
|
+
tunes_client.select_team(team_id: tunes_team_id, team_name: team_name)
|
98
60
|
end
|
99
|
-
|
61
|
+
|
62
|
+
return ConnectAPI::Client.new(tunes_client: tunes_client, portal_client: portal_client)
|
100
63
|
end
|
101
64
|
|
102
|
-
def
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
65
|
+
def initialize(cookie: nil, current_team_id: nil, token: nil, tunes_client: nil, portal_client: nil)
|
66
|
+
@token = token
|
67
|
+
|
68
|
+
# If using web session...
|
69
|
+
# Spaceship::Tunes is needed for TestFlight::API, Tunes::API, and Users::API
|
70
|
+
# Spaceship::Portal is needed for Provisioning::API
|
71
|
+
@tunes_client = tunes_client
|
72
|
+
@portal_client = portal_client
|
73
|
+
|
74
|
+
# Extending this instance to add API endpoints from these modules
|
75
|
+
# Each of these modules adds a new setter method for an instance
|
76
|
+
# of an ConnectAPI::APIClient
|
77
|
+
# These get set in set_indvidual_clients
|
78
|
+
self.extend(Spaceship::ConnectAPI::TestFlight::API)
|
79
|
+
self.extend(Spaceship::ConnectAPI::Tunes::API)
|
80
|
+
self.extend(Spaceship::ConnectAPI::Provisioning::API)
|
81
|
+
self.extend(Spaceship::ConnectAPI::Users::API)
|
82
|
+
|
83
|
+
set_indvidual_clients(
|
84
|
+
cookie: cookie,
|
85
|
+
current_team_id: current_team_id,
|
86
|
+
token: token,
|
87
|
+
tunes_client: @tunes_client,
|
88
|
+
portal_client: @portal_client
|
89
|
+
)
|
111
90
|
end
|
112
91
|
|
113
|
-
def
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
92
|
+
def in_house?
|
93
|
+
if token
|
94
|
+
if token.in_house.nil?
|
95
|
+
message = [
|
96
|
+
"Cannot determine if team is App Store or Enterprise via the App Store Connect API (yet)",
|
97
|
+
"Set 'in_house' on your Spaceship::ConnectAPI::Token",
|
98
|
+
"Or set 'in_house' in your App Store Connect API key JSON file",
|
99
|
+
"Or set the 'SPACESHIP_CONNECT_API_IN_HOUSE' environment variable to 'true'",
|
100
|
+
"View more info in the docs at https://docs.fastlane.tools/app-store-connect-api/"
|
101
|
+
]
|
102
|
+
raise message.join('\n')
|
121
103
|
end
|
104
|
+
return !!token.in_house
|
105
|
+
elsif @portal_client
|
106
|
+
return @portal_client.in_house?
|
107
|
+
else
|
108
|
+
raise "No App Store Connect API token or Portal Client set"
|
122
109
|
end
|
123
|
-
handle_response(response)
|
124
110
|
end
|
125
111
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
112
|
+
def select_team(portal_team_id: nil, tunes_team_id: nil, team_name: nil)
|
113
|
+
@portal_client.select_team(team_id: portal_team_id, team_name: team_name) unless @portal_client.nil?
|
114
|
+
@tunes_client.select_team(team_id: tunes_team_id, team_name: team_name) unless @tunes_client.nil?
|
115
|
+
|
116
|
+
# Updating the tunes and portal clients requires resetting
|
117
|
+
# of the clients in the API modules
|
118
|
+
set_indvidual_clients(
|
119
|
+
cookie: nil,
|
120
|
+
current_team_id: nil,
|
121
|
+
token: nil,
|
122
|
+
tunes_client: tunes_client,
|
123
|
+
portal_client: portal_client
|
124
|
+
)
|
125
|
+
end
|
131
126
|
|
132
|
-
|
127
|
+
private
|
133
128
|
|
134
|
-
|
135
|
-
|
136
|
-
|
129
|
+
def set_indvidual_clients(cookie: nil, current_team_id: nil, token: nil, tunes_client: nil, portal_client: nil)
|
130
|
+
# This was added by Spaceship::ConnectAPI::TestFlight::API and is required
|
131
|
+
# to be set for API methods to have a client to send request on
|
132
|
+
if cookie || token || tunes_client
|
133
|
+
self.test_flight_request_client = Spaceship::ConnectAPI::TestFlight::Client.new(
|
134
|
+
cookie: cookie,
|
135
|
+
current_team_id: current_team_id,
|
136
|
+
token: token,
|
137
|
+
another_client: tunes_client
|
138
|
+
)
|
137
139
|
end
|
138
140
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
141
|
+
# This was added by Spaceship::ConnectAPI::Tunes::API and is required
|
142
|
+
# to be set for API methods to have a client to send request on
|
143
|
+
if cookie || token || tunes_client
|
144
|
+
self.tunes_request_client = Spaceship::ConnectAPI::Tunes::Client.new(
|
145
|
+
cookie: cookie,
|
146
|
+
current_team_id: current_team_id,
|
147
|
+
token: token,
|
148
|
+
another_client: tunes_client
|
149
|
+
)
|
147
150
|
end
|
148
|
-
end
|
149
151
|
|
150
|
-
|
151
|
-
|
152
|
-
|
152
|
+
# This was added by Spaceship::ConnectAPI::Provisioning::API and is required
|
153
|
+
# to be set for API methods to have a client to send request on
|
154
|
+
if cookie || token || portal_client
|
155
|
+
self.provisioning_request_client = Spaceship::ConnectAPI::Provisioning::Client.new(
|
156
|
+
cookie: cookie,
|
157
|
+
current_team_id: current_team_id,
|
158
|
+
token: token,
|
159
|
+
another_client: portal_client
|
160
|
+
)
|
153
161
|
end
|
154
162
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
163
|
+
# This was added by Spaceship::ConnectAPI::Users::API and is required
|
164
|
+
# to be set for API methods to have a client to send request on
|
165
|
+
if cookie || token || tunes_client
|
166
|
+
self.users_request_client = Spaceship::ConnectAPI::Users::Client.new(
|
167
|
+
cookie: cookie,
|
168
|
+
current_team_id: current_team_id,
|
169
|
+
token: token,
|
170
|
+
another_client: tunes_client
|
171
|
+
)
|
159
172
|
end
|
160
|
-
|
161
|
-
raise UnexpectedResponse, response.body['error'] if response.body['error']
|
162
|
-
|
163
|
-
raise UnexpectedResponse, handle_errors(response) if response.body['errors']
|
164
|
-
|
165
|
-
raise UnexpectedResponse, "Temporary App Store Connect error: #{response.body}" if response.body['statusCode'] == 'ERROR'
|
166
|
-
|
167
|
-
store_csrf_tokens(response)
|
168
|
-
|
169
|
-
return Spaceship::ConnectAPI::Response.new(body: response.body, status: response.status, client: self)
|
170
|
-
end
|
171
|
-
|
172
|
-
def handle_errors(response)
|
173
|
-
# Example error format
|
174
|
-
# {
|
175
|
-
# "errors":[
|
176
|
-
# {
|
177
|
-
# "id":"cbfd8674-4802-4857-bfe8-444e1ea36e32",
|
178
|
-
# "status":"409",
|
179
|
-
# "code":"STATE_ERROR",
|
180
|
-
# "title":"The request cannot be fulfilled because of the state of another resource.",
|
181
|
-
# "detail":"Submit for review errors found.",
|
182
|
-
# "meta":{
|
183
|
-
# "associatedErrors":{
|
184
|
-
# "/v1/appScreenshots/":[
|
185
|
-
# {
|
186
|
-
# "id":"23d1734f-b81f-411a-98e4-6d3e763d54ed",
|
187
|
-
# "status":"409",
|
188
|
-
# "code":"STATE_ERROR.SCREENSHOT_REQUIRED.APP_WATCH_SERIES_4",
|
189
|
-
# "title":"App screenshot missing (APP_WATCH_SERIES_4)."
|
190
|
-
# },
|
191
|
-
# {
|
192
|
-
# "id":"db993030-0a93-48e9-9fd7-7e5676633431",
|
193
|
-
# "status":"409",
|
194
|
-
# "code":"STATE_ERROR.SCREENSHOT_REQUIRED.APP_WATCH_SERIES_4",
|
195
|
-
# "title":"App screenshot missing (APP_WATCH_SERIES_4)."
|
196
|
-
# }
|
197
|
-
# ],
|
198
|
-
# "/v1/builds/d710b6fa-5235-4fe4-b791-2b80d6818db0":[
|
199
|
-
# {
|
200
|
-
# "id":"e421fe6f-0e3b-464b-89dc-ba437e7bb77d",
|
201
|
-
# "status":"409",
|
202
|
-
# "code":"ENTITY_ERROR.ATTRIBUTE.REQUIRED",
|
203
|
-
# "title":"The provided entity is missing a required attribute",
|
204
|
-
# "detail":"You must provide a value for the attribute 'usesNonExemptEncryption' with this request",
|
205
|
-
# "source":{
|
206
|
-
# "pointer":"/data/attributes/usesNonExemptEncryption"
|
207
|
-
# }
|
208
|
-
# }
|
209
|
-
# ]
|
210
|
-
# }
|
211
|
-
# }
|
212
|
-
# }
|
213
|
-
# ]
|
214
|
-
# }
|
215
|
-
|
216
|
-
return response.body['errors'].map do |error|
|
217
|
-
messages = [[error['title'], error['detail']].compact.join(" - ")]
|
218
|
-
|
219
|
-
meta = error["meta"] || {}
|
220
|
-
associated_errors = meta["associatedErrors"] || {}
|
221
|
-
|
222
|
-
messages + associated_errors.values.flatten.map do |associated_error|
|
223
|
-
[[associated_error["title"], associated_error["detail"]].compact.join(" - ")]
|
224
|
-
end
|
225
|
-
end.flatten.join("\n")
|
226
|
-
end
|
227
|
-
|
228
|
-
private
|
229
|
-
|
230
|
-
def local_variable_get(binding, name)
|
231
|
-
if binding.respond_to?(:local_variable_get)
|
232
|
-
binding.local_variable_get(name)
|
233
|
-
else
|
234
|
-
binding.eval(name.to_s)
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
def provider_id
|
239
|
-
return team_id if self.provider.nil?
|
240
|
-
self.provider.provider_id
|
241
173
|
end
|
242
174
|
end
|
243
175
|
end
|
244
|
-
# rubocop:enable Metrics/ClassLength
|
245
176
|
end
|
@@ -69,14 +69,15 @@ module Spaceship
|
|
69
69
|
return resps.flat_map(&:to_models)
|
70
70
|
end
|
71
71
|
|
72
|
-
def self.create(name: nil, profile_type: nil, bundle_id_id: nil, certificate_ids: nil, device_ids: nil)
|
72
|
+
def self.create(name: nil, profile_type: nil, bundle_id_id: nil, certificate_ids: nil, device_ids: nil, template_name: nil)
|
73
73
|
resp = Spaceship::ConnectAPI.post_profiles(
|
74
74
|
bundle_id_id: bundle_id_id,
|
75
75
|
certificates: certificate_ids,
|
76
76
|
devices: device_ids,
|
77
77
|
attributes: {
|
78
78
|
name: name,
|
79
|
-
profileType: profile_type
|
79
|
+
profileType: profile_type,
|
80
|
+
templateName: template_name
|
80
81
|
}
|
81
82
|
)
|
82
83
|
return resp.to_models.first
|
@@ -1,27 +1,18 @@
|
|
1
|
-
require_relative '../
|
1
|
+
require_relative '../api_client'
|
2
|
+
require_relative './provisioning'
|
2
3
|
require_relative '../../portal/portal_client'
|
3
4
|
|
4
5
|
module Spaceship
|
5
6
|
class ConnectAPI
|
6
7
|
module Provisioning
|
7
|
-
class Client < Spaceship::ConnectAPI::
|
8
|
-
def
|
9
|
-
|
10
|
-
if Spaceship::ConnectAPI.token
|
11
|
-
if @client.nil? || @client.token != Spaceship::ConnectAPI.token
|
12
|
-
@client = Spaceship::ConnectAPI::Provisioning::Client.new(token: Spaceship::ConnectAPI.token)
|
13
|
-
end
|
14
|
-
elsif Spaceship::Portal.client
|
15
|
-
# Initialize new client if new or if team changed
|
16
|
-
if @client.nil? || @client.team_id != Spaceship::Portal.client.team_id
|
17
|
-
@client = Spaceship::ConnectAPI::Provisioning::Client.client_with_authorization_from(Spaceship::Portal.client)
|
18
|
-
end
|
19
|
-
end
|
8
|
+
class Client < Spaceship::ConnectAPI::APIClient
|
9
|
+
def initialize(cookie: nil, current_team_id: nil, token: nil, another_client: nil)
|
10
|
+
another_client ||= Spaceship::Portal.client if cookie.nil? && token.nil?
|
20
11
|
|
21
|
-
|
22
|
-
raise "Please login using `Spaceship::Portal.login('user', 'password')`" unless @client
|
12
|
+
super(cookie: cookie, current_team_id: current_team_id, token: token, another_client: another_client)
|
23
13
|
|
24
|
-
|
14
|
+
self.extend(Spaceship::ConnectAPI::Provisioning::API)
|
15
|
+
self.provisioning_request_client = self
|
25
16
|
end
|
26
17
|
|
27
18
|
def self.hostname
|
@@ -3,86 +3,97 @@ require 'spaceship/connect_api/provisioning/client'
|
|
3
3
|
module Spaceship
|
4
4
|
class ConnectAPI
|
5
5
|
module Provisioning
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
module API
|
7
|
+
def provisioning_request_client=(provisioning_request_client)
|
8
|
+
@provisioning_request_client = provisioning_request_client
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
def provisioning_request_client
|
12
|
+
return @provisioning_request_client if @provisioning_request_client
|
13
|
+
raise TypeError, "You need to instantiate this module with provisioning_request_client"
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
16
|
+
#
|
17
|
+
# bundleIds
|
18
|
+
#
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
def get_bundle_ids(filter: {}, includes: nil, limit: nil, sort: nil)
|
21
|
+
params = provisioning_request_client.build_params(filter: filter, includes: includes, limit: limit, sort: sort)
|
22
|
+
provisioning_request_client.get("bundleIds", params)
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
def get_bundle_id(bundle_id_id: {}, includes: nil)
|
26
|
+
params = provisioning_request_client.build_params(filter: nil, includes: includes, limit: nil, sort: nil)
|
27
|
+
provisioning_request_client.get("bundleIds/#{bundle_id_id}", params)
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
#
|
31
|
+
# certificates
|
32
|
+
#
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
def get_certificates(filter: {}, includes: nil, limit: nil, sort: nil)
|
35
|
+
params = provisioning_request_client.build_params(filter: filter, includes: includes, limit: limit, sort: sort)
|
36
|
+
provisioning_request_client.get("certificates", params)
|
37
|
+
end
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
39
|
+
#
|
40
|
+
# devices
|
41
|
+
#
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
def get_devices(filter: {}, includes: nil, limit: nil, sort: nil)
|
44
|
+
params = provisioning_request_client.build_params(filter: filter, includes: includes, limit: limit, sort: sort)
|
45
|
+
provisioning_request_client.get("devices", params)
|
46
|
+
end
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
},
|
67
|
-
devices: {
|
68
|
-
data: (devices || []).map do |device|
|
69
|
-
{
|
70
|
-
type: "devices",
|
71
|
-
id: device
|
48
|
+
#
|
49
|
+
# profiles
|
50
|
+
#
|
51
|
+
|
52
|
+
def get_profiles(filter: {}, includes: nil, limit: nil, sort: nil)
|
53
|
+
params = provisioning_request_client.build_params(filter: filter, includes: includes, limit: limit, sort: sort)
|
54
|
+
provisioning_request_client.get("profiles", params)
|
55
|
+
end
|
56
|
+
|
57
|
+
def post_profiles(bundle_id_id: nil, certificates: nil, devices: nil, attributes: {})
|
58
|
+
body = {
|
59
|
+
data: {
|
60
|
+
attributes: attributes,
|
61
|
+
type: "profiles",
|
62
|
+
relationships: {
|
63
|
+
bundleId: {
|
64
|
+
data: {
|
65
|
+
type: "bundleIds",
|
66
|
+
id: bundle_id_id
|
72
67
|
}
|
73
|
-
|
68
|
+
},
|
69
|
+
certificates: {
|
70
|
+
data: certificates.map do |certificate|
|
71
|
+
{
|
72
|
+
type: "certificates",
|
73
|
+
id: certificate
|
74
|
+
}
|
75
|
+
end
|
76
|
+
},
|
77
|
+
devices: {
|
78
|
+
data: (devices || []).map do |device|
|
79
|
+
{
|
80
|
+
type: "devices",
|
81
|
+
id: device
|
82
|
+
}
|
83
|
+
end
|
84
|
+
}
|
74
85
|
}
|
75
86
|
}
|
76
87
|
}
|
77
|
-
}
|
78
88
|
|
79
|
-
|
80
|
-
|
89
|
+
provisioning_request_client.post("profiles", body)
|
90
|
+
end
|
81
91
|
|
82
|
-
|
83
|
-
|
92
|
+
def delete_profile(profile_id: nil)
|
93
|
+
raise "Profile id is nil" if profile_id.nil?
|
84
94
|
|
85
|
-
|
95
|
+
provisioning_request_client.delete("profiles/#{profile_id}")
|
96
|
+
end
|
86
97
|
end
|
87
98
|
end
|
88
99
|
end
|