spaceship 0.3.4 → 0.4.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 +16 -15
- data/lib/spaceship.rb +2 -1
- data/lib/spaceship/base.rb +0 -1
- data/lib/spaceship/client.rb +71 -69
- data/lib/spaceship/helper/net_http_generic_request.rb +1 -1
- data/lib/spaceship/launcher.rb +19 -14
- data/lib/spaceship/portal/app.rb +23 -9
- data/lib/spaceship/portal/app_group.rb +77 -0
- data/lib/spaceship/portal/app_service.rb +222 -0
- data/lib/spaceship/portal/certificate.rb +2 -2
- data/lib/spaceship/portal/device.rb +7 -7
- data/lib/spaceship/portal/portal.rb +3 -1
- data/lib/spaceship/portal/portal_base.rb +1 -1
- data/lib/spaceship/portal/portal_client.rb +64 -10
- data/lib/spaceship/portal/provisioning_profile.rb +28 -54
- data/lib/spaceship/portal/spaceship.rb +27 -9
- data/lib/spaceship/portal/ui/select_team.rb +6 -8
- data/lib/spaceship/tunes/app_screenshot.rb +1 -1
- data/lib/spaceship/tunes/app_status.rb +5 -6
- data/lib/spaceship/tunes/app_submission.rb +24 -23
- data/lib/spaceship/tunes/app_version.rb +27 -34
- data/lib/spaceship/tunes/application.rb +24 -25
- data/lib/spaceship/tunes/build.rb +6 -7
- data/lib/spaceship/tunes/build_train.rb +2 -2
- data/lib/spaceship/tunes/language_converter.rb +14 -13
- data/lib/spaceship/tunes/language_item.rb +1 -1
- data/lib/spaceship/tunes/processing_build.rb +1 -1
- data/lib/spaceship/tunes/spaceship.rb +5 -5
- data/lib/spaceship/tunes/tester.rb +14 -15
- data/lib/spaceship/tunes/tunes_client.rb +61 -61
- data/lib/spaceship/ui.rb +1 -2
- data/lib/spaceship/version.rb +2 -2
- metadata +18 -2
@@ -16,12 +16,12 @@ module Spaceship
|
|
16
16
|
attr_accessor :uuid
|
17
17
|
|
18
18
|
# @return (DateTime) The date and time of when the profile
|
19
|
-
# expires.
|
19
|
+
# expires.
|
20
20
|
# @example
|
21
21
|
# #<DateTime: 2015-11-25T22:45:50+00:00 ((2457352j,81950s,0n),+0s,2299161j)>
|
22
22
|
attr_accessor :expires
|
23
23
|
|
24
|
-
# @return (String) The profile distribution type. You probably want to
|
24
|
+
# @return (String) The profile distribution type. You probably want to
|
25
25
|
# use the class type to detect the profile type instead of this string.
|
26
26
|
# @example AppStore Profile
|
27
27
|
# "store"
|
@@ -45,7 +45,7 @@ module Spaceship
|
|
45
45
|
# "Invalid"
|
46
46
|
attr_accessor :status
|
47
47
|
|
48
|
-
# @return (String) The type of the profile (development or distribution).
|
48
|
+
# @return (String) The type of the profile (development or distribution).
|
49
49
|
# You'll probably not need this value
|
50
50
|
# @example Distribution
|
51
51
|
# "iOS Distribution"
|
@@ -69,7 +69,7 @@ module Spaceship
|
|
69
69
|
# A reference to the app this profile is for.
|
70
70
|
# You can then easily access the value directly
|
71
71
|
# @return (App) The app this profile is for
|
72
|
-
#
|
72
|
+
#
|
73
73
|
# @example Example Value
|
74
74
|
# <Spaceship::App
|
75
75
|
# @app_id="2UMR2S6PAA"
|
@@ -80,7 +80,7 @@ module Spaceship
|
|
80
80
|
# @is_wildcard=false
|
81
81
|
# @dev_push_enabled=false
|
82
82
|
# @prod_push_enabled=false>
|
83
|
-
#
|
83
|
+
#
|
84
84
|
# @example Usage
|
85
85
|
# profile.app.name
|
86
86
|
attr_accessor :app
|
@@ -99,14 +99,14 @@ module Spaceship
|
|
99
99
|
# @owner_id=nil
|
100
100
|
# @type_display_id="R58UK2EWAA">]
|
101
101
|
# ]
|
102
|
-
#
|
102
|
+
#
|
103
103
|
# @example Usage
|
104
104
|
# profile.certificates.first.id
|
105
105
|
attr_accessor :certificates
|
106
106
|
|
107
107
|
# @return (Array) A list of devices this profile is enabled for.
|
108
108
|
# This will always be [] for AppStore profiles
|
109
|
-
#
|
109
|
+
#
|
110
110
|
# @example Example Value
|
111
111
|
# <Spaceship::Device
|
112
112
|
# @id="WXQ7V239BE"
|
@@ -114,7 +114,7 @@ module Spaceship
|
|
114
114
|
# @udid="ba0ac7d70f7a14c6fa02ef0e02f4fe9c5178e2f7"
|
115
115
|
# @platform="ios"
|
116
116
|
# @status="c">]
|
117
|
-
#
|
117
|
+
#
|
118
118
|
# @example Usage
|
119
119
|
# profile.devices.first.name
|
120
120
|
attr_accessor :devices
|
@@ -204,7 +204,7 @@ module Spaceship
|
|
204
204
|
|
205
205
|
devices = [] if (self == AppStore or self == InHouse) # App Store Profiles MUST NOT have devices
|
206
206
|
|
207
|
-
certificate_parameter = certificate.collect { |c| c.id } if certificate.kind_of?Array
|
207
|
+
certificate_parameter = certificate.collect { |c| c.id } if certificate.kind_of? Array
|
208
208
|
certificate_parameter ||= [certificate.id]
|
209
209
|
|
210
210
|
# Fix https://github.com/KrauseFx/fastlane/issues/349
|
@@ -217,29 +217,19 @@ module Spaceship
|
|
217
217
|
end
|
218
218
|
end
|
219
219
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
retry
|
227
|
-
end
|
228
|
-
|
229
|
-
raise ex # re-raise the exception
|
220
|
+
profile = client.with_retry do
|
221
|
+
client.create_provisioning_profile!(name,
|
222
|
+
self.type,
|
223
|
+
app.app_id,
|
224
|
+
certificate_parameter,
|
225
|
+
devices.map {|d| d.id} )
|
230
226
|
end
|
231
227
|
|
232
|
-
profile = send_create_request(name,
|
233
|
-
self.type,
|
234
|
-
app.app_id,
|
235
|
-
certificate_parameter,
|
236
|
-
devices.map {|d| d.id} )
|
237
|
-
|
238
228
|
self.new(profile)
|
239
229
|
end
|
240
230
|
|
241
231
|
# @return (Array) Returns all profiles registered for this account
|
242
|
-
# If you're calling this from a subclass (like AdHoc), this will
|
232
|
+
# If you're calling this from a subclass (like AdHoc), this will
|
243
233
|
# only return the profiles that are of this type
|
244
234
|
def all
|
245
235
|
profiles = client.provisioning_profiles.map do |profile|
|
@@ -317,7 +307,7 @@ module Spaceship
|
|
317
307
|
|
318
308
|
# Repair an existing provisioning profile
|
319
309
|
# alias to update!
|
320
|
-
# @return (ProvisioningProfile) A new provisioning profile, as
|
310
|
+
# @return (ProvisioningProfile) A new provisioning profile, as
|
321
311
|
# the repair method will generate a profile with a new ID
|
322
312
|
def repair!
|
323
313
|
update!
|
@@ -326,56 +316,40 @@ module Spaceship
|
|
326
316
|
# Updates the provisioning profile from the local data
|
327
317
|
# e.g. after you added new devices to the profile
|
328
318
|
# This will also update the code signing identity if necessary
|
329
|
-
# @return (ProvisioningProfile) A new provisioning profile, as
|
319
|
+
# @return (ProvisioningProfile) A new provisioning profile, as
|
330
320
|
# the repair method will generate a profile with a new ID
|
331
321
|
def update!
|
332
322
|
unless certificate_valid?
|
333
|
-
if self.kind_of?Development
|
323
|
+
if self.kind_of? Development
|
334
324
|
self.certificates = [Spaceship::Certificate::Development.all.first]
|
335
|
-
elsif self.kind_of?InHouse
|
325
|
+
elsif self.kind_of? InHouse
|
336
326
|
self.certificates = [Spaceship::Certificate::InHouse.all.first]
|
337
327
|
else
|
338
|
-
self.certificates = [Spaceship::Certificate::Production.all.first]
|
328
|
+
self.certificates = [Spaceship::Certificate::Production.all.first]
|
339
329
|
end
|
340
330
|
end
|
341
331
|
|
342
|
-
|
343
|
-
tries ||= 5
|
332
|
+
client.with_retry do
|
344
333
|
client.repair_provisioning_profile!(
|
345
334
|
id,
|
346
335
|
name,
|
347
336
|
distribution_method,
|
348
|
-
app_id,
|
349
|
-
certificates,
|
350
|
-
devices
|
337
|
+
app.app_id,
|
338
|
+
certificates.map { |c| c.id },
|
339
|
+
devices.map { |d| d.id }
|
351
340
|
)
|
352
|
-
rescue => ex
|
353
|
-
unless (tries -= 1).zero?
|
354
|
-
sleep 3
|
355
|
-
retry
|
356
|
-
end
|
357
|
-
raise ex # re-raise the exception
|
358
341
|
end
|
359
342
|
|
360
|
-
send_update_request(
|
361
|
-
self.id,
|
362
|
-
self.name,
|
363
|
-
self.distribution_method,
|
364
|
-
self.app.app_id,
|
365
|
-
self.certificates.map { |c| c.id },
|
366
|
-
self.devices.map { |d| d.id }
|
367
|
-
)
|
368
|
-
|
369
343
|
# We need to fetch the provisioning profile again, as the ID changes
|
370
|
-
profile = Spaceship::ProvisioningProfile.all.find do |
|
371
|
-
|
344
|
+
profile = Spaceship::ProvisioningProfile.all.find do |p|
|
345
|
+
p.name == self.name # we can use the name as it's valid
|
372
346
|
end
|
373
347
|
|
374
348
|
return profile
|
375
349
|
end
|
376
350
|
|
377
351
|
# Is the certificate of this profile available?
|
378
|
-
# @return (Bool) is the certificate valid?
|
352
|
+
# @return (Bool) is the certificate valid?
|
379
353
|
def certificate_valid?
|
380
354
|
return false if (certificates || []).count == 0
|
381
355
|
certificates.each do |c|
|
@@ -8,30 +8,30 @@ module Spaceship
|
|
8
8
|
# Authenticates with Apple's web services. This method has to be called once
|
9
9
|
# to generate a valid session. The session will automatically be used from then
|
10
10
|
# on.
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# This method will automatically use the username from the Appfile (if available)
|
13
13
|
# and fetch the password from the Keychain (if available)
|
14
|
-
#
|
14
|
+
#
|
15
15
|
# @param user (String) (optional): The username (usually the email address)
|
16
16
|
# @param password (String) (optional): The password
|
17
|
-
#
|
17
|
+
#
|
18
18
|
# @raise InvalidUserCredentialsError: raised if authentication failed
|
19
|
-
#
|
19
|
+
#
|
20
20
|
# @return (Spaceship::Client) The client the login method was called for
|
21
21
|
def login(user = nil, password = nil)
|
22
22
|
@client = PortalClient.login(user, password)
|
23
23
|
end
|
24
24
|
|
25
25
|
# Open up the team selection for the user (if necessary).
|
26
|
-
#
|
26
|
+
#
|
27
27
|
# If the user is in multiple teams, a team selection is shown.
|
28
28
|
# The user can then select a team by entering the number
|
29
|
-
#
|
29
|
+
#
|
30
30
|
# Additionally, the team ID is shown next to each team name
|
31
31
|
# so that the user can use the environment variable `FASTLANE_TEAM_ID`
|
32
32
|
# for future user.
|
33
|
-
#
|
34
|
-
# @return (String) The ID of the select team. You also get the value if
|
33
|
+
#
|
34
|
+
# @return (String) The ID of the select team. You also get the value if
|
35
35
|
# the user is only in one team.
|
36
36
|
def select_team
|
37
37
|
@client.select_team
|
@@ -44,6 +44,16 @@ module Spaceship
|
|
44
44
|
Spaceship::App.set_client(@client)
|
45
45
|
end
|
46
46
|
|
47
|
+
# @return (Class) Access the app groups for the spaceship
|
48
|
+
def app_group
|
49
|
+
Spaceship::AppGroup.set_client(@client)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return (Class) Access app services for the spaceship
|
53
|
+
def app_service
|
54
|
+
Spaceship::AppService
|
55
|
+
end
|
56
|
+
|
47
57
|
# @return (Class) Access the devices for the spaceship
|
48
58
|
def device
|
49
59
|
Spaceship::Device.set_client(@client)
|
@@ -75,6 +85,14 @@ module Spaceship
|
|
75
85
|
Spaceship::Portal.app
|
76
86
|
end
|
77
87
|
|
88
|
+
def app_group
|
89
|
+
Spaceship::Portal.app_group
|
90
|
+
end
|
91
|
+
|
92
|
+
def app_service
|
93
|
+
Spaceship::Portal.app_service
|
94
|
+
end
|
95
|
+
|
78
96
|
def device
|
79
97
|
Spaceship::Portal.device
|
80
98
|
end
|
@@ -91,4 +109,4 @@ module Spaceship
|
|
91
109
|
Spaceship::Portal.client
|
92
110
|
end
|
93
111
|
end
|
94
|
-
end
|
112
|
+
end
|
@@ -8,11 +8,11 @@ module Spaceship
|
|
8
8
|
# "type"=>"Company/Organization",
|
9
9
|
# "extendedTeamAttributes"=>{},
|
10
10
|
# "teamAgent"=>{
|
11
|
-
# "personId"=>15534241111,
|
12
|
-
# "firstName"=>"Felix",
|
13
|
-
# "lastName"=>"Krause",
|
14
|
-
# "email"=>"spaceship@krausefx.com",
|
15
|
-
# "developerStatus"=>"active",
|
11
|
+
# "personId"=>15534241111,
|
12
|
+
# "firstName"=>"Felix",
|
13
|
+
# "lastName"=>"Krause",
|
14
|
+
# "email"=>"spaceship@krausefx.com",
|
15
|
+
# "developerStatus"=>"active",
|
16
16
|
# "teamMemberId"=>"5Y354CXAAA"},
|
17
17
|
# "memberships"=>
|
18
18
|
# [{"membershipId"=>"HJ5WHYC5CE",
|
@@ -57,10 +57,8 @@ module Spaceship
|
|
57
57
|
puts "Couldn't find team with Name '#{team_name}'"
|
58
58
|
end
|
59
59
|
|
60
|
-
|
61
60
|
return teams[0]['teamId'] if teams.count == 1 # user is just in one team
|
62
61
|
|
63
|
-
|
64
62
|
# User Selection
|
65
63
|
loop do
|
66
64
|
# Multiple teams, user has to select
|
@@ -77,4 +75,4 @@ module Spaceship
|
|
77
75
|
end
|
78
76
|
end
|
79
77
|
end
|
80
|
-
end
|
78
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Spaceship
|
2
2
|
module Tunes
|
3
3
|
# Defines the different states of the app
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# As specified by Apple: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/ChangingAppStatus.html
|
6
6
|
module AppStatus
|
7
7
|
# You can edit this version, upload new binaries and more
|
@@ -23,7 +23,7 @@ module Spaceship
|
|
23
23
|
DEVELOPER_REMOVED_FROM_SALE = "Developer Removed From Sale"
|
24
24
|
|
25
25
|
# Developer rejected this version/binary
|
26
|
-
DEVELOPER_REJECTED = "Developer Rejected"
|
26
|
+
DEVELOPER_REJECTED = "Developer Rejected"
|
27
27
|
|
28
28
|
# You have to renew your Apple account to keep using iTunes Connect
|
29
29
|
PENDING_CONTRACT = "Pending Contract"
|
@@ -34,13 +34,12 @@ module Spaceship
|
|
34
34
|
|
35
35
|
# Unused app states
|
36
36
|
# PENDING_APPLE_RELASE = "Pending Apple Release"
|
37
|
-
|
37
|
+
|
38
38
|
# WAITING_FOR_EXPORT_COMPLIANCE = "Waiting For Export Compliance"
|
39
39
|
# METADATA_REJECTED = "Metadata Rejected"
|
40
40
|
# REMOVED_FROM_SALE = "Removed From Sale"
|
41
41
|
# INVALID_BINARY = "Invalid Binary"
|
42
42
|
|
43
|
-
|
44
43
|
# Get the app status matching based on a string (given by iTunes Connect)
|
45
44
|
def self.get_from_string(text)
|
46
45
|
mapping = {
|
@@ -52,7 +51,7 @@ module Spaceship
|
|
52
51
|
'waitingForReview' => WAITING_FOR_REVIEW
|
53
52
|
}
|
54
53
|
|
55
|
-
mapping.each do |k, v|
|
54
|
+
mapping.each do |k, v|
|
56
55
|
return v if k == text
|
57
56
|
end
|
58
57
|
|
@@ -60,4 +59,4 @@ module Spaceship
|
|
60
59
|
end
|
61
60
|
end
|
62
61
|
end
|
63
|
-
end
|
62
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
module Spaceship
|
2
3
|
module Tunes
|
3
4
|
# Represents a submission for review of an iTunes Connect Application
|
@@ -9,61 +10,61 @@ module Spaceship
|
|
9
10
|
|
10
11
|
# @return (AppVersion) The version to use for this submission
|
11
12
|
attr_accessor :version
|
12
|
-
|
13
|
+
|
13
14
|
# @return (String) The stage of this submission (start, complete)
|
14
15
|
attr_accessor :stage
|
15
|
-
|
16
|
+
|
16
17
|
# @return (Boolean) Submitted for Review
|
17
18
|
attr_accessor :submitted_for_review
|
18
19
|
|
19
20
|
# @return (Boolean) Ad ID Info - Limits ads tracking
|
20
21
|
attr_accessor :add_id_info_limits_tracking
|
21
|
-
|
22
|
+
|
22
23
|
# @return (Boolean) Ad ID Info - Serves ads
|
23
24
|
attr_accessor :add_id_info_serves_ads
|
24
|
-
|
25
|
+
|
25
26
|
# @return (Boolean) Ad ID Info - Tracks actions
|
26
27
|
attr_accessor :add_id_info_tracks_action
|
27
|
-
|
28
|
+
|
28
29
|
# @return (Boolean) Ad ID Info - Tracks installs
|
29
30
|
attr_accessor :add_id_info_tracks_install
|
30
|
-
|
31
|
+
|
31
32
|
# @return (Boolean) Ad ID Info - Uses idfa
|
32
33
|
attr_accessor :add_id_info_uses_idfa
|
33
|
-
|
34
|
+
|
34
35
|
# @return (Boolean) Content Rights - Contains third party content
|
35
36
|
attr_accessor :content_rights_contains_third_party_content
|
36
|
-
|
37
|
+
|
37
38
|
# @return (Boolean) Content Rights - Has rights of content
|
38
39
|
attr_accessor :content_rights_has_rights
|
39
|
-
|
40
|
+
|
40
41
|
# @return (Boolean) Export Compliance - Available on French Store
|
41
42
|
attr_accessor :export_compliance_available_on_french_store
|
42
|
-
|
43
|
+
|
43
44
|
# @return (Not Yet Implemented) Export Compliance - CCAT File
|
44
45
|
attr_accessor :export_compliance_ccat_file
|
45
|
-
|
46
|
+
|
46
47
|
# @return (Boolean) Export Compliance - Contains proprietary cryptography
|
47
48
|
attr_accessor :export_compliance_contains_proprietary_cryptography
|
48
|
-
|
49
|
+
|
49
50
|
# @return (Boolean) Export Compliance - Contains third-party cryptography
|
50
51
|
attr_accessor :export_compliance_contains_third_party_cryptography
|
51
|
-
|
52
|
+
|
52
53
|
# @return (Boolean) Export Compliance - Is exempt
|
53
54
|
attr_accessor :export_compliance_is_exempt
|
54
|
-
|
55
|
+
|
55
56
|
# @return (Boolean) Export Compliance - Uses encryption
|
56
57
|
attr_accessor :export_compliance_uses_encryption
|
57
58
|
|
58
59
|
# @return (String) Export Compliance - App type
|
59
60
|
attr_accessor :export_compliance_app_type
|
60
|
-
|
61
|
+
|
61
62
|
# @return (Boolean) Export Compliance - Encryption Updated
|
62
63
|
attr_accessor :export_compliance_encryption_updated
|
63
|
-
|
64
|
+
|
64
65
|
# @return (Boolean) Export Compliance - Compliance Required
|
65
66
|
attr_accessor :export_compliance_compliance_required
|
66
|
-
|
67
|
+
|
67
68
|
# @return (String) Export Compliance - Platform
|
68
69
|
attr_accessor :export_compliance_platform
|
69
70
|
|
@@ -75,11 +76,11 @@ module Spaceship
|
|
75
76
|
'adIdInfo.tracksAction.value' => :add_id_info_tracks_action,
|
76
77
|
'adIdInfo.tracksInstall.value' => :add_id_info_tracks_install,
|
77
78
|
'adIdInfo.usesIdfa.value' => :add_id_info_uses_idfa,
|
78
|
-
|
79
|
+
|
79
80
|
# Content Rights Section
|
80
81
|
'contentRights.containsThirdPartyContent.value' => :content_rights_contains_third_party_content,
|
81
82
|
'contentRights.hasRights.value' => :content_rights_has_rights,
|
82
|
-
|
83
|
+
|
83
84
|
# Export Compliance Section
|
84
85
|
'exportCompliance.availableOnFrenchStore.value' => :export_compliance_available_on_french_store,
|
85
86
|
'exportCompliance.ccatFile.value' => :export_compliance_ccat_file,
|
@@ -98,7 +99,7 @@ module Spaceship
|
|
98
99
|
# This is used to create a new object based on the server response.
|
99
100
|
def factory(attrs)
|
100
101
|
orig = attrs.dup
|
101
|
-
|
102
|
+
|
102
103
|
# fill content rights section if iTC returns nil
|
103
104
|
if attrs["contentRights"].nil?
|
104
105
|
attrs.merge!("contentRights" => {
|
@@ -110,11 +111,11 @@ module Spaceship
|
|
110
111
|
}
|
111
112
|
})
|
112
113
|
end
|
113
|
-
|
114
|
+
|
114
115
|
obj = self.new(attrs)
|
115
116
|
return obj
|
116
117
|
end
|
117
|
-
|
118
|
+
|
118
119
|
# @param application (Spaceship::Tunes::Application) The app this submission is for
|
119
120
|
# @param app_id (String) The unique Apple ID of this app
|
120
121
|
def create(application, app_id, version)
|
@@ -127,7 +128,7 @@ module Spaceship
|
|
127
128
|
return self.factory(attrs)
|
128
129
|
end
|
129
130
|
end
|
130
|
-
|
131
|
+
|
131
132
|
# Save and complete the app submission
|
132
133
|
def complete!
|
133
134
|
@stage = "complete"
|