spaceship 0.36.2 → 0.37.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/lib/spaceship.rb +3 -0
- data/lib/spaceship/client.rb +2 -2
- data/lib/spaceship/du/upload_file.rb +8 -2
- data/lib/spaceship/portal/app_service.rb +56 -0
- data/lib/spaceship/tunes/app_version.rb +14 -0
- data/lib/spaceship/tunes/build_train.rb +22 -1
- data/lib/spaceship/tunes/tester.rb +33 -3
- data/lib/spaceship/tunes/tunes_client.rb +15 -3
- data/lib/spaceship/tunes/user_detail.rb +2 -1
- data/lib/spaceship/two_step_client.rb +5 -1
- data/lib/spaceship/update_checker.rb +42 -0
- data/lib/spaceship/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5876ed2b557a73506b42f22b1845d8e532574b96
|
4
|
+
data.tar.gz: 8b70dd155a884a368c2b55ea67b320674581928a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 705f85a89b839339b2b7b32344f8abf0525416add39db3a7ba07faf7b8fa2ae33f6db1dc7df0e7f225dce468fe60afd7400bcc8cfd82a59129ea783319bb8f17
|
7
|
+
data.tar.gz: 70d0bd2a25191aff18e84378fb0e300383c2a56fc9a1282f0286d8d5b868733677bfdf1790a02c6c6297f8c218a8d5816b7c1accfcc181c434c13e29cfde576a
|
data/README.md
CHANGED
@@ -111,7 +111,7 @@ This requires you to install `pry` using `sudo gem install pry`. `pry` is not in
|
|
111
111
|
|
112
112
|
## 2 Step Verification
|
113
113
|
|
114
|
-
When your Apple account has 2
|
114
|
+
When your Apple account has 2 factor verification enabled, you'll automatically be asked to verify your identity using your phone. The resulting session will be stored in `~/.spaceship/[email]/cookie`. The session should be valid for about one month, however there is no way to test this without actually waiting for over a month.
|
115
115
|
|
116
116
|
Since your CI system probably doesn't allow you to input values (like the verification code), you can use `spaceauth`:
|
117
117
|
|
@@ -127,9 +127,9 @@ export FASTLANE_SESSION='---\n- !ruby/object:HTTP::Cookie\n name: DES5c148586df
|
|
127
127
|
|
128
128
|
Copy everything from `---\n` to your CI server and provide it as environment variable named `FASTLANE_SESSION`.
|
129
129
|
|
130
|
-
###
|
130
|
+
### _spaceship_ in use
|
131
131
|
|
132
|
-
|
132
|
+
All [fastlane tools](https://fastlane.tools) that communicate with Apple's web services in some way, use _spaceship_ to do so.
|
133
133
|
|
134
134
|
# Technical Details
|
135
135
|
|
data/lib/spaceship.rb
CHANGED
@@ -2,6 +2,7 @@ require 'spaceship/version'
|
|
2
2
|
require 'spaceship/base'
|
3
3
|
require 'spaceship/client'
|
4
4
|
require 'spaceship/launcher'
|
5
|
+
require 'spaceship/update_checker'
|
5
6
|
|
6
7
|
# Dev Portal
|
7
8
|
require 'spaceship/portal/portal'
|
@@ -27,4 +28,6 @@ module Spaceship
|
|
27
28
|
AppVersion = Spaceship::Tunes::AppVersion
|
28
29
|
AppSubmission = Spaceship::Tunes::AppSubmission
|
29
30
|
Application = Spaceship::Tunes::Application
|
31
|
+
|
32
|
+
UpdateChecker.ensure_spaceship_version
|
30
33
|
end
|
data/lib/spaceship/client.rb
CHANGED
@@ -101,8 +101,8 @@ module Spaceship
|
|
101
101
|
def initialize
|
102
102
|
options = {
|
103
103
|
request: {
|
104
|
-
timeout: 300,
|
105
|
-
open_timeout: 300
|
104
|
+
timeout: (ENV["SPACESHIP_TIMEOUT"] || 300).to_i,
|
105
|
+
open_timeout: (ENV["SPACESHIP_TIMEOUT"] || 300).to_i
|
106
106
|
}
|
107
107
|
}
|
108
108
|
@cookie = HTTP::CookieJar.new
|
@@ -33,10 +33,16 @@ module Spaceship
|
|
33
33
|
def remove_alpha_channel(original)
|
34
34
|
path = "/tmp/#{Digest::MD5.hexdigest(original)}.png"
|
35
35
|
FileUtils.copy(original, path)
|
36
|
-
|
37
|
-
|
36
|
+
if mac? # sips is only available on macOS
|
37
|
+
`sips -s format bmp '#{path}' &> /dev/null` # &> /dev/null since there is warning because of the extension
|
38
|
+
`sips -s format png '#{path}'`
|
39
|
+
end
|
38
40
|
return path
|
39
41
|
end
|
42
|
+
|
43
|
+
def mac?
|
44
|
+
(/darwin/ =~ RUBY_PLATFORM) != nil
|
45
|
+
end
|
40
46
|
end
|
41
47
|
|
42
48
|
private
|
@@ -35,6 +35,10 @@ module Spaceship
|
|
35
35
|
self::AppGroup
|
36
36
|
end
|
37
37
|
|
38
|
+
def apple_pay
|
39
|
+
self::ApplePay
|
40
|
+
end
|
41
|
+
|
38
42
|
def associated_domains
|
39
43
|
self::AssociatedDomains
|
40
44
|
end
|
@@ -43,6 +47,10 @@ module Spaceship
|
|
43
47
|
self::DataProtection
|
44
48
|
end
|
45
49
|
|
50
|
+
def game_center
|
51
|
+
self::GameCenter
|
52
|
+
end
|
53
|
+
|
46
54
|
def health_kit
|
47
55
|
self::HealthKit
|
48
56
|
end
|
@@ -63,6 +71,10 @@ module Spaceship
|
|
63
71
|
self::CloudKit
|
64
72
|
end
|
65
73
|
|
74
|
+
def in_app_purchase
|
75
|
+
self::InAppPurchase
|
76
|
+
end
|
77
|
+
|
66
78
|
def inter_app_audio
|
67
79
|
self::InterAppAudio
|
68
80
|
end
|
@@ -75,6 +87,10 @@ module Spaceship
|
|
75
87
|
self::PushNotification
|
76
88
|
end
|
77
89
|
|
90
|
+
def siri_kit
|
91
|
+
self::SiriKit
|
92
|
+
end
|
93
|
+
|
78
94
|
def vpn_configuration
|
79
95
|
self::VPNConfiguration
|
80
96
|
end
|
@@ -100,6 +116,16 @@ module Spaceship
|
|
100
116
|
end
|
101
117
|
end
|
102
118
|
|
119
|
+
module ApplePay
|
120
|
+
def self.off
|
121
|
+
AppService.new("OM633U5T5G", false)
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.on
|
125
|
+
AppService.new("OM633U5T5G", true)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
103
129
|
module AssociatedDomains
|
104
130
|
def self.off
|
105
131
|
AppService.new("SKC3T5S89Y", false)
|
@@ -128,6 +154,16 @@ module Spaceship
|
|
128
154
|
end
|
129
155
|
end
|
130
156
|
|
157
|
+
module GameCenter
|
158
|
+
def self.off
|
159
|
+
AppService.new("gameCenter", false)
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.on
|
163
|
+
AppService.new("gameCenter", true)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
131
167
|
module HealthKit
|
132
168
|
def self.off
|
133
169
|
AppService.new("HK421J6T7P", false)
|
@@ -178,6 +214,16 @@ module Spaceship
|
|
178
214
|
end
|
179
215
|
end
|
180
216
|
|
217
|
+
module InAppPurchase
|
218
|
+
def self.off
|
219
|
+
AppService.new("inAppPurchase", false)
|
220
|
+
end
|
221
|
+
|
222
|
+
def self.on
|
223
|
+
AppService.new("inAppPurchase", true)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
181
227
|
module InterAppAudio
|
182
228
|
def self.off
|
183
229
|
AppService.new("IAD53UNK2F", false)
|
@@ -208,6 +254,16 @@ module Spaceship
|
|
208
254
|
end
|
209
255
|
end
|
210
256
|
|
257
|
+
module SiriKit
|
258
|
+
def self.off
|
259
|
+
AppService.new("SI015DKUHP", false)
|
260
|
+
end
|
261
|
+
|
262
|
+
def self.on
|
263
|
+
AppService.new("SI015DKUHP", true)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
211
267
|
module VPNConfiguration
|
212
268
|
def self.off
|
213
269
|
AppService.new("V66P55NK2I", false)
|
@@ -30,6 +30,9 @@ module Spaceship
|
|
30
30
|
# @return (String) App Status (e.g. 'readyForSale'). You should use `app_status` instead
|
31
31
|
attr_accessor :raw_status
|
32
32
|
|
33
|
+
# @return (String) Build Version
|
34
|
+
attr_accessor :build_version
|
35
|
+
|
33
36
|
# @return (Bool)
|
34
37
|
attr_accessor :can_reject_version
|
35
38
|
|
@@ -133,6 +136,7 @@ module Spaceship
|
|
133
136
|
'largeAppIcon.value.url' => :app_icon_url,
|
134
137
|
'releaseOnApproval.value' => :release_on_approval,
|
135
138
|
'status' => :raw_status,
|
139
|
+
'preReleaseBuild.buildVersion' => :build_version,
|
136
140
|
'supportsAppleWatch' => :supports_apple_watch,
|
137
141
|
'versionId' => :version_id,
|
138
142
|
'version.value' => :version,
|
@@ -215,6 +219,16 @@ module Spaceship
|
|
215
219
|
nil
|
216
220
|
end
|
217
221
|
|
222
|
+
def current_build_number
|
223
|
+
if self.is_live?
|
224
|
+
build_version
|
225
|
+
else
|
226
|
+
if candidate_builds.length > 0
|
227
|
+
candidate_builds.first.build_version
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
218
232
|
# Returns an array of all builds that can be sent to review
|
219
233
|
def candidate_builds
|
220
234
|
res = client.candidate_builds(self.application.apple_id, self.version_id)
|
@@ -141,7 +141,28 @@ module Spaceship
|
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
144
|
-
|
144
|
+
begin
|
145
|
+
result = client.update_build_trains!(application.apple_id, testing_type, data)
|
146
|
+
rescue Spaceship::TunesClient::ITunesConnectError => ex
|
147
|
+
if ex.to_s.include?("You must provide an answer for this question")
|
148
|
+
# This is a very common error message that's raised by TestFlight
|
149
|
+
# We want to show a nicer error message with instructions on how
|
150
|
+
# to resolve the underlying issue
|
151
|
+
# https://github.com/fastlane/fastlane/issues/1873
|
152
|
+
# https://github.com/fastlane/fastlane/issues/4002
|
153
|
+
error_message = [""] # to have a nice new-line in the beginning
|
154
|
+
error_message << "TestFlight requires you to provide the answer to the encryption question"
|
155
|
+
error_message << "to provide the reply, please add the following to your Info.plist file"
|
156
|
+
error_message << ""
|
157
|
+
error_message << "<key>ITSAppUsesNonExemptEncryption</key><false/>"
|
158
|
+
error_message << ""
|
159
|
+
error_message << "Afterwards re-build your app and try again"
|
160
|
+
error_message << "iTunes Connect reported: '#{ex}'"
|
161
|
+
raise error_message.join("\n")
|
162
|
+
else
|
163
|
+
raise ex
|
164
|
+
end
|
165
|
+
end
|
145
166
|
self.internal_testing_enabled = new_value if testing_type == 'internal'
|
146
167
|
self.external_testing_enabled = new_value if testing_type == 'external'
|
147
168
|
|
@@ -21,6 +21,16 @@ module Spaceship
|
|
21
21
|
# "Bennett"
|
22
22
|
attr_accessor :last_name
|
23
23
|
|
24
|
+
# @return (Array) an array of associated groups
|
25
|
+
# @example
|
26
|
+
# [{
|
27
|
+
# "id": "e031e048-4f0f-4c1e-8d8a-a5341a267986",
|
28
|
+
# "name": {
|
29
|
+
# "value": "My App Testers"
|
30
|
+
# }
|
31
|
+
# }]
|
32
|
+
attr_accessor :groups
|
33
|
+
|
24
34
|
# @return (Array) An array of registered devices for this user
|
25
35
|
# @example
|
26
36
|
# [{
|
@@ -50,6 +60,7 @@ module Spaceship
|
|
50
60
|
'emailAddress.value' => :email,
|
51
61
|
'firstName.value' => :first_name,
|
52
62
|
'lastName.value' => :last_name,
|
63
|
+
'groups' => :groups,
|
53
64
|
'devices' => :devices,
|
54
65
|
'latestInstalledAppAdamId' => :latest_install_app_id,
|
55
66
|
'latestInstalledDate' => :latest_install_date,
|
@@ -83,18 +94,24 @@ module Spaceship
|
|
83
94
|
end
|
84
95
|
end
|
85
96
|
|
97
|
+
def groups
|
98
|
+
client.groups
|
99
|
+
end
|
100
|
+
|
86
101
|
# Create new tester in iTunes Connect
|
87
102
|
# @param email (String) (required): The email of the new tester
|
88
103
|
# @param first_name (String) (optional): The first name of the new tester
|
89
104
|
# @param last_name (String) (optional): The last name of the new tester
|
105
|
+
# @param groups (Array) (option): Names/IDs of existing groups for the new tester
|
90
106
|
# @example
|
91
|
-
# Spaceship::Tunes::Tester.external.create!(email: "tester@mathiascarignani.com", first_name: "Cary", last_name:"Bennett")
|
107
|
+
# Spaceship::Tunes::Tester.external.create!(email: "tester@mathiascarignani.com", first_name: "Cary", last_name:"Bennett", groups:["Testers"])
|
92
108
|
# @return (Tester): The newly created tester
|
93
|
-
def create!(email: nil, first_name: nil, last_name: nil)
|
109
|
+
def create!(email: nil, first_name: nil, last_name: nil, groups: nil)
|
94
110
|
data = client.create_tester!(tester: self,
|
95
111
|
email: email,
|
96
112
|
first_name: first_name,
|
97
|
-
last_name: last_name
|
113
|
+
last_name: last_name,
|
114
|
+
groups: groups)
|
98
115
|
self.factory(data)
|
99
116
|
end
|
100
117
|
|
@@ -187,6 +204,19 @@ module Spaceship
|
|
187
204
|
def remove_from_app!(app_id)
|
188
205
|
client.remove_tester_from_app!(self, app_id)
|
189
206
|
end
|
207
|
+
|
208
|
+
#####################################################
|
209
|
+
# @!group Helpers
|
210
|
+
#####################################################
|
211
|
+
|
212
|
+
# Return a list of the Tester's group, if any
|
213
|
+
# @return
|
214
|
+
def groups_list(separator = ', ')
|
215
|
+
if groups
|
216
|
+
group_names = groups.map { |group| group["name"]["value"] }
|
217
|
+
group_names.join(separator)
|
218
|
+
end
|
219
|
+
end
|
190
220
|
end
|
191
221
|
|
192
222
|
class SandboxTester < TunesBase
|
@@ -87,7 +87,10 @@ module Spaceship
|
|
87
87
|
|
88
88
|
response = request(:post) do |req|
|
89
89
|
req.url "ra/v1/session/webSession"
|
90
|
-
req.body = {
|
90
|
+
req.body = {
|
91
|
+
contentProviderId: team_id,
|
92
|
+
dsId: user_detail_data.ds_id # https://github.com/fastlane/fastlane/issues/6711
|
93
|
+
}.to_json
|
91
94
|
req.headers['Content-Type'] = 'application/json'
|
92
95
|
end
|
93
96
|
|
@@ -538,7 +541,7 @@ module Spaceship
|
|
538
541
|
return @cached if @cached
|
539
542
|
r = request(:get, '/WebObjects/iTunesConnect.woa/ra/user/detail')
|
540
543
|
data = parse_response(r, 'data')
|
541
|
-
@cached
|
544
|
+
@cached = Spaceship::Tunes::UserDetail.factory(data)
|
542
545
|
end
|
543
546
|
|
544
547
|
#####################################################
|
@@ -785,7 +788,13 @@ module Spaceship
|
|
785
788
|
parse_response(r, 'data')['users']
|
786
789
|
end
|
787
790
|
|
788
|
-
def
|
791
|
+
def groups
|
792
|
+
return @cached_groups if @cached_groups
|
793
|
+
r = request(:get, '/WebObjects/iTunesConnect.woa/ra/users/pre/ext')
|
794
|
+
@cached_groups = parse_response(r, 'data')['groups']
|
795
|
+
end
|
796
|
+
|
797
|
+
def create_tester!(tester: nil, email: nil, first_name: nil, last_name: nil, groups: nil)
|
789
798
|
url = tester.url[:create]
|
790
799
|
raise "Action not provided for this tester type." unless url
|
791
800
|
|
@@ -803,6 +812,9 @@ module Spaceship
|
|
803
812
|
value: true
|
804
813
|
}
|
805
814
|
}
|
815
|
+
if groups
|
816
|
+
tester_data[:groups] = groups.map { |x| { "id" => x } }
|
817
|
+
end
|
806
818
|
|
807
819
|
data = { testers: [tester_data] }
|
808
820
|
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module Spaceship
|
2
2
|
module Tunes
|
3
3
|
class UserDetail < TunesBase
|
4
|
-
attr_accessor :content_provider_id
|
4
|
+
attr_accessor :content_provider_id
|
5
|
+
attr_accessor :ds_id # used for the team selection (https://github.com/fastlane/fastlane/issues/6711)
|
5
6
|
|
6
7
|
attr_mapping(
|
7
8
|
'contentProviderId' => :content_provider_id,
|
@@ -36,7 +36,6 @@ module Spaceship
|
|
36
36
|
device_id = result.match(/.*\t.*\t\((.*)\)/)[1]
|
37
37
|
select_device(r, device_id)
|
38
38
|
elsif r.body.kind_of?(Hash) && r.body["phoneNumberVerification"].kind_of?(Hash)
|
39
|
-
puts "Two Factor Authentication for account '#{self.user}' is enabled"
|
40
39
|
handle_two_factor(r)
|
41
40
|
else
|
42
41
|
raise "Invalid 2 step response #{r.body}"
|
@@ -44,6 +43,11 @@ module Spaceship
|
|
44
43
|
end
|
45
44
|
|
46
45
|
def handle_two_factor(response)
|
46
|
+
two_factor_url = "https://github.com/fastlane/fastlane/tree/master/spaceship#2-step-verification"
|
47
|
+
puts "Two Factor Authentication for account '#{self.user}' is enabled"
|
48
|
+
puts "If you're running this in a non-interactive session (e.g. server or CI)"
|
49
|
+
puts "check out #{two_factor_url}"
|
50
|
+
|
47
51
|
security_code = response.body["phoneNumberVerification"]["securityCode"]
|
48
52
|
# {"length"=>6,
|
49
53
|
# "tooManyCodesSent"=>false,
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Spaceship
|
2
|
+
class UpdateChecker
|
3
|
+
UPDATE_URL = "https://fastlane-refresher.herokuapp.com/spaceship"
|
4
|
+
|
5
|
+
def self.ensure_spaceship_version
|
6
|
+
return if defined?(SpecHelper) # is this running via tests
|
7
|
+
return if ENV["FASTLANE_SKIP_UPDATE_CHECK"]
|
8
|
+
|
9
|
+
require 'faraday'
|
10
|
+
require 'json'
|
11
|
+
|
12
|
+
response = Faraday.get(UPDATE_URL)
|
13
|
+
return if response.nil? || response.body.to_s.length == 0
|
14
|
+
|
15
|
+
version = JSON.parse(response.body)["version"]
|
16
|
+
puts "Comparing spaceship version (remote #{version} - local #{Spaceship::VERSION})" if $verbose
|
17
|
+
return if Gem::Version.new(version) <= Gem::Version.new(Spaceship::VERSION)
|
18
|
+
|
19
|
+
show_update_message(Spaceship::VERSION, version)
|
20
|
+
rescue => ex
|
21
|
+
puts ex.to_s if $verbose
|
22
|
+
puts "Couldn't verify that spaceship is up to date"
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.show_update_message(local_version, live_version)
|
26
|
+
puts "---------------------------------------------".red
|
27
|
+
puts "-------------------WARNING-------------------".red
|
28
|
+
puts "---------------------------------------------".red
|
29
|
+
puts "You're using an old version of spaceship"
|
30
|
+
puts "To ensure spaceship and fastlane works"
|
31
|
+
puts "update to the latest version."
|
32
|
+
puts ""
|
33
|
+
puts "Run `[sudo] gem update spaceship`"
|
34
|
+
puts ""
|
35
|
+
puts "or `bundle update` if you use bundler."
|
36
|
+
puts ""
|
37
|
+
puts "You're on spaceship version: #{local_version}".yellow
|
38
|
+
puts "Latest spaceship version : #{live_version}".yellow
|
39
|
+
puts ""
|
40
|
+
end
|
41
|
+
end
|
42
|
+
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.37.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-
|
12
|
+
date: 2016-11-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: credentials_manager
|
@@ -379,6 +379,7 @@ files:
|
|
379
379
|
- lib/spaceship/tunes/user_detail.rb
|
380
380
|
- lib/spaceship/two_step_client.rb
|
381
381
|
- lib/spaceship/ui.rb
|
382
|
+
- lib/spaceship/update_checker.rb
|
382
383
|
- lib/spaceship/version.rb
|
383
384
|
homepage: https://fastlane.tools
|
384
385
|
licenses:
|
@@ -400,7 +401,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
400
401
|
version: '0'
|
401
402
|
requirements: []
|
402
403
|
rubyforge_project:
|
403
|
-
rubygems_version: 2.
|
404
|
+
rubygems_version: 2.5.1
|
404
405
|
signing_key:
|
405
406
|
specification_version: 4
|
406
407
|
summary: Ruby library to access the Apple Dev Center and iTunes Connect
|