spaceship 0.1.2 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5874fb36abe1aa100b7c5b793a291699ca11568d
4
- data.tar.gz: 43449a997428f3e6bddc8eda4e67f94e50781354
3
+ metadata.gz: 904794a304cacd104b57a5dfdc757a9daaa73154
4
+ data.tar.gz: c73073f31e7b3d3b7385fc1e864cf9944ef55583
5
5
  SHA512:
6
- metadata.gz: 7aec5cec146a3ee90077d67a2c0efba4c3ae03a6d9000f0aa36bbf7a763cc02f33f821257d782d83751ec1150050690b21aa98d2d235ee002e177ec1873b97b8
7
- data.tar.gz: 7f54d76361cc18e52b826fdd40f1542c5623823b83dddb7321d140b5d63d59caf3c5aa119ddc90b81e12f413ef09036dfa901b97882d217376fd0a8a401b6688
6
+ metadata.gz: da46f269738c9ed37cf56fa1c4c5ae8ba491eb9c3eedef6c59415d492b0defb7819df981091666cadd328d84aea67bccb8c6a21d7104e17a1c2395aa000ad6fb
7
+ data.tar.gz: a8e15b850a1fca1cdbb565a988b51bf9fbb503ed9d6fc911bd4f09032f234971d1cc4513b82b3ee2d845bd5d68f1e3e3a310dad05d6e8b0f8f3dd8169b9f7661
@@ -162,6 +162,8 @@ module Spaceship
162
162
  Tunes::BuildTrain.all(self, self.apple_id)
163
163
  end
164
164
 
165
+ # @return [Array] A list of all pre-processing builds
166
+ # These are all build that have no information except the upload date
165
167
  def pre_processing_builds
166
168
  data = client.build_trains(apple_id) # we need to fetch all trains here to get the builds
167
169
 
@@ -171,6 +173,33 @@ module Spaceship
171
173
  end
172
174
  end
173
175
 
176
+ # @return [Array] This will return an array of *all* processing builds
177
+ # this include pre-processing or standard processing
178
+ def all_processing_builds
179
+ builds = self.pre_processing_builds
180
+
181
+ self.build_trains.each do |version_number, train|
182
+ train.processing_builds.each do |build|
183
+ builds << build
184
+ end
185
+ end
186
+
187
+ return builds
188
+ end
189
+
190
+ # Get all builds that are already processed for all build trains
191
+ # You can either use the return value (array) or pass a block
192
+ def builds
193
+ all_builds = []
194
+ self.build_trains.each do |version_number, train|
195
+ train.builds.each do |build|
196
+ yield(build) if block_given?
197
+ all_builds << build unless block_given?
198
+ end
199
+ end
200
+ all_builds
201
+ end
202
+
174
203
  #####################################################
175
204
  # @!group Submit for Review
176
205
  #####################################################
@@ -184,6 +213,18 @@ module Spaceship
184
213
  Spaceship::AppSubmission.create(self, self.apple_id, version)
185
214
  end
186
215
 
216
+ # Cancels all ongoing TestFlight beta submission for this application
217
+ def cancel_all_testflight_submissions!
218
+ self.builds do |build|
219
+ begin
220
+ build.cancel_beta_review!
221
+ rescue => ex
222
+ # We really don't care about any errors here
223
+ end
224
+ end
225
+ true
226
+ end
227
+
187
228
  #####################################################
188
229
  # @!group General
189
230
  #####################################################
@@ -7,7 +7,7 @@ module Spaceship
7
7
  # @!group General metadata
8
8
  #####################################################
9
9
 
10
- # @return (Spaceship::Tunes::Application) A reference to the build train this build is contained in
10
+ # @return (Spaceship::Tunes::BuildTrain) A reference to the build train this build is contained in
11
11
  attr_accessor :build_train
12
12
 
13
13
  # @return (Integer) The ID generated by iTunes Connect
@@ -16,7 +16,7 @@ module Spaceship
16
16
  # @return (Boolean)
17
17
  attr_accessor :valid
18
18
 
19
- # @return (String) The build version (not the version number)
19
+ # @return (String) The build version (not the version number), but also is named `build number`
20
20
  attr_accessor :build_version
21
21
 
22
22
  # @return (String) The version number (e.g. 1.3)
@@ -28,7 +28,7 @@ module Spaceship
28
28
  # @return (String) URL to the app icon of this build (150x150px)
29
29
  attr_accessor :icon_url
30
30
 
31
- # @return (String)
31
+ # @return (String) The name of the app this build is for
32
32
  attr_accessor :app_name
33
33
 
34
34
  # @return (String) The platform of this build (e.g. 'ios')
@@ -104,6 +104,65 @@ module Spaceship
104
104
 
105
105
  @external_testing_enabled = (self.external_expiry_date || 0) > 0
106
106
  end
