spaceship 0.4.0 → 0.5.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 +2 -10
- data/lib/spaceship/base.rb +7 -7
- data/lib/spaceship/client.rb +14 -12
- data/lib/spaceship/helper/plist_middleware.rb +1 -1
- data/lib/spaceship/portal/certificate.rb +5 -1
- data/lib/spaceship/portal/device.rb +44 -6
- data/lib/spaceship/portal/portal_base.rb +4 -4
- data/lib/spaceship/portal/portal_client.rb +33 -20
- data/lib/spaceship/portal/provisioning_profile.rb +17 -19
- data/lib/spaceship/tunes/app_submission.rb +1 -4
- data/lib/spaceship/tunes/app_version.rb +4 -3
- data/lib/spaceship/tunes/application.rb +3 -3
- data/lib/spaceship/tunes/build.rb +33 -34
- data/lib/spaceship/tunes/language_converter.rb +3 -3
- data/lib/spaceship/tunes/tunes_client.rb +12 -15
- data/lib/spaceship/ui.rb +5 -5
- data/lib/spaceship/version.rb +1 -1
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f8c0b6228e0f397f7f6b04eac0970e292e5dfd9
|
4
|
+
data.tar.gz: 92605b06ec0181b05d85f4ea1c8324a20f8c65d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf24cf176b3e186e21f8e9acdd4ebe51625a7f22d6ec0035aea748ea7255b1b11142b31fb5549d9c58f1544b743158db66506e6dd002df0b1c1b186dd0ccf9bc
|
7
|
+
data.tar.gz: 4d94ea406b064d1e2aeb86c8ec8f55995485753b5e201a5122c1792bb4a181648cb6057d5e6d99763879da4c7b73c525dc711438c18a38d57b46d03862dc4275
|
data/README.md
CHANGED
@@ -16,7 +16,8 @@
|
|
16
16
|
<a href="https://github.com/KrauseFx/codes">codes</a> •
|
17
17
|
<b>spaceship</b> •
|
18
18
|
<a href="https://github.com/fastlane/pilot">pilot</a> •
|
19
|
-
<a href="https://github.com/fastlane/boarding">boarding</a>
|
19
|
+
<a href="https://github.com/fastlane/boarding">boarding</a> •
|
20
|
+
<a href="https://github.com/fastlane/gym">gym</a>
|
20
21
|
</p>
|
21
22
|
-------
|
22
23
|
|
@@ -180,12 +181,3 @@ The initial release was sponsored by [ZeroPush](https://zeropush.com).
|
|
180
181
|
This project is licensed under the terms of the MIT license. See the LICENSE file.
|
181
182
|
|
182
183
|
> This project and all fastlane tools are in no way affiliated with Apple Inc. This project is open source under the MIT license, which means you have full access to the source code and can modify it to fit your own needs. All fastlane tools run on your own computer or server, so your credentials or other sensitive information will never leave your own computer. You are responsible for how you use fastlane tools.
|
183
|
-
|
184
|
-
# Contributing
|
185
|
-
|
186
|
-
1. Create an issue to start a discussion about your idea
|
187
|
-
2. Fork it (https://github.com/fastlane/spaceship/fork)
|
188
|
-
3. Create your feature branch (`git checkout -b my-new-feature`)
|
189
|
-
4. Commit your changes (`git commit -am 'Add some feature'`)
|
190
|
-
5. Push to the branch (`git push origin my-new-feature`)
|
191
|
-
6. Create a new Pull Request
|
data/lib/spaceship/base.rb
CHANGED
@@ -62,10 +62,12 @@ module Spaceship
|
|
62
62
|
##
|
63
63
|
# Sets client and returns self for chaining.
|
64
64
|
# @return (Spaceship::Base)
|
65
|
+
# rubocop:disable Style/AccessorMethodName
|
65
66
|
def set_client(client)
|
66
67
|
self.client = client
|
67
68
|
self
|
68
69
|
end
|
70
|
+
# rubocop:enable Style/AccessorMethodName
|
69
71
|
|
70
72
|
##
|
71
73
|
# Binds attributes getters and setters to underlying data returned from the API.
|
@@ -143,7 +145,7 @@ module Spaceship
|
|
143
145
|
def method_missing(method_sym, *args, &block)
|
144
146
|
module_name = method_sym.to_s
|
145
147
|
module_name.sub!(/^[a-z\d]/) { $&.upcase }
|
146
|
-
module_name.gsub!(
|
148
|
+
module_name.gsub!(%r{(?:_|(/))([a-z\d])}) { $2.upcase }
|
147
149
|
if const_defined?(module_name)
|
148
150
|
klass = const_get(module_name)
|
149
151
|
klass.set_client(@client)
|
@@ -153,6 +155,10 @@ module Spaceship
|
|
153
155
|
end
|
154
156
|
end
|
155
157
|
|
158
|
+
##
|
159
|
+
# @return (Spaceship::Client) The current spaceship client used by the model to make requests.
|
160
|
+
attr_reader :client
|
161
|
+
|
156
162
|
##
|
157
163
|
# @return (Hash/Array) Holds the raw data we got from Apple's
|
158
164
|
# server to use it later
|
@@ -177,12 +183,6 @@ module Spaceship
|
|
177
183
|
def setup
|
178
184
|
end
|
179
185
|
|
180
|
-
##
|
181
|
-
# @return (Spaceship::Client) The current spaceship client used by the model to make requests.
|
182
|
-
def client
|
183
|
-
@client
|
184
|
-
end
|
185
|
-
|
186
186
|
#####################################################
|
187
187
|
# @!group Storing the `attr_accessor`
|
188
188
|
#####################################################
|
data/lib/spaceship/client.rb
CHANGED
@@ -48,7 +48,7 @@ module Spaceship
|
|
48
48
|
if instance.login(user, password)
|
49
49
|
instance
|
50
50
|
else
|
51
|
-
raise InvalidUserCredentialsError.new
|
51
|
+
raise InvalidUserCredentialsError.new, "Invalid User Credentials"
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -76,6 +76,7 @@ module Spaceship
|
|
76
76
|
# /tmp/spaceship[time].log by default
|
77
77
|
def logger
|
78
78
|
unless @logger
|
79
|
+
# rubocop:disable Style/GlobalVars
|
79
80
|
if $verbose || ENV["VERBOSE"]
|
80
81
|
@logger = Logger.new(STDOUT)
|
81
82
|
else
|
@@ -83,9 +84,10 @@ module Spaceship
|
|
83
84
|
path = "/tmp/spaceship#{Time.now.to_i}.log"
|
84
85
|
@logger = Logger.new(path)
|
85
86
|
end
|
87
|
+
# rubocop:enable Style/GlobalVars
|
86
88
|
|
87
89
|
@logger.formatter = proc do |severity, datetime, progname, msg|
|
88
|
-
|
90
|
+
"[#{datetime.strftime('%H:%M:%S')}]: #{msg}\n"
|
89
91
|
end
|
90
92
|
end
|
91
93
|
|
@@ -110,9 +112,9 @@ module Spaceship
|
|
110
112
|
page += 1
|
111
113
|
current = yield(page)
|
112
114
|
|
113
|
-
results
|
115
|
+
results += current
|
114
116
|
|
115
|
-
break if (
|
117
|
+
break if (current || []).count < page_size # no more results
|
116
118
|
end
|
117
119
|
|
118
120
|
return results
|
@@ -144,7 +146,7 @@ module Spaceship
|
|
144
146
|
end
|
145
147
|
|
146
148
|
if user.to_s.strip.empty? or password.to_s.strip.empty?
|
147
|
-
raise NoUserCredentialsError.new
|
149
|
+
raise NoUserCredentialsError.new, "No login data provided"
|
148
150
|
end
|
149
151
|
|
150
152
|
send_login_request(user, password) # different in subclasses
|
@@ -171,14 +173,14 @@ module Spaceship
|
|
171
173
|
# Is called from `parse_response` to store the latest csrf_token (if available)
|
172
174
|
def store_csrf_tokens(response)
|
173
175
|
if response and response.headers
|
174
|
-
tokens = response.headers.select { |k, v| %w
|
175
|
-
if tokens and
|
176
|
+
tokens = response.headers.select { |k, v| %w(csrf csrf_ts).include?(k) }
|
177
|
+
if tokens and !tokens.empty?
|
176
178
|
@csrf_tokens = tokens
|
177
179
|
end
|
178
180
|
end
|
179
181
|
end
|
180
182
|
|
181
|
-
|
183
|
+
# memorize the last csrf tokens from responses
|
182
184
|
def csrf_tokens
|
183
185
|
@csrf_tokens || {}
|
184
186
|
end
|
@@ -220,8 +222,8 @@ module Spaceship
|
|
220
222
|
logger.debug("#{method.upcase}: #{url}: #{response.body}")
|
221
223
|
end
|
222
224
|
|
223
|
-
|
224
|
-
|
225
|
+
# Actually sends the request to the remote server
|
226
|
+
# Automatically retries the request up to 3 times if something goes wrong
|
225
227
|
def send_request(method, url_or_path, params, headers, &block)
|
226
228
|
with_retry do
|
227
229
|
@client.send(method, url_or_path, params, headers, &block)
|
@@ -235,8 +237,8 @@ module Spaceship
|
|
235
237
|
content = response.body
|
236
238
|
end
|
237
239
|
|
238
|
-
if content
|
239
|
-
raise UnexpectedResponse.new
|
240
|
+
if content.nil?
|
241
|
+
raise UnexpectedResponse.new, response.body
|
240
242
|
else
|
241
243
|
store_csrf_tokens(response)
|
242
244
|
content
|
@@ -130,7 +130,7 @@ module Spaceship
|
|
130
130
|
"4APLUP237T" => ApplePay
|
131
131
|
}
|
132
132
|
|
133
|
-
#
|
133
|
+
# Class methods
|
134
134
|
class << self
|
135
135
|
# Create a new code signing request that can be used to
|
136
136
|
# generate a new certificate
|
@@ -181,8 +181,10 @@ module Spaceship
|
|
181
181
|
end
|
182
182
|
|
183
183
|
# Parse the dates
|
184
|
+
# rubocop:disable Style/RescueModifier
|
184
185
|
attrs['expirationDate'] = (Time.parse(attrs['expirationDate']) rescue attrs['expirationDate'])
|
185
186
|
attrs['dateCreated'] = (Time.parse(attrs['dateCreated']) rescue attrs['dateCreated'])
|
187
|
+
# rubocop:enable Style/RescueModifier
|
186
188
|
|
187
189
|
# Here we go
|
188
190
|
klass = CERTIFICATE_TYPE_IDS[attrs['certificateTypeDisplayId']]
|
@@ -265,9 +267,11 @@ module Spaceship
|
|
265
267
|
end
|
266
268
|
|
267
269
|
# @return (Bool): Is this certificate a push profile for apps?
|
270
|
+
# rubocop:disable Style/PredicateName
|
268
271
|
def is_push?
|
269
272
|
self.kind_of? PushCertificate
|
270
273
|
end
|
274
|
+
# rubocop:enable Style/PredicateName
|
271
275
|
end
|
272
276
|
end
|
273
277
|
end
|
@@ -27,12 +27,28 @@ module Spaceship
|
|
27
27
|
# "c"
|
28
28
|
attr_accessor :status
|
29
29
|
|
30
|
+
# @return (String) Model (can be nil)
|
31
|
+
# @example
|
32
|
+
# 'iPhone 6', 'iPhone 4 GSM'
|
33
|
+
attr_accessor :model
|
34
|
+
|
35
|
+
# @return (String) Device type
|
36
|
+
# @example
|
37
|
+
# 'pc' - Apple TV
|
38
|
+
# 'watch' - Apple Watch
|
39
|
+
# 'ipad' - iPad
|
40
|
+
# 'iphone' - iPhone
|
41
|
+
# 'ipod' - iPod
|
42
|
+
attr_accessor :device_type
|
43
|
+
|
30
44
|
attr_mapping({
|
31
45
|
'deviceId' => :id,
|
32
46
|
'name' => :name,
|
33
47
|
'deviceNumber' => :udid,
|
34
48
|
'devicePlatform' => :platform,
|
35
|
-
'status' => :status
|
49
|
+
'status' => :status,
|
50
|
+
'deviceClass' => :device_type,
|
51
|
+
'model' => :model
|
36
52
|
})
|
37
53
|
|
38
54
|
class << self
|
@@ -47,6 +63,31 @@ module Spaceship
|
|
47
63
|
client.devices.map { |device| self.factory(device) }
|
48
64
|
end
|
49
65
|
|
66
|
+
# @return (Array) Returns all Apple TVs registered for this account
|
67
|
+
def all_apple_tvs
|
68
|
+
client.devices_by_class('pc').map { |device| self.factory(device) }
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return (Array) Returns all Watches registered for this account
|
72
|
+
def all_watches
|
73
|
+
client.devices_by_class('watch').map { |device| self.factory(device) }
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return (Array) Returns all iPads registered for this account
|
77
|
+
def all_ipads
|
78
|
+
client.devices_by_class('ipad').map { |device| self.factory(device) }
|
79
|
+
end
|
80
|
+
|
81
|
+
# @return (Array) Returns all iPhones registered for this account
|
82
|
+
def all_iphones
|
83
|
+
client.devices_by_class('iphone').map { |device| self.factory(device) }
|
84
|
+
end
|
85
|
+
|
86
|
+
# @return (Array) Returns all iPods registered for this account
|
87
|
+
def all_ipod_touches
|
88
|
+
client.devices_by_class('ipod').map { |device| self.factory(device) }
|
89
|
+
end
|
90
|
+
|
50
91
|
# @return (Device) Find a device based on the ID of the device. *Attention*:
|
51
92
|
# This is *not* the UDID. nil if no device was found.
|
52
93
|
def find(device_id)
|
@@ -77,7 +118,7 @@ module Spaceship
|
|
77
118
|
# @return (Device): The newly created device
|
78
119
|
def create!(name: nil, udid: nil)
|
79
120
|
# Check whether the user has passed in a UDID and a name
|
80
|
-
unless
|
121
|
+
unless udid && name
|
81
122
|
raise "You cannot create a device without a device_id (UDID) and name"
|
82
123
|
end
|
83
124
|
|
@@ -86,10 +127,7 @@ module Spaceship
|
|
86
127
|
raise "The device UDID '#{udid}' already exists on this team."
|
87
128
|
end
|
88
129
|
|
89
|
-
#
|
90
|
-
if self.find_by_name(name)
|
91
|
-
raise "The device name '#{name}' already exists on this team, use different one."
|
92
|
-
end
|
130
|
+
# It is valid to have the same name for multiple devices
|
93
131
|
|
94
132
|
device = client.create_device!(name, udid)
|
95
133
|
|
@@ -3,10 +3,10 @@ module Spaceship
|
|
3
3
|
class << self
|
4
4
|
def client
|
5
5
|
(
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
@client or
|
7
|
+
Spaceship::Portal.client or
|
8
|
+
raise "Please login using `Spaceship::Portal.login('user', 'password')`"
|
9
|
+
)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -22,12 +22,12 @@ module Spaceship
|
|
22
22
|
logger.info("GET: " + landing_url)
|
23
23
|
headers = @client.get(landing_url).headers
|
24
24
|
results = headers['location'].match(/.*appIdKey=(\h+)/)
|
25
|
-
if results.length > 1
|
25
|
+
if (results || []).length > 1
|
26
26
|
api_key = results[1]
|
27
27
|
File.write(cache_path, api_key)
|
28
28
|
return api_key
|
29
29
|
else
|
30
|
-
raise "Could not find latest API Key from the Dev Portal"
|
30
|
+
raise "Could not find latest API Key from the Dev Portal - the server might be slow right now"
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -43,7 +43,7 @@ module Spaceship
|
|
43
43
|
return @client
|
44
44
|
else
|
45
45
|
# User Credentials are wrong
|
46
|
-
raise InvalidUserCredentialsError.new
|
46
|
+
raise InvalidUserCredentialsError.new, response
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -123,11 +123,11 @@ module Spaceship
|
|
123
123
|
end
|
124
124
|
|
125
125
|
def associate_groups_with_app(app, groups)
|
126
|
-
|
126
|
+
request(:post, 'account/ios/identifiers/assignApplicationGroupToAppId.action', {
|
127
127
|
teamId: team_id,
|
128
128
|
appIdId: app.app_id,
|
129
129
|
displayId: app.app_id,
|
130
|
-
applicationGroups: groups.map
|
130
|
+
applicationGroups: groups.map(&:app_group_id)
|
131
131
|
})
|
132
132
|
|
133
133
|
details_for_app(app)
|
@@ -135,21 +135,21 @@ module Spaceship
|
|
135
135
|
|
136
136
|
def create_app!(type, name, bundle_id)
|
137
137
|
ident_params = case type.to_sym
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
138
|
+
when :explicit
|
139
|
+
{
|
140
|
+
type: 'explicit',
|
141
|
+
explicitIdentifier: bundle_id,
|
142
|
+
appIdentifierString: bundle_id,
|
143
|
+
push: 'on',
|
144
|
+
inAppPurchase: 'on',
|
145
|
+
gameCenter: 'on'
|
146
|
+
}
|
147
|
+
when :wildcard
|
148
|
+
{
|
149
|
+
type: 'wildcard',
|
150
|
+
wildcardIdentifier: bundle_id,
|
151
|
+
appIdentifierString: bundle_id
|
152
|
+
}
|
153
153
|
end
|
154
154
|
|
155
155
|
params = {
|
@@ -220,6 +220,19 @@ module Spaceship
|
|
220
220
|
end
|
221
221
|
end
|
222
222
|
|
223
|
+
def devices_by_class(deviceClass)
|
224
|
+
paging do |page_number|
|
225
|
+
r = request(:post, 'account/ios/device/listDevices.action', {
|
226
|
+
teamId: team_id,
|
227
|
+
pageNumber: page_number,
|
228
|
+
pageSize: page_size,
|
229
|
+
sort: 'name=asc',
|
230
|
+
deviceClasses: deviceClass
|
231
|
+
})
|
232
|
+
parse_response(r, 'devices')
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
223
236
|
def create_device!(device_name, device_id)
|
224
237
|
req = request(:post) do |r|
|
225
238
|
r.url "https://developerservices2.apple.com/services/#{PROTOCOL_VERSION}/ios/addDevice.action"
|
@@ -152,16 +152,16 @@ module Spaceship
|
|
152
152
|
# available values of `distributionMethod` at this point: ['adhoc', 'store', 'limited']
|
153
153
|
|
154
154
|
klass = case attrs['distributionMethod']
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
155
|
+
when 'limited'
|
156
|
+
Development
|
157
|
+
when 'store'
|
158
|
+
AppStore
|
159
|
+
when 'adhoc'
|
160
|
+
AdHoc
|
161
|
+
when 'inhouse'
|
162
|
+
InHouse
|
163
|
+
else
|
164
|
+
raise "Can't find class '#{attrs['distributionMethod']}'"
|
165
165
|
end
|
166
166
|
|
167
167
|
attrs['appId'] = App.factory(attrs['appId'])
|
@@ -202,9 +202,9 @@ module Spaceship
|
|
202
202
|
# Fill in sensible default values
|
203
203
|
name ||= [bundle_id, self.pretty_type].join(' ')
|
204
204
|
|
205
|
-
devices = [] if
|
205
|
+
devices = [] if self == AppStore || self == InHouse # App Store Profiles MUST NOT have devices
|
206
206
|
|
207
|
-
certificate_parameter = certificate.collect
|
207
|
+
certificate_parameter = certificate.collect(&:id) if certificate.kind_of? Array
|
208
208
|
certificate_parameter ||= [certificate.id]
|
209
209
|
|
210
210
|
# Fix https://github.com/KrauseFx/fastlane/issues/349
|
@@ -222,7 +222,7 @@ module Spaceship
|
|
222
222
|
self.type,
|
223
223
|
app.app_id,
|
224
224
|
certificate_parameter,
|
225
|
-
devices.map
|
225
|
+
devices.map(&:id) )
|
226
226
|
end
|
227
227
|
|
228
228
|
self.new(profile)
|
@@ -237,9 +237,7 @@ module Spaceship
|
|
237
237
|
end
|
238
238
|
|
239
239
|
# filter out the profiles managed by xcode
|
240
|
-
profiles.delete_if
|
241
|
-
profile.managed_by_xcode?
|
242
|
-
end
|
240
|
+
profiles.delete_if(&:managed_by_xcode?)
|
243
241
|
|
244
242
|
return profiles if self == ProvisioningProfile
|
245
243
|
|
@@ -335,8 +333,8 @@ module Spaceship
|
|
335
333
|
name,
|
336
334
|
distribution_method,
|
337
335
|
app.app_id,
|
338
|
-
certificates.map
|
339
|
-
devices.map
|
336
|
+
certificates.map(&:id),
|
337
|
+
devices.map(&:id)
|
340
338
|
)
|
341
339
|
end
|
342
340
|
|
@@ -353,7 +351,7 @@ module Spaceship
|
|
353
351
|
def certificate_valid?
|
354
352
|
return false if (certificates || []).count == 0
|
355
353
|
certificates.each do |c|
|
356
|
-
if Spaceship::Certificate.all.collect
|
354
|
+
if Spaceship::Certificate.all.collect(&:id).include?(c.id)
|
357
355
|
return true
|
358
356
|
end
|
359
357
|
end
|
@@ -98,8 +98,6 @@ module Spaceship
|
|
98
98
|
# Create a new object based on a hash.
|
99
99
|
# This is used to create a new object based on the server response.
|
100
100
|
def factory(attrs)
|
101
|
-
orig = attrs.dup
|
102
|
-
|
103
101
|
# fill content rights section if iTC returns nil
|
104
102
|
if attrs["contentRights"].nil?
|
105
103
|
attrs.merge!("contentRights" => {
|
@@ -117,8 +115,7 @@ module Spaceship
|
|
117
115
|
end
|
118
116
|
|
119
117
|
# @param application (Spaceship::Tunes::Application) The app this submission is for
|
120
|
-
|
121
|
-
def create(application, app_id, version)
|
118
|
+
def create(application, version)
|
122
119
|
stage = "start"
|
123
120
|
attrs = client.send_app_submission(application.apple_id, version.raw_data, stage)
|
124
121
|
attrs.merge!(application: application)
|
@@ -161,7 +161,6 @@ module Spaceship
|
|
161
161
|
# Create a new object based on a hash.
|
162
162
|
# This is used to create a new object based on the server response.
|
163
163
|
def factory(attrs)
|
164
|
-
orig = attrs.dup
|
165
164
|
obj = self.new(attrs)
|
166
165
|
obj.unfold_languages
|
167
166
|
|
@@ -181,9 +180,11 @@ module Spaceship
|
|
181
180
|
end
|
182
181
|
|
183
182
|
# @return (Bool) Is that version currently available in the App Store?
|
183
|
+
# rubocop:disable Style/PredicateName
|
184
184
|
def is_live?
|
185
185
|
is_live
|
186
186
|
end
|
187
|
+
# rubocop:enable Style/PredicateName
|
187
188
|
|
188
189
|
# Call this method to make sure the given languages are available for this app
|
189
190
|
# You should call this method before accessing the name, description and other localized values
|
@@ -264,7 +265,7 @@ module Spaceship
|
|
264
265
|
end
|
265
266
|
|
266
267
|
def supports_apple_watch
|
267
|
-
|
268
|
+
!super.nil?
|
268
269
|
end
|
269
270
|
|
270
271
|
def primary_category=(value)
|
@@ -299,7 +300,7 @@ module Spaceship
|
|
299
300
|
|
300
301
|
private
|
301
302
|
|
302
|
-
|
303
|
+
# generates the nested data structure to represent screenshots
|
303
304
|
def setup_screenshots(row)
|
304
305
|
screenshots = row.fetch('screenshots', {}).fetch('value', nil)
|
305
306
|
return [] unless screenshots
|
@@ -101,7 +101,7 @@ module Spaceship
|
|
101
101
|
# @return (Spaceship::AppVersion) Receive the version that is currently live on the
|
102
102
|
# App Store. You can't modify all values there, so be careful.
|
103
103
|
def live_version
|
104
|
-
|
104
|
+
Spaceship::AppVersion.find(self, self.apple_id, true)
|
105
105
|
end
|
106
106
|
|
107
107
|
# @return (Spaceship::AppVersion) Receive the version that can fully be edited
|
@@ -210,7 +210,7 @@ module Spaceship
|
|
210
210
|
raise "Could not find a valid version to submit for review"
|
211
211
|
end
|
212
212
|
|
213
|
-
Spaceship::AppSubmission.create(self,
|
213
|
+
Spaceship::AppSubmission.create(self, version)
|
214
214
|
end
|
215
215
|
|
216
216
|
# Cancels all ongoing TestFlight beta submission for this application
|
@@ -218,7 +218,7 @@ module Spaceship
|
|
218
218
|
self.builds do |build|
|
219
219
|
begin
|
220
220
|
build.cancel_beta_review!
|
221
|
-
rescue
|
221
|
+
rescue
|
222
222
|
# We really don't care about any errors here
|
223
223
|
end
|
224
224
|
end
|
@@ -146,7 +146,6 @@ module Spaceship
|
|
146
146
|
|
147
147
|
# Optional Metadata:
|
148
148
|
privacy_policy_url: nil,
|
149
|
-
review_notes: nil,
|
150
149
|
review_user_name: nil,
|
151
150
|
review_password: nil,
|
152
151
|
encryption: false
|
@@ -170,7 +169,7 @@ module Spaceship
|
|
170
169
|
end
|
171
170
|
end
|
172
171
|
|
173
|
-
if
|
172
|
+
if Time.at(self.internal_expiry_date / 1000) > Time.now
|
174
173
|
testing ||= "Inactive"
|
175
174
|
else
|
176
175
|
testing = "Expired"
|
@@ -190,35 +189,35 @@ module Spaceship
|
|
190
189
|
end
|
191
190
|
|
192
191
|
# Example response
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
192
|
+
# "buildVersion": "0.9.10",
|
193
|
+
# "trainVersion": "0.9.10",
|
194
|
+
# "uploadDate": 1413966436000,
|
195
|
+
# "iconUrl": "https://is5-ssl.mzstatic.com/image/thumb/Newsstand5/v4/e8/ab/f8/e8abf8ca-6c22-a519-aa1b-c73901c4917e/Icon-60@2x.png.png/150x150bb-80.png",
|
196
|
+
# "appName": "Yeahaa",
|
197
|
+
# "platform": "ios",
|
198
|
+
# "betaEntitled": false,
|
199
|
+
# "id": 523299,
|
200
|
+
# "valid": true,
|
201
|
+
# "missingExportCompliance": false,
|
202
|
+
# "waitingForExportComplianceApproval": false,
|
203
|
+
# "addedInternalUsersCount": 0,
|
204
|
+
# "addedExternalUsersCount": 0,
|
205
|
+
# "invitedExternalUsersCount": 0,
|
206
|
+
# "invitedInternalUsersCount": 0,
|
207
|
+
# "acceptedInternalUsersCount": 0,
|
208
|
+
# "acceptedExternalUsersCount": 0,
|
209
|
+
# "installCount": 0,
|
210
|
+
# "internalInstallCount": 0,
|
211
|
+
# "externalInstallCount": 0,
|
212
|
+
# "sessionCount": null,
|
213
|
+
# "crashCount": null,
|
214
|
+
# "promotedVersion": null,
|
215
|
+
# "internalState": "noBetaEntitlement",
|
216
|
+
# "betaState": "noBetaEntitlement",
|
217
|
+
# "internalExpiry": 1416562036000,
|
218
|
+
# "externalExpiry": 0,
|
219
|
+
# "watchKitEnabled": false,
|
220
|
+
# "readyToInstall": false,
|
221
|
+
# "sdkBuildWhitelisted": true,
|
222
|
+
# "internalTesting": null,
|
223
|
+
# "externalTesting": null
|
@@ -29,16 +29,16 @@ module Spaceship
|
|
29
29
|
|
30
30
|
private
|
31
31
|
|
32
|
-
|
32
|
+
# Path to the gem to fetch resoures
|
33
33
|
def spaceship_gem_path
|
34
|
-
if Gem::Specification
|
34
|
+
if Gem::Specification.find_all_by_name('spaceship').any?
|
35
35
|
return Gem::Specification.find_by_name('spaceship').gem_dir
|
36
36
|
else
|
37
37
|
return './'
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
|
41
|
+
# Get the mapping JSON parsed
|
42
42
|
def mapping
|
43
43
|
@languages ||= JSON.parse(File.read(File.join(spaceship_gem_path, "lib", "assets", "languageMapping.json")))
|
44
44
|
end
|
@@ -24,7 +24,7 @@ module Spaceship
|
|
24
24
|
|
25
25
|
host = "https://itunesconnect.apple.com"
|
26
26
|
begin
|
27
|
-
url = host + request(:get, self.class.hostname).body.match(
|
27
|
+
url = host + request(:get, self.class.hostname).body.match(%r{action="(/WebObjects/iTunesConnect.woa/wo/.*)"})[1]
|
28
28
|
raise "" unless url.length > 0
|
29
29
|
|
30
30
|
File.write(cache_path, url)
|
@@ -57,15 +57,15 @@ module Spaceship
|
|
57
57
|
]
|
58
58
|
|
59
59
|
@cookie = to_use.join(';')
|
60
|
-
rescue
|
60
|
+
rescue
|
61
61
|
# User Credentials are wrong
|
62
|
-
raise InvalidUserCredentialsError.new
|
62
|
+
raise InvalidUserCredentialsError.new, response
|
63
63
|
end
|
64
64
|
|
65
65
|
return @client
|
66
66
|
else
|
67
67
|
# User Credentials are wrong
|
68
|
-
raise InvalidUserCredentialsError.new
|
68
|
+
raise InvalidUserCredentialsError.new, response
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
@@ -86,24 +86,23 @@ module Spaceship
|
|
86
86
|
errors = []
|
87
87
|
if hash.kind_of? Hash
|
88
88
|
hash.each do |key, value|
|
89
|
-
errors
|
89
|
+
errors += handle_response_hash.call(value)
|
90
90
|
|
91
91
|
if key == 'errorKeys' and value.kind_of? Array and value.count > 0
|
92
|
-
errors
|
92
|
+
errors += value
|
93
93
|
end
|
94
94
|
end
|
95
95
|
elsif hash.kind_of? Array
|
96
96
|
hash.each do |value|
|
97
|
-
errors
|
97
|
+
errors += handle_response_hash.call(value)
|
98
98
|
end
|
99
|
-
|
100
|
-
# We don't care about simple values
|
99
|
+
# else: We don't care about simple values
|
101
100
|
end
|
102
101
|
return errors
|
103
102
|
end
|
104
103
|
|
105
104
|
errors = handle_response_hash.call(data)
|
106
|
-
errors
|
105
|
+
errors += data.fetch('sectionErrorKeys') if data['sectionErrorKeys']
|
107
106
|
|
108
107
|
# Sometimes there is a different kind of error in the JSON response
|
109
108
|
# e.g. {"warn"=>nil, "error"=>["operation_failed"], "info"=>nil}
|
@@ -111,7 +110,7 @@ module Spaceship
|
|
111
110
|
errors << different_error if different_error
|
112
111
|
|
113
112
|
if errors.count > 0 # they are separated by `.` by default
|
114
|
-
raise ITunesConnectError.new
|
113
|
+
raise ITunesConnectError.new, errors.join(' ')
|
115
114
|
end
|
116
115
|
|
117
116
|
puts data['sectionInfoKeys'] if data['sectionInfoKeys']
|
@@ -176,7 +175,7 @@ module Spaceship
|
|
176
175
|
|
177
176
|
def get_resolution_center(app_id)
|
178
177
|
r = request(:get, "ra/apps/#{app_id}/resolutionCenter?v=latest")
|
179
|
-
|
178
|
+
parse_response(r, 'data')
|
180
179
|
end
|
181
180
|
|
182
181
|
#####################################################
|
@@ -214,7 +213,7 @@ module Spaceship
|
|
214
213
|
raise "app_id is required" unless app_id
|
215
214
|
|
216
215
|
r = request(:get, "ra/apps/#{app_id}/trains/")
|
217
|
-
|
216
|
+
parse_response(r, 'data')
|
218
217
|
end
|
219
218
|
|
220
219
|
def update_build_trains!(app_id, data)
|
@@ -242,7 +241,6 @@ module Spaceship
|
|
242
241
|
app_id: nil,
|
243
242
|
train: nil,
|
244
243
|
build_number: nil,
|
245
|
-
cancel_other_submissions: false,
|
246
244
|
|
247
245
|
# Required Metadata:
|
248
246
|
changelog: nil,
|
@@ -256,7 +254,6 @@ module Spaceship
|
|
256
254
|
|
257
255
|
# Optional Metadata:
|
258
256
|
privacy_policy_url: nil,
|
259
|
-
review_notes: nil,
|
260
257
|
review_user_name: nil,
|
261
258
|
review_password: nil,
|
262
259
|
encryption: false)
|
data/lib/spaceship/ui.rb
CHANGED
@@ -7,21 +7,21 @@ end
|
|
7
7
|
module Spaceship
|
8
8
|
class Client
|
9
9
|
# Public getter for all UI related code
|
10
|
+
# rubocop:disable Style/MethodName
|
10
11
|
def UI
|
11
12
|
UserInterface.new(self)
|
12
13
|
end
|
14
|
+
# rubocop:enable Style/MethodName
|
13
15
|
|
14
16
|
# All User Interface related code lives in this class
|
15
17
|
class UserInterface
|
18
|
+
# Access the client this UserInterface object is for
|
19
|
+
attr_reader :client
|
20
|
+
|
16
21
|
# Is called by the client to generate one instance of UserInterface
|
17
22
|
def initialize(c)
|
18
23
|
@client = c
|
19
24
|
end
|
20
|
-
|
21
|
-
# Access the client this UserInterface object is for
|
22
|
-
def client
|
23
|
-
@client
|
24
|
-
end
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
data/lib/spaceship/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spaceship
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Stefan Natchev
|
8
7
|
- Felix Krause
|
8
|
+
- Stefan Natchev
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-08-
|
12
|
+
date: 2015-08-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: credentials_manager
|
@@ -95,6 +95,20 @@ dependencies:
|
|
95
95
|
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: fastlane
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: 1.15.0
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 1.15.0
|
98
112
|
- !ruby/object:Gem::Dependency
|
99
113
|
name: rake
|
100
114
|
requirement: !ruby/object:Gem::Requirement
|
@@ -210,8 +224,8 @@ dependencies:
|
|
210
224
|
description: Because you would rather spend your time building stuff than fighting
|
211
225
|
provisioning
|
212
226
|
email:
|
213
|
-
- stefan@natchev.com
|
214
227
|
- spaceship@krausefx.com
|
228
|
+
- stefan@natchev.com
|
215
229
|
executables: []
|
216
230
|
extensions: []
|
217
231
|
extra_rdoc_files: []
|