spaceship 0.0.15 → 0.1.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/lib/assets/languageMapping.json +224 -0
- data/lib/spaceship.rb +20 -63
- data/lib/spaceship/base.rb +71 -14
- data/lib/spaceship/client.rb +9 -274
- data/lib/spaceship/launcher.rb +1 -1
- data/lib/spaceship/portal/app.rb +125 -0
- data/lib/spaceship/portal/certificate.rb +273 -0
- data/lib/spaceship/portal/device.rb +102 -0
- data/lib/spaceship/portal/portal.rb +6 -0
- data/lib/spaceship/portal/portal_base.rb +13 -0
- data/lib/spaceship/portal/portal_client.rb +289 -0
- data/lib/spaceship/portal/provisioning_profile.rb +369 -0
- data/lib/spaceship/portal/spaceship.rb +94 -0
- data/lib/spaceship/{ui → portal/ui}/select_team.rb +0 -0
- data/lib/spaceship/tunes/app_screenshot.rb +28 -0
- data/lib/spaceship/tunes/app_status.rb +63 -0
- data/lib/spaceship/tunes/app_submission.rb +149 -0
- data/lib/spaceship/tunes/app_version.rb +337 -0
- data/lib/spaceship/tunes/application.rb +253 -0
- data/lib/spaceship/tunes/build.rb +128 -0
- data/lib/spaceship/tunes/build_train.rb +79 -0
- data/lib/spaceship/tunes/language_converter.rb +44 -0
- data/lib/spaceship/tunes/language_item.rb +54 -0
- data/lib/spaceship/tunes/processing_build.rb +30 -0
- data/lib/spaceship/tunes/spaceship.rb +26 -0
- data/lib/spaceship/tunes/tester.rb +177 -0
- data/lib/spaceship/tunes/tunes.rb +12 -0
- data/lib/spaceship/tunes/tunes_base.rb +15 -0
- data/lib/spaceship/tunes/tunes_client.rb +360 -0
- data/lib/spaceship/version.rb +1 -1
- metadata +27 -7
- data/lib/spaceship/app.rb +0 -125
- data/lib/spaceship/certificate.rb +0 -271
- data/lib/spaceship/device.rb +0 -100
- data/lib/spaceship/provisioning_profile.rb +0 -367
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.0
|
4
|
+
version: 0.1.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-
|
12
|
+
date: 2015-07-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: credentials_manager
|
@@ -204,18 +204,38 @@ extra_rdoc_files: []
|
|
204
204
|
files:
|
205
205
|
- LICENSE
|
206
206
|
- README.md
|
207
|
+
- lib/assets/languageMapping.json
|
207
208
|
- lib/spaceship.rb
|
208
|
-
- lib/spaceship/app.rb
|
209
209
|
- lib/spaceship/base.rb
|
210
|
-
- lib/spaceship/certificate.rb
|
211
210
|
- lib/spaceship/client.rb
|
212
|
-
- lib/spaceship/device.rb
|
213
211
|
- lib/spaceship/helper/net_http_generic_request.rb
|
214
212
|
- lib/spaceship/helper/plist_middleware.rb
|
215
213
|
- lib/spaceship/launcher.rb
|
216
|
-
- lib/spaceship/
|
214
|
+
- lib/spaceship/portal/app.rb
|
215
|
+
- lib/spaceship/portal/certificate.rb
|
216
|
+
- lib/spaceship/portal/device.rb
|
217
|
+
- lib/spaceship/portal/portal.rb
|
218
|
+
- lib/spaceship/portal/portal_base.rb
|
219
|
+
- lib/spaceship/portal/portal_client.rb
|
220
|
+
- lib/spaceship/portal/provisioning_profile.rb
|
221
|
+
- lib/spaceship/portal/spaceship.rb
|
222
|
+
- lib/spaceship/portal/ui/select_team.rb
|
223
|
+
- lib/spaceship/tunes/app_screenshot.rb
|
224
|
+
- lib/spaceship/tunes/app_status.rb
|
225
|
+
- lib/spaceship/tunes/app_submission.rb
|
226
|
+
- lib/spaceship/tunes/app_version.rb
|
227
|
+
- lib/spaceship/tunes/application.rb
|
228
|
+
- lib/spaceship/tunes/build.rb
|
229
|
+
- lib/spaceship/tunes/build_train.rb
|
230
|
+
- lib/spaceship/tunes/language_converter.rb
|
231
|
+
- lib/spaceship/tunes/language_item.rb
|
232
|
+
- lib/spaceship/tunes/processing_build.rb
|
233
|
+
- lib/spaceship/tunes/spaceship.rb
|
234
|
+
- lib/spaceship/tunes/tester.rb
|
235
|
+
- lib/spaceship/tunes/tunes.rb
|
236
|
+
- lib/spaceship/tunes/tunes_base.rb
|
237
|
+
- lib/spaceship/tunes/tunes_client.rb
|
217
238
|
- lib/spaceship/ui.rb
|
218
|
-
- lib/spaceship/ui/select_team.rb
|
219
239
|
- lib/spaceship/version.rb
|
220
240
|
homepage: https://fastlane.tools
|
221
241
|
licenses:
|
data/lib/spaceship/app.rb
DELETED
@@ -1,125 +0,0 @@
|
|
1
|
-
module Spaceship
|
2
|
-
# Represents an App ID from the Developer Portal
|
3
|
-
class App < Base
|
4
|
-
|
5
|
-
# @return (String) The identifier of this app, provided by the Dev Portal
|
6
|
-
# @example
|
7
|
-
# "RGAWZGXSAA"
|
8
|
-
attr_accessor :app_id
|
9
|
-
|
10
|
-
# @return (String) The name you provided for this app
|
11
|
-
# @example
|
12
|
-
# "Spaceship"
|
13
|
-
attr_accessor :name
|
14
|
-
|
15
|
-
# @return (String) the supported platform of this app
|
16
|
-
# @example
|
17
|
-
# "ios"
|
18
|
-
attr_accessor :platform
|
19
|
-
|
20
|
-
# Prefix provided by the Dev Portal
|
21
|
-
# @example
|
22
|
-
# "5A997XSHK2"
|
23
|
-
attr_accessor :prefix
|
24
|
-
|
25
|
-
# @return (String) The bundle_id (app identifier) of your app
|
26
|
-
# @example
|
27
|
-
# "com.krausefx.app"
|
28
|
-
attr_accessor :bundle_id
|
29
|
-
|
30
|
-
# @return (Bool) Is this app a wildcard app (e.g. com.krausefx.*)
|
31
|
-
attr_accessor :is_wildcard
|
32
|
-
|
33
|
-
# @return (Hash) Feature details
|
34
|
-
attr_accessor :features
|
35
|
-
|
36
|
-
# @return (Array) List of enabled features
|
37
|
-
attr_accessor :enabled_features
|
38
|
-
|
39
|
-
# @return (Bool) Development Push Enabled?
|
40
|
-
attr_accessor :dev_push_enabled
|
41
|
-
|
42
|
-
# @return (Bool) Production Push Enabled?
|
43
|
-
attr_accessor :prod_push_enabled
|
44
|
-
|
45
|
-
# @return (Fixnum) Number of associated app groups
|
46
|
-
attr_accessor :app_groups_count
|
47
|
-
|
48
|
-
# @return (Fixnum) Number of associated cloud containers
|
49
|
-
attr_accessor :cloud_containers_count
|
50
|
-
|
51
|
-
# @return (Fixnum) Number of associated identifiers
|
52
|
-
attr_accessor :identifiers_count
|
53
|
-
|
54
|
-
attr_mapping(
|
55
|
-
'appIdId' => :app_id,
|
56
|
-
'name' => :name,
|
57
|
-
'appIdPlatform' => :platform,
|
58
|
-
'prefix' => :prefix,
|
59
|
-
'identifier' => :bundle_id,
|
60
|
-
'isWildCard' => :is_wildcard,
|
61
|
-
'features' => :features,
|
62
|
-
'enabledFeatures' => :enabled_features,
|
63
|
-
'isDevPushEnabled' => :dev_push_enabled,
|
64
|
-
'isProdPushEnabled' => :prod_push_enabled,
|
65
|
-
'associatedApplicationGroupsCount' => :app_groups_count,
|
66
|
-
'associatedCloudContainersCount' => :cloud_containers_count,
|
67
|
-
'associatedIdentifiersCount' => :identifiers_count
|
68
|
-
|
69
|
-
)
|
70
|
-
|
71
|
-
class << self
|
72
|
-
# Create a new object based on a hash.
|
73
|
-
# This is used to create a new object based on the server response.
|
74
|
-
def factory(attrs)
|
75
|
-
self.new(attrs)
|
76
|
-
end
|
77
|
-
|
78
|
-
# @return (Array) Returns all apps available for this account
|
79
|
-
def all
|
80
|
-
client.apps.map { |app| self.factory(app) }
|
81
|
-
end
|
82
|
-
|
83
|
-
# Creates a new App ID on the Apple Dev Portal
|
84
|
-
#
|
85
|
-
# if bundle_id ends with '*' then it is a wildcard id otherwise, it is an explicit id
|
86
|
-
# @param bundle_id [String] the bundle id (app_identifier) of the app associated with this provisioning profile
|
87
|
-
# @param name [String] the name of the App
|
88
|
-
# @return (App) The app you just created
|
89
|
-
def create!(bundle_id: nil, name: nil)
|
90
|
-
if bundle_id.end_with?('*')
|
91
|
-
type = :wildcard
|
92
|
-
else
|
93
|
-
type = :explicit
|
94
|
-
end
|
95
|
-
|
96
|
-
new_app = client.create_app!(type, name, bundle_id)
|
97
|
-
self.new(new_app)
|
98
|
-
end
|
99
|
-
|
100
|
-
# Find a specific App ID based on the bundle_id
|
101
|
-
# @return (App) The app you're looking for. This is nil if the app can't be found.
|
102
|
-
def find(bundle_id)
|
103
|
-
all.find do |app|
|
104
|
-
app.bundle_id == bundle_id
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
# Delete this App ID. This action will most likely fail if the App ID is already in the store
|
110
|
-
# or there are active profiles
|
111
|
-
# @return (App) The app you just deletd
|
112
|
-
def delete!
|
113
|
-
client.delete_app!(app_id)
|
114
|
-
self
|
115
|
-
end
|
116
|
-
|
117
|
-
# Fetch a specific App ID details based on the bundle_id
|
118
|
-
# @return (App) The app you're looking for. This is nil if the app can't be found.
|
119
|
-
def details
|
120
|
-
app = client.details_for_app(self)
|
121
|
-
self.class.factory(app)
|
122
|
-
end
|
123
|
-
|
124
|
-
end
|
125
|
-
end
|
@@ -1,271 +0,0 @@
|
|
1
|
-
require 'openssl'
|
2
|
-
|
3
|
-
module Spaceship
|
4
|
-
# Represents a certificate from the Apple Developer Portal.
|
5
|
-
#
|
6
|
-
# This can either be a code signing identity or a push profile
|
7
|
-
class Certificate < Base
|
8
|
-
# @return (String) The ID given from the developer portal. You'll probably not need it.
|
9
|
-
# @example
|
10
|
-
# "P577TH3PAA"
|
11
|
-
attr_accessor :id
|
12
|
-
|
13
|
-
# @return (String) The name of the certificate
|
14
|
-
# @example Company
|
15
|
-
# "SunApps GmbH"
|
16
|
-
# @example Push Profile
|
17
|
-
# "com.krausefx.app"
|
18
|
-
attr_accessor :name
|
19
|
-
|
20
|
-
# @return (String) Status of the certificate
|
21
|
-
# @example
|
22
|
-
# "Issued"
|
23
|
-
attr_accessor :status
|
24
|
-
|
25
|
-
# @return (Date) The date and time when the certificate was created
|
26
|
-
# @example
|
27
|
-
# 2015-04-01 21:24:00 UTC
|
28
|
-
attr_accessor :created
|
29
|
-
|
30
|
-
# @return (Date) The date and time when the certificate will expire
|
31
|
-
# @example
|
32
|
-
# 2016-04-01 21:24:00 UTC
|
33
|
-
attr_accessor :expires
|
34
|
-
|
35
|
-
# @return (String) The owner type that defines if it's a push profile
|
36
|
-
# or a code signing identity
|
37
|
-
#
|
38
|
-
# @example Code Signing Identity
|
39
|
-
# "team"
|
40
|
-
# @example Push Certificate
|
41
|
-
# "bundle"
|
42
|
-
attr_accessor :owner_type
|
43
|
-
|
44
|
-
# @return (String) The name of the owner
|
45
|
-
#
|
46
|
-
# @example Code Signing Identity (usually the company name)
|
47
|
-
# "SunApps Gmbh"
|
48
|
-
# @example Push Certificate (the name of your App ID)
|
49
|
-
# "Awesome App"
|
50
|
-
attr_accessor :owner_name
|
51
|
-
|
52
|
-
# @return (String) The ID of the owner, that can be used to
|
53
|
-
# fetch more information
|
54
|
-
# @example
|
55
|
-
# "75B83SPLAA"
|
56
|
-
attr_accessor :owner_id
|
57
|
-
|
58
|
-
# Indicates the type of this certificate
|
59
|
-
# which is automatically used to determine the class of
|
60
|
-
# the certificate. Available values listed in CERTIFICATE_TYPE_IDS
|
61
|
-
# @return (String) The type of the certificate
|
62
|
-
# @example Production Certificate
|
63
|
-
# "R58UK2EWSO"
|
64
|
-
# @example Development Certificate
|
65
|
-
# "5QPB9NHCEI"
|
66
|
-
attr_accessor :type_display_id
|
67
|
-
|
68
|
-
attr_mapping({
|
69
|
-
'certificateId' => :id,
|
70
|
-
'name' => :name,
|
71
|
-
'statusString' => :status,
|
72
|
-
'dateCreated' => :created,
|
73
|
-
'expirationDate' => :expires,
|
74
|
-
'ownerType' => :owner_type,
|
75
|
-
'ownerName' => :owner_name,
|
76
|
-
'ownerId' => :owner_id,
|
77
|
-
'certificateTypeDisplayId' => :type_display_id
|
78
|
-
})
|
79
|
-
|
80
|
-
#####################################################
|
81
|
-
# Certs are not associated with apps
|
82
|
-
#####################################################
|
83
|
-
|
84
|
-
# A development code signing certificate used for development environment
|
85
|
-
class Development < Certificate; end
|
86
|
-
|
87
|
-
# A production code signing certificate used for distribution environment
|
88
|
-
class Production < Certificate; end
|
89
|
-
|
90
|
-
# An In House code signing certificate used for enterprise distributions
|
91
|
-
class InHouse < Certificate; end
|
92
|
-
|
93
|
-
#####################################################
|
94
|
-
# Certs that are specific for one app
|
95
|
-
#####################################################
|
96
|
-
|
97
|
-
# Abstract class for push certificates. Check out the subclasses
|
98
|
-
# DevelopmentPush, ProductionPush, WebsitePush and VoipPush
|
99
|
-
class PushCertificate < Certificate; end
|
100
|
-
|
101
|
-
# A push notification certificate for development environment
|
102
|
-
class DevelopmentPush < PushCertificate; end
|
103
|
-
|
104
|
-
# A push notification certificate for production environment
|
105
|
-
class ProductionPush < PushCertificate; end
|
106
|
-
|
107
|
-
# A push notification certificate for websites
|
108
|
-
class WebsitePush < PushCertificate; end
|
109
|
-
|
110
|
-
# A push notification certificate for the VOIP environment
|
111
|
-
class VoipPush < PushCertificate; end
|
112
|
-
|
113
|
-
# Passbook certificate
|
114
|
-
class Passbook < Certificate; end
|
115
|
-
|
116
|
-
# ApplePay certificate
|
117
|
-
class ApplePay < Certificate; end
|
118
|
-
|
119
|
-
CERTIFICATE_TYPE_IDS = {
|
120
|
-
"5QPB9NHCEI" => Development,
|
121
|
-
"R58UK2EWSO" => Production,
|
122
|
-
"9RQEK7MSXA" => InHouse,
|
123
|
-
"LA30L5BJEU" => Certificate,
|
124
|
-
"BKLRAVXMGM" => DevelopmentPush,
|
125
|
-
"3BQKVH9I2X" => ProductionPush,
|
126
|
-
"Y3B2F3TYSI" => Passbook,
|
127
|
-
"3T2ZP62QW8" => WebsitePush,
|
128
|
-
"E5D663CMZW" => WebsitePush,
|
129
|
-
"4APLUP237T" => ApplePay
|
130
|
-
}
|
131
|
-
|
132
|
-
#class methods
|
133
|
-
class << self
|
134
|
-
# Create a new code signing request that can be used to
|
135
|
-
# generate a new certificate
|
136
|
-
# @example
|
137
|
-
# Create a new certificate signing request
|
138
|
-
# csr, pkey = Spaceship.certificate.create_certificate_signing_request
|
139
|
-
#
|
140
|
-
# # Use the signing request to create a new distribution certificate
|
141
|
-
# Spaceship.certificate.production.create!(csr: csr)
|
142
|
-
def create_certificate_signing_request
|
143
|
-
key = OpenSSL::PKey::RSA.new 2048
|
144
|
-
csr = OpenSSL::X509::Request.new
|
145
|
-
csr.version = 0
|
146
|
-
csr.subject = OpenSSL::X509::Name.new([
|
147
|
-
['CN', 'PEM', OpenSSL::ASN1::UTF8STRING]
|
148
|
-
])
|
149
|
-
csr.public_key = key.public_key
|
150
|
-
csr.sign(key, OpenSSL::Digest::SHA1.new)
|
151
|
-
return [csr, key]
|
152
|
-
end
|
153
|
-
|
154
|
-
# Create a new object based on a hash.
|
155
|
-
# This is used to create a new object based on the server response.
|
156
|
-
def factory(attrs)
|
157
|
-
# Example:
|
158
|
-
# => {"name"=>"iOS Distribution: SunApps GmbH",
|
159
|
-
# "certificateId"=>"XC5PH8DAAA",
|
160
|
-
# "serialNumber"=>"797E732CCE8B7AAA",
|
161
|
-
# "status"=>"Issued",
|
162
|
-
# "statusCode"=>0,
|
163
|
-
# "expirationDate"=>#<DateTime: 2015-11-25T22:45:50+00:00 ((2457352j,81950s,0n),+0s,2299161j)>,
|
164
|
-
# "certificatePlatform"=>"ios",
|
165
|
-
# "certificateType"=>
|
166
|
-
# {"certificateTypeDisplayId"=>"R58UK2EAAA",
|
167
|
-
# "name"=>"iOS Distribution",
|
168
|
-
# "platform"=>"ios",
|
169
|
-
# "permissionType"=>"distribution",
|
170
|
-
# "distributionType"=>"store",
|
171
|
-
# "distributionMethod"=>"app",
|
172
|
-
# "ownerType"=>"team",
|
173
|
-
# "daysOverlap"=>364,
|
174
|
-
# "maxActive"=>2}}
|
175
|
-
|
176
|
-
if attrs['certificateType']
|
177
|
-
# On some accounts this is nested, so we need to flatten it
|
178
|
-
attrs.merge!(attrs['certificateType'])
|
179
|
-
attrs.delete('certificateType')
|
180
|
-
end
|
181
|
-
|
182
|
-
# Parse the dates
|
183
|
-
attrs['expirationDate'] = (Time.parse(attrs['expirationDate']) rescue attrs['expirationDate'])
|
184
|
-
attrs['dateCreated'] = (Time.parse(attrs['dateCreated']) rescue attrs['dateCreated'])
|
185
|
-
|
186
|
-
# Here we go
|
187
|
-
klass = CERTIFICATE_TYPE_IDS[attrs['certificateTypeDisplayId']]
|
188
|
-
klass ||= Certificate
|
189
|
-
klass.client = @client
|
190
|
-
klass.new(attrs)
|
191
|
-
end
|
192
|
-
|
193
|
-
# @return (Array) Returns all certificates of this account.
|
194
|
-
# If this is called from a subclass of Certificate, this will
|
195
|
-
# only include certificates matching the current type.
|
196
|
-
def all
|
197
|
-
if (self == Certificate) # are we the base-class?
|
198
|
-
types = CERTIFICATE_TYPE_IDS.keys
|
199
|
-
else
|
200
|
-
types = [CERTIFICATE_TYPE_IDS.key(self)]
|
201
|
-
end
|
202
|
-
|
203
|
-
client.certificates(types).map do |cert|
|
204
|
-
factory(cert)
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
# @return (Certificate) Find a certificate based on the ID of the certificate.
|
209
|
-
def find(certificate_id)
|
210
|
-
all.find do |c|
|
211
|
-
c.id == certificate_id
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
# Generate a new certificate based on a code certificate signing request
|
216
|
-
# @param csr (OpenSSL::X509::Request) (required): The certificate signing request to use. Get one using
|
217
|
-
# `create_certificate_signing_request`
|
218
|
-
# @param bundle_id (String) (optional): The app identifier this certificate is for.
|
219
|
-
# This value is only needed if you create a push profile. For normal code signing
|
220
|
-
# certificates, you must only pass a certificate signing request.
|
221
|
-
# @example
|
222
|
-
# # Create a new certificate signing request
|
223
|
-
# csr, pkey = Spaceship::Certificate.create_certificate_signing_request
|
224
|
-
#
|
225
|
-
# # Use the signing request to create a new distribution certificate
|
226
|
-
# Spaceship::Certificate::Production.create!(csr: csr)
|
227
|
-
# @return (Device): The newly created device
|
228
|
-
def create!(csr: nil, bundle_id: nil)
|
229
|
-
type = CERTIFICATE_TYPE_IDS.key(self)
|
230
|
-
|
231
|
-
# look up the app_id by the bundle_id
|
232
|
-
if bundle_id
|
233
|
-
app = Spaceship::App.find(bundle_id)
|
234
|
-
raise "Could not find app with bundle id '#{bundle_id}'" unless app
|
235
|
-
app_id = app.app_id
|
236
|
-
end
|
237
|
-
|
238
|
-
# ensure csr is a OpenSSL::X509::Request
|
239
|
-
csr = OpenSSL::X509::Request.new(csr) if csr.is_a?(String)
|
240
|
-
|
241
|
-
# if this succeeds, we need to save the .cer and the private key in keychain access or wherever they go in linux
|
242
|
-
response = client.create_certificate!(type, csr.to_pem, app_id)
|
243
|
-
# munge the response to make it work for the factory
|
244
|
-
response['certificateTypeDisplayId'] = response['certificateType']['certificateTypeDisplayId']
|
245
|
-
self.new(response)
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
# instance methods
|
250
|
-
|
251
|
-
# @return (String) Download the raw data of the certificate without parsing
|
252
|
-
def download_raw
|
253
|
-
client.download_certificate(id, type_display_id)
|
254
|
-
end
|
255
|
-
|
256
|
-
# @return (OpenSSL::X509::Certificate) Downloads and parses the certificate
|
257
|
-
def download
|
258
|
-
OpenSSL::X509::Certificate.new(download_raw)
|
259
|
-
end
|
260
|
-
|
261
|
-
# Revoke the certificate. You shouldn't use this method probably.
|
262
|
-
def revoke!
|
263
|
-
client.revoke_certificate!(id, type_display_id)
|
264
|
-
end
|
265
|
-
|
266
|
-
# @return (Bool): Is this certificate a push profile for apps?
|
267
|
-
def is_push?
|
268
|
-
self.kind_of?PushCertificate
|
269
|
-
end
|
270
|
-
end
|
271
|
-
end
|