107
+
108
+ # This will submit this build for TestFlight beta review
109
+ # @param metadata [Hash] A hash containing the following information (keys must be symbols):
110
+ # {
111
+ # # Required Metadata:
112
+ # changelog: "Changelog",
113
+ # description: "Your Description",
114
+ # feedback_email: "Email Address for Feedback",
115
+ # marketing_url: "https://marketing.com",
116
+ # first_name: "Felix",
117
+ # last_name: "Krause",
118
+ # review_email: "Contact email address for Apple",
119
+ # phone_number: "0128383383",
120
+ #
121
+ # # Optional Metadata:
122
+ # privacy_policy_url: nil,
123
+ # review_notes: nil,
124
+ # review_user_name: nil,
125
+ # review_password: nil,
126
+ # encryption: false
127
+ # }
128
+ def submit_for_beta_review!(metadata)
129
+ # First, enable beta testing for this train (per iTC requirement)
130
+ self.build_train.update_testing_status!(true)
131
+
132
+ parameters = {
133
+ app_id: self.build_train.application.apple_id,
134
+ train: self.build_train.version_string,
135
+ build_number: self.build_version,
136
+
137
+ # Required Metadata:
138
+ changelog: "No changelog provided",
139
+ description: "No app description provided",
140
+ feedback_email: "contact@company.com",
141
+ marketing_url: "http://marketing.com",
142
+ first_name: "Felix",
143
+ last_name: "Krause",
144
+ review_email: "contact@company.com",
145
+ phone_number: "0123456789",
146
+
147
+ # Optional Metadata:
148
+ privacy_policy_url: nil,
149
+ review_notes: nil,
150
+ review_user_name: nil,
151
+ review_password: nil,
152
+ encryption: false
153
+ }.merge(metadata)
154
+
155
+ client.submit_testflight_build_for_review!(parameters)
156
+
157
+ return parameters
158
+ end
159
+
160
+ # This will cancel the review process for this TestFlight build
161
+ def cancel_beta_review!
162
+ client.remove_testflight_build_from_review!(app_id: self.build_train.application.apple_id,
163
+ train: self.build_train.version_string,
164
+ build_number: self.build_version)
165
+ end
107
166
  end
108
167
  end
109
168
  end
@@ -32,12 +32,31 @@ module Spaceship
32
32
  # }]
33
33
  attr_accessor :devices
34
34
 
35
+
36
+ # Information about the most recent beta install
37
+ # @return [Integer] The ID of the most recently installed app
38
+ attr_accessor :latest_install_app_id
39
+
40
+ # @return [Integer] Date of the last install of this tester
41
+ # Number of seconds since 1970
42
+ attr_accessor :latest_install_date
43
+
44
+ # @return [Integer] The build number of the last installed build
45
+ attr_accessor :latest_installed_build_number
46
+
47
+ # @return [Integer] The version number of the last installed build
48
+ attr_accessor :latest_installed_version_number
49
+
35
50
  attr_mapping(
36
51
  'testerId' => :tester_id,
37
52
  'emailAddress.value' => :email,
38
53
  'firstName.value' => :first_name,
39
54
  'lastName.value' => :last_name,
40
- 'devices' => :devices
55
+ 'devices' => :devices,
56
+ 'latestInstalledAppAdamId' => :latest_install_app_id,
57
+ 'latestInstalledDate' => :latest_install_date,
58
+ 'latestInstalledVersion' => :latest_installed_version_number,
59
+ 'latestInstalledShortVersion' => :latest_installed_build_number,
41
60
  )
42
61
 
43
62
  class << self
@@ -1,6 +1,10 @@
1
1
  module Spaceship
2
2
  class TunesClient < Spaceship::Client
3
3
 
4
+ # ITunesConnectError is only thrown when iTunes Connect raises an exception
5
+ class ITunesConnectError < StandardError
6
+ end
7
+
4
8
  #####################################################
5
9
  # @!group Init and Login
6
10
  #####################################################
@@ -65,9 +69,11 @@ module Spaceship
65
69
  end
66
70
  end
67
71
 
68
- def handle_itc_response(data)
69
- return unless data
70
- return unless data.kind_of?Hash
72
+ def handle_itc_response(raw)
73
+ return unless raw
74
+ return unless raw.kind_of?Hash
75
+
76
+ data = raw['data'] || raw # sometimes it's with data, sometimes it isn't
71
77
 
72
78
  if data.fetch('sectionErrorKeys', []).count == 0 and
73
79
  data.fetch('sectionInfoKeys', []).count == 0 and
@@ -100,10 +106,13 @@ module Spaceship
100
106
  errors = errors + data.fetch('sectionErrorKeys') if data['sectionErrorKeys']
101
107
 
102
108
  # Sometimes there is a different kind of error in the JSON response
103
- different_error = data.fetch('messages', {}).fetch('error', nil)
109
+ # e.g. {"warn"=>nil, "error"=>["operation_failed"], "info"=>nil}
110
+ different_error = raw.fetch('messages', {}).fetch('error', nil)
104
111
  errors << different_error if different_error
105
112
 
106
- raise errors.join(' ') if errors.count > 0 # they are separated by `.` by default
113
+ if errors.count > 0 # they are separated by `.` by default
114
+ raise ITunesConnectError.new(errors.join(' '))
115
+ end
107
116
 
