spaceship 0.19.4 → 0.20.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/README.md +1 -1
- data/lib/spaceship/client.rb +3 -3
- data/lib/spaceship/portal/portal_client.rb +16 -23
- data/lib/spaceship/tunes/build.rb +6 -4
- data/lib/spaceship/tunes/build_train.rb +25 -12
- data/lib/spaceship/tunes/tunes_client.rb +26 -22
- data/lib/spaceship/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13327e628a59af20edccc21b45b712a7369ba849
|
4
|
+
data.tar.gz: 899347df5eed63a08ab77a14f5bce260857260df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 66ca044745dff1f1e44d41e67fa149c407b95a1796391aa24bf07864d682815d35273813076d50895e196b5ac45ef7a3a624d02aea71e46fb3bf3bfcfa6f961b
|
7
|
+
data.tar.gz: c463fc2b1d2a5bf1adb4079d36815ebdd31e476429ab00774ec86f96517e22c2dee498e5142528ed2bc91ff0a196ef6f14fbd9c8183d0a9a92da00cbf18e9532
|
data/README.md
CHANGED
@@ -118,7 +118,7 @@ Most [fastlane tools](https://fastlane.tools) already use `spaceship`, like `sig
|
|
118
118
|
|
119
119
|
The detailed documentation of all available classes is available on [RubyDoc](http://www.rubydoc.info/github/fastlane/spaceship/frames).
|
120
120
|
|
121
|
-
You can find the log file here `/tmp/spaceship[time].log`.
|
121
|
+
You can find the log file here `/tmp/spaceship[time]_[pid].log`.
|
122
122
|
|
123
123
|
# Technical Details
|
124
124
|
|
data/lib/spaceship/client.rb
CHANGED
@@ -25,7 +25,7 @@ module Spaceship
|
|
25
25
|
attr_accessor :user
|
26
26
|
|
27
27
|
# The logger in which all requests are logged
|
28
|
-
# /tmp/spaceship[time].log by default
|
28
|
+
# /tmp/spaceship[time]_[pid].log by default
|
29
29
|
attr_accessor :logger
|
30
30
|
|
31
31
|
# Invalid user credentials were provided
|
@@ -84,14 +84,14 @@ module Spaceship
|
|
84
84
|
end
|
85
85
|
|
86
86
|
# The logger in which all requests are logged
|
87
|
-
# /tmp/spaceship[time].log by default
|
87
|
+
# /tmp/spaceship[time]_[pid].log by default
|
88
88
|
def logger
|
89
89
|
unless @logger
|
90
90
|
if ENV["VERBOSE"]
|
91
91
|
@logger = Logger.new(STDOUT)
|
92
92
|
else
|
93
93
|
# Log to file by default
|
94
|
-
path = "/tmp/spaceship#{Time.now.to_i}.log"
|
94
|
+
path = "/tmp/spaceship#{Time.now.to_i}_#{Process.pid}.log"
|
95
95
|
@logger = Logger.new(path)
|
96
96
|
end
|
97
97
|
|
@@ -10,7 +10,7 @@ module Spaceship
|
|
10
10
|
|
11
11
|
# Fetches the latest API Key from the Apple Dev Portal
|
12
12
|
def api_key
|
13
|
-
cache_path = "/
|
13
|
+
cache_path = File.expand_path("~/Library/Caches/spaceship_api_key.txt")
|
14
14
|
begin
|
15
15
|
cached = File.read(cache_path)
|
16
16
|
rescue Errno::ENOENT
|
@@ -23,6 +23,7 @@ module Spaceship
|
|
23
23
|
results = headers['location'].match(/.*appIdKey=(\h+)/)
|
24
24
|
if (results || []).length > 1
|
25
25
|
api_key = results[1]
|
26
|
+
FileUtils.mkdir_p(File.dirname(cache_path))
|
26
27
|
File.write(cache_path, api_key) if api_key.length == 64
|
27
28
|
return api_key
|
28
29
|
else
|
@@ -177,11 +178,7 @@ module Spaceship
|
|
177
178
|
|
178
179
|
params.merge!(ident_params)
|
179
180
|
|
180
|
-
|
181
|
-
# If we directly create a new app without querying anything before
|
182
|
-
# we don't have a valid csrf token, that's why we have to do at least one request
|
183
|
-
apps
|
184
|
-
end
|
181
|
+
ensure_csrf
|
185
182
|
|
186
183
|
r = request(:post, "account/#{platform_slug(mac)}/identifiers/addAppId.action", params)
|
187
184
|
parse_response(r, 'appId')
|
@@ -288,11 +285,7 @@ module Spaceship
|
|
288
285
|
end
|
289
286
|
|
290
287
|
def create_certificate!(type, csr, app_id = nil)
|
291
|
-
|
292
|
-
# If we directly create a new certificate without querying anything before
|
293
|
-
# we don't have a valid csrf token, that's why we have to do at least one request
|
294
|
-
certificates([Certificate::CERTIFICATE_TYPE_IDS.keys.first])
|
295
|
-
end
|
288
|
+
ensure_csrf
|
296
289
|
|
297
290
|
r = request(:post, 'account/ios/certificate/submitCertificateRequest.action', {
|
298
291
|
teamId: team_id,
|
@@ -346,11 +339,7 @@ module Spaceship
|
|
346
339
|
end
|
347
340
|
|
348
341
|
def create_provisioning_profile!(name, distribution_method, app_id, certificate_ids, device_ids, mac: false)
|
349
|
-
|
350
|
-
# If we directly create a new profile without querying anything before
|
351
|
-
# we don't have a valid csrf token, that's why we have to do at least one request
|
352
|
-
provisioning_profiles
|
353
|
-
end
|
342
|
+
ensure_csrf
|
354
343
|
|
355
344
|
r = request(:post, "account/#{platform_slug(mac)}/profile/createProvisioningProfile.action", {
|
356
345
|
teamId: team_id,
|
@@ -377,13 +366,7 @@ module Spaceship
|
|
377
366
|
end
|
378
367
|
|
379
368
|
def delete_provisioning_profile!(profile_id, mac: false)
|
380
|
-
|
381
|
-
r = request(:post, "account/#{platform_slug(mac)}/profile/getProvisioningProfile.action", {
|
382
|
-
teamId: team_id,
|
383
|
-
provisioningProfileId: profile_id
|
384
|
-
})
|
385
|
-
parse_response(r)
|
386
|
-
end
|
369
|
+
ensure_csrf
|
387
370
|
|
388
371
|
r = request(:post, "account/#{platform_slug(mac)}/profile/deleteProvisioningProfile.action", {
|
389
372
|
teamId: team_id,
|
@@ -405,5 +388,15 @@ module Spaceship
|
|
405
388
|
|
406
389
|
parse_response(r, 'provisioningProfile')
|
407
390
|
end
|
391
|
+
|
392
|
+
private
|
393
|
+
|
394
|
+
def ensure_csrf
|
395
|
+
if csrf_tokens.count == 0
|
396
|
+
# If we directly create a new resource (e.g. app) without querying anything before
|
397
|
+
# we don't have a valid csrf token, that's why we have to do at least one request
|
398
|
+
apps
|
399
|
+
end
|
400
|
+
end
|
408
401
|
end
|
409
402
|
end
|
@@ -149,13 +149,11 @@ module Spaceship
|
|
149
149
|
# encryption: false
|
150
150
|
# }
|
151
151
|
def submit_for_beta_review!(metadata)
|
152
|
-
# First, enable beta testing for this train (per iTC requirement)
|
153
|
-
self.build_train.update_testing_status!(true, 'external')
|
154
|
-
|
155
152
|
parameters = {
|
156
153
|
app_id: self.build_train.application.apple_id,
|
157
154
|
train: self.build_train.version_string,
|
158
155
|
build_number: self.build_version,
|
156
|
+
platform: self.platform,
|
159
157
|
|
160
158
|
# Required Metadata:
|
161
159
|
changelog: "No changelog provided",
|
@@ -177,6 +175,9 @@ module Spaceship
|
|
177
175
|
|
178
176
|
client.submit_testflight_build_for_review!(parameters)
|
179
177
|
|
178
|
+
# Last, enable beta testing for this train (per iTC requirement). This will fail until the app has been approved for beta testing
|
179
|
+
self.build_train.update_testing_status!(true, 'external', self)
|
180
|
+
|
180
181
|
return parameters
|
181
182
|
end
|
182
183
|
|
@@ -200,7 +201,8 @@ module Spaceship
|
|
200
201
|
def cancel_beta_review!
|
201
202
|
client.remove_testflight_build_from_review!(app_id: self.build_train.application.apple_id,
|
202
203
|
train: self.build_train.version_string,
|
203
|
-
build_number: self.build_version
|
204
|
+
build_number: self.build_version,
|
205
|
+
platform: self.platform)
|
204
206
|
end
|
205
207
|
end
|
206
208
|
end
|
@@ -87,18 +87,31 @@ module Spaceship
|
|
87
87
|
data = client.build_trains(self.application.apple_id, testing_type)
|
88
88
|
|
89
89
|
build ||= latest_build if testing_type == 'external'
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
90
|
+
testing_key = "#{testing_type}Testing"
|
91
|
+
|
92
|
+
# Delete the irrelevant trains and update the relevant one to enable testing
|
93
|
+
data['trains'].delete_if do |train|
|
94
|
+
if train['versionString'] != version_string
|
95
|
+
true
|
96
|
+
else
|
97
|
+
train[testing_key]['value'] = new_value
|
98
|
+
|
99
|
+
# also update the builds
|
100
|
+
train['builds'].delete_if do |b|
|
101
|
+
return true if b[testing_key].nil?
|
102
|
+
|
103
|
+
if build && b["buildVersion"] == build.build_version
|
104
|
+
b[testing_key]['value'] = new_value
|
105
|
+
false
|
106
|
+
elsif b[testing_key]['value'] == true
|
107
|
+
b[testing_key]['value'] = false
|
108
|
+
false
|
109
|
+
else
|
110
|
+
true
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
false
|
102
115
|
end
|
103
116
|
end
|
104
117
|
|
@@ -281,9 +281,9 @@ module Spaceship
|
|
281
281
|
handle_itc_response(data)
|
282
282
|
end
|
283
283
|
|
284
|
-
def create_version!(app_id, version_number)
|
284
|
+
def create_version!(app_id, version_number, platform = 'ios')
|
285
285
|
r = request(:post) do |req|
|
286
|
-
req.url "ra/apps/#{app_id}/platforms/
|
286
|
+
req.url "ra/apps/#{app_id}/platforms/#{platform}/versions/create/"
|
287
287
|
req.body = {
|
288
288
|
version: {
|
289
289
|
value: version_number.to_s
|
@@ -526,9 +526,9 @@ module Spaceship
|
|
526
526
|
handle_itc_response(r.body)
|
527
527
|
end
|
528
528
|
|
529
|
-
def remove_testflight_build_from_review!(app_id: nil, train: nil, build_number: nil)
|
529
|
+
def remove_testflight_build_from_review!(app_id: nil, train: nil, build_number: nil, platform: 'ios')
|
530
530
|
r = request(:post) do |req|
|
531
|
-
req.url "ra/apps/#{app_id}/platforms/
|
531
|
+
req.url "ra/apps/#{app_id}/platforms/#{platform}/trains/#{train}/builds/#{build_number}/reject"
|
532
532
|
req.body = {}.to_json
|
533
533
|
req.headers['Content-Type'] = 'application/json'
|
534
534
|
end
|
@@ -567,7 +567,7 @@ module Spaceship
|
|
567
567
|
handle_itc_response(r.body)
|
568
568
|
end
|
569
569
|
|
570
|
-
def submit_testflight_build_for_review!(app_id: nil, train: nil, build_number: nil,
|
570
|
+
def submit_testflight_build_for_review!(app_id: nil, train: nil, build_number: nil, platform: 'ios',
|
571
571
|
# Required Metadata:
|
572
572
|
changelog: nil,
|
573
573
|
description: nil,
|
@@ -585,29 +585,29 @@ module Spaceship
|
|
585
585
|
review_password: nil,
|
586
586
|
encryption: false)
|
587
587
|
|
588
|
-
build_info = get_build_info_for_review(app_id: app_id, train: train, build_number: build_number)
|
588
|
+
build_info = get_build_info_for_review(app_id: app_id, train: train, build_number: build_number, platform: platform)
|
589
589
|
# Now fill in the values provided by the user
|
590
590
|
|
591
591
|
# First the localised values:
|
592
592
|
build_info['testInfo']['details'].each do |current|
|
593
|
-
current['whatsNew']['value'] = changelog
|
594
|
-
current['description']['value'] = description
|
595
|
-
current['feedbackEmail']['value'] = feedback_email
|
596
|
-
current['marketingUrl']['value'] = marketing_url
|
597
|
-
current['privacyPolicyUrl']['value'] = privacy_policy_url
|
593
|
+
current['whatsNew']['value'] = changelog if changelog
|
594
|
+
current['description']['value'] = description if description
|
595
|
+
current['feedbackEmail']['value'] = feedback_email if feedback_email
|
596
|
+
current['marketingUrl']['value'] = marketing_url if marketing_url
|
597
|
+
current['privacyPolicyUrl']['value'] = privacy_policy_url if privacy_policy_url
|
598
598
|
current['pageLanguageValue'] = current['language'] # There is no valid reason why we need this, only iTC being iTC
|
599
599
|
end
|
600
600
|
build_info['significantChange'] ||= {}
|
601
601
|
build_info['significantChange']['value'] = significant_change
|
602
|
-
build_info['testInfo']['reviewFirstName']['value'] = first_name
|
603
|
-
build_info['testInfo']['reviewLastName']['value'] = last_name
|
604
|
-
build_info['testInfo']['reviewPhone']['value'] = phone_number
|
605
|
-
build_info['testInfo']['reviewEmail']['value'] = review_email
|
606
|
-
build_info['testInfo']['reviewUserName']['value'] = review_user_name
|
607
|
-
build_info['testInfo']['reviewPassword']['value'] = review_password
|
602
|
+
build_info['testInfo']['reviewFirstName']['value'] = first_name if first_name
|
603
|
+
build_info['testInfo']['reviewLastName']['value'] = last_name if last_name
|
604
|
+
build_info['testInfo']['reviewPhone']['value'] = phone_number if phone_number
|
605
|
+
build_info['testInfo']['reviewEmail']['value'] = review_email if review_email
|
606
|
+
build_info['testInfo']['reviewUserName']['value'] = review_user_name if review_user_name
|
607
|
+
build_info['testInfo']['reviewPassword']['value'] = review_password if review_password
|
608
608
|
|
609
609
|
r = request(:post) do |req| # same URL, but a POST request
|
610
|
-
req.url "ra/apps/#{app_id}/platforms/
|
610
|
+
req.url "ra/apps/#{app_id}/platforms/#{platform}/trains/#{train}/builds/#{build_number}/submit/start"
|
611
611
|
|
612
612
|
req.body = build_info.to_json
|
613
613
|
req.headers['Content-Type'] = 'application/json'
|
@@ -618,13 +618,14 @@ module Spaceship
|
|
618
618
|
update_encryption_compliance(app_id: app_id,
|
619
619
|
train: train,
|
620
620
|
build_number: build_number,
|
621
|
+
platform: platform,
|
621
622
|
encryption_info: encryption_info,
|
622
623
|
encryption: encryption)
|
623
624
|
end
|
624
625
|
|
625
|
-
def get_build_info_for_review(app_id: nil, train: nil, build_number: nil)
|
626
|
+
def get_build_info_for_review(app_id: nil, train: nil, build_number: nil, platform: 'ios')
|
626
627
|
r = request(:get) do |req|
|
627
|
-
req.url "ra/apps/#{app_id}/platforms/
|
628
|
+
req.url "ra/apps/#{app_id}/platforms/#{platform}/trains/#{train}/builds/#{build_number}/submit/start"
|
628
629
|
req.headers['Content-Type'] = 'application/json'
|
629
630
|
end
|
630
631
|
handle_itc_response(r.body)
|
@@ -632,16 +633,19 @@ module Spaceship
|
|
632
633
|
r.body['data']
|
633
634
|
end
|
634
635
|
|
635
|
-
def update_encryption_compliance(app_id: nil, train: nil, build_number: nil, encryption_info: nil, encryption: nil)
|
636
|
+
def update_encryption_compliance(app_id: nil, train: nil, build_number: nil, platform: 'ios', encryption_info: nil, encryption: nil, is_exempt: true, proprietary: false, third_party: false)
|
636
637
|
return unless encryption_info['exportComplianceRequired']
|
637
638
|
# only sometimes this is required
|
638
639
|
|
639
640
|
encryption_info['usesEncryption']['value'] = encryption
|
640
641
|
encryption_info['encryptionUpdated'] ||= {}
|
641
642
|
encryption_info['encryptionUpdated']['value'] = encryption
|
643
|
+
encryption_info['isExempt']['value'] = is_exempt
|
644
|
+
encryption_info['containsProprietaryCryptography']['value'] = proprietary
|
645
|
+
encryption_info['containsThirdPartyCryptography']['value'] = third_party
|
642
646
|
|
643
647
|
r = request(:post) do |req|
|
644
|
-
req.url "ra/apps/#{app_id}/platforms/
|
648
|
+
req.url "ra/apps/#{app_id}/platforms/#{platform}/trains/#{train}/builds/#{build_number}/submit/complete"
|
645
649
|
req.body = encryption_info.to_json
|
646
650
|
req.headers['Content-Type'] = 'application/json'
|
647
651
|
end
|
data/lib/spaceship/version.rb
CHANGED
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.
|
4
|
+
version: 0.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Krause
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-02-
|
12
|
+
date: 2016-02-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: credentials_manager
|