108
117
  puts data['sectionInfoKeys'] if data['sectionInfoKeys']
109
118
  puts data['sectionWarningKeys'] if data['sectionWarningKeys']
@@ -194,7 +203,7 @@ module Spaceship
194
203
  req.headers['Content-Type'] = 'application/json'
195
204
  end
196
205
 
197
- handle_itc_response(r.body['data'])
206
+ handle_itc_response(r.body)
198
207
  end
199
208
 
200
209
  #####################################################
@@ -217,7 +226,88 @@ module Spaceship
217
226
  req.headers['Content-Type'] = 'application/json'
218
227
  end
219
228
 
220
- handle_itc_response(r.body['data'])
229
+ handle_itc_response(r.body)
230
+ end
231
+
232
+ def remove_testflight_build_from_review!(app_id: nil, train: nil, build_number: nil)
233
+ r = request(:post) do |req|
234
+ req.url "ra/apps/#{app_id}/trains/#{train}/builds/#{build_number}/reject"
235
+ req.body = {}.to_json
236
+ req.headers['Content-Type'] = 'application/json'
237
+ end
238
+ handle_itc_response(r.body)
239
+ end
240
+
241
+ def submit_testflight_build_for_review!(# Required:
242
+ app_id: nil,
243
+ train: nil,
244
+ build_number: nil,
245
+ cancel_other_submissions: false,
246
+
247
+ # Required Metadata:
248
+ changelog: nil,
249
+ description: nil,
250
+ feedback_email: nil,
251
+ marketing_url: nil,
252
+ first_name: nil,
253
+ last_name: nil,
254
+ review_email: nil,
255
+ phone_number: nil,
256
+
257
+ # Optional Metadata:
258
+ privacy_policy_url: nil,
259
+ review_notes: nil,
260
+ review_user_name: nil,
261
+ review_password: nil,
262
+ encryption: false)
263
+
264
+ start_url = "ra/apps/#{app_id}/trains/#{train}/builds/#{build_number}/submit/start"
265
+ r = request(:get) do |req|
266
+ req.url start_url
267
+ req.headers['Content-Type'] = 'application/json'
268
+ end
269
+ handle_itc_response(r.body)
270
+
271
+ build_info = r.body['data']
272
+ # Now fill in the values provided by the user
273
+
274
+ # First the localised values:
275
+ build_info['testInfo']['details'].each do |current|
276
+ current['whatsNew']['value'] = changelog
277
+ current['description']['value'] = description
278
+ current['feedbackEmail']['value'] = feedback_email
279
+ current['marketingUrl']['value'] = marketing_url
280
+ current['privacyPolicyUrl']['value'] = privacy_policy_url
281
+ current["pageLanguageValue"] = current['language'] # could iTunes Connect be any more buggy? This is required for some reason
282
+ end
283
+ build_info['testInfo']['reviewFirstName']['value'] = first_name
284
+ build_info['testInfo']['reviewLastName']['value'] = last_name
285
+ build_info['testInfo']['reviewPhone']['value'] = phone_number
286
+ build_info['testInfo']['reviewEmail']['value'] = review_email
287
+ build_info['testInfo']['reviewUserName']['value'] = review_user_name
288
+ build_info['testInfo']['reviewPassword']['value'] = review_password
289
+
290
+ r = request(:post) do |req| # same URL, but a POST request
291
+ req.url start_url
292
+ req.body = build_info.to_json
293
+ req.headers['Content-Type'] = 'application/json'
294
+ end
295
+ handle_itc_response(r.body)
296
+
297
+ encryption_info = r.body['data']
298
+ if encryption_info['exportComplianceRequired']
299
+ # only sometimes this is required
300
+
301
+ encryption_info['usesEncryption']['value'] = encryption
302
+
303
+ r = request(:post) do |req|
304
+ req.url "ra/apps/#{app_id}/trains/#{train}/builds/#{build_number}/submit/complete"
305
+ req.body = encryption_info.to_json
306
+ req.headers['Content-Type'] = 'application/json'
307
+ end
308
+
309
+ handle_itc_response(r.body)
310
+ end
221
311
  end
222
312
 
223
313
  #####################################################
@@ -233,7 +323,7 @@ module Spaceship
233
323
  req.headers['Content-Type'] = 'application/json'
234
324
  end
235
325
 
236
- handle_itc_response(r.body['data'])
326
+ handle_itc_response(r.body)
237
327
  parse_response(r, 'data')
238
328
  end
239
329
 
@@ -310,7 +400,8 @@ module Spaceship
310
400
  },
311
401
  testing: {
312
402
  value: false
313
- },
403
+ },
404
+ userName: tester.email,
314
405
  testerId: tester.tester_id
315
406
  }
316
407
  ]
@@ -1,3 +1,3 @@
1
1
  module Spaceship
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spaceship
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Natchev
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-07-18 00:00:00.000000000 Z
12
+ date: 2015-07-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: credentials_manager