spaceship 0.0.15 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/assets/languageMapping.json +224 -0
  3. data/lib/spaceship.rb +20 -63
  4. data/lib/spaceship/base.rb +71 -14
  5. data/lib/spaceship/client.rb +9 -274
  6. data/lib/spaceship/launcher.rb +1 -1
  7. data/lib/spaceship/portal/app.rb +125 -0
  8. data/lib/spaceship/portal/certificate.rb +273 -0
  9. data/lib/spaceship/portal/device.rb +102 -0
  10. data/lib/spaceship/portal/portal.rb +6 -0
  11. data/lib/spaceship/portal/portal_base.rb +13 -0
  12. data/lib/spaceship/portal/portal_client.rb +289 -0
  13. data/lib/spaceship/portal/provisioning_profile.rb +369 -0
  14. data/lib/spaceship/portal/spaceship.rb +94 -0
  15. data/lib/spaceship/{ui → portal/ui}/select_team.rb +0 -0
  16. data/lib/spaceship/tunes/app_screenshot.rb +28 -0
  17. data/lib/spaceship/tunes/app_status.rb +63 -0
  18. data/lib/spaceship/tunes/app_submission.rb +149 -0
  19. data/lib/spaceship/tunes/app_version.rb +337 -0
  20. data/lib/spaceship/tunes/application.rb +253 -0
  21. data/lib/spaceship/tunes/build.rb +128 -0
  22. data/lib/spaceship/tunes/build_train.rb +79 -0
  23. data/lib/spaceship/tunes/language_converter.rb +44 -0
  24. data/lib/spaceship/tunes/language_item.rb +54 -0
  25. data/lib/spaceship/tunes/processing_build.rb +30 -0
  26. data/lib/spaceship/tunes/spaceship.rb +26 -0
  27. data/lib/spaceship/tunes/tester.rb +177 -0
  28. data/lib/spaceship/tunes/tunes.rb +12 -0
  29. data/lib/spaceship/tunes/tunes_base.rb +15 -0
  30. data/lib/spaceship/tunes/tunes_client.rb +360 -0
  31. data/lib/spaceship/version.rb +1 -1
  32. metadata +27 -7
  33. data/lib/spaceship/app.rb +0 -125
  34. data/lib/spaceship/certificate.rb +0 -271
  35. data/lib/spaceship/device.rb +0 -100
  36. data/lib/spaceship/provisioning_profile.rb +0 -367
@@ -0,0 +1,253 @@
1
+ module Spaceship
2
+ module Tunes
3
+ class Application < TunesBase
4
+
5
+ # @return (String) The App identifier of this app, provided by iTunes Connect
6
+ # @example
7
+ # "1013943394"
8
+ attr_accessor :apple_id
9
+
10
+ # @return (String) The name you provided for this app (in the default language)
11
+ # @example
12
+ # "Spaceship App"
13
+ attr_accessor :name
14
+
15
+ # @return (String) the supported platform of this app
16
+ # @example
17
+ # "ios"
18
+ attr_accessor :platform
19
+
20
+ # @return (String) The Vendor ID provided by iTunes Connect
21
+ # @example
22
+ # "1435592086"
23
+ attr_accessor :vendor_id
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 (String) Last modified
31
+ attr_accessor :last_modified
32
+
33
+ # @return (Integer) The number of issues provided by iTunes Connect
34
+ attr_accessor :issues_count
35
+
36
+ # @return (String) The URL to a low resolution app icon of this app (340x340px). Might be nil
37
+ # @example
38
+ # "https://is1-ssl.mzstatic.com/image/thumb/Purple7/v4/cd/a3/e2/cda3e2ac-4034-c6af-ee0c-3e4d9a0bafaa/pr_source.png/340x340bb-80.png"
39
+ # @example
40
+ # nil
41
+ attr_accessor :app_icon_preview_url
42
+
43
+ # @return [Array] A list of binaries which are not even yet processing based on the version
44
+ # Those builds are usually the ones that are just stuck on iTunes Connect...
45
+ attr_accessor :pre_processing_builds
46
+
47
+ attr_mapping(
48
+ 'adamId' => :apple_id,
49
+ 'name' => :name,
50
+ 'appType' => :platform,
51
+ 'vendorId' => :vendor_id,
52
+ 'bundleId' => :bundle_id,
53
+ 'lastModifiedDate' => :last_modified,
54
+ 'issuesCount' => :issues_count,
55
+ 'iconUrl' => :app_icon_preview_url
56
+ )
57
+
58
+ class << self
59
+ # Create a new object based on a hash.
60
+ # This is used to create a new object based on the server response.
61
+ def factory(attrs)
62
+ self.new(attrs)
63
+ end
64
+
65
+ # @return (Array) Returns all apps available for this account
66
+ def all
67
+ client.applications.map { |application| self.factory(application) }
68
+ end
69
+
70
+ # @return (Spaceship::Tunes::Application) Returns the application matching the parameter
71
+ # as either the App ID or the bundle identifier
72
+ def find(identifier)
73
+ all.find do |app|
74
+ (app.apple_id == identifier.to_s or app.bundle_id == identifier)
75
+ end
76
+ end
77
+
78
+ # Creates a new application on iTunes Connect
79
+ # @param name (String): The name of your app as it will appear on the App Store.
80
+ # This can't be longer than 255 characters.
81
+ # @param primary_language (String): If localized app information isn't available in an
82
+ # App Store territory, the information from your primary language will be used instead.
83
+ # @param version (String): The version number is shown on the App Store and should
84
+ # match the one you used in Xcode.
85
+ # @param sku (String): A unique ID for your app that is not visible on the App Store.
86
+ # @param bundle_id (String): The bundle ID must match the one you used in Xcode. It
87
+ # can't be changed after you submit your first build.
88
+ def create!(name: nil, primary_language: nil, version: nil, sku: nil, bundle_id: nil, bundle_id_suffix: nil)
89
+ client.create_application!(name: name,
90
+ primary_language: primary_language,
91
+ version: version,
92
+ sku: sku,
93
+ bundle_id: bundle_id,
94
+ bundle_id_suffix: bundle_id_suffix)
95
+ end
96
+ end
97
+
98
+ #####################################################
99
+ # @!group Getting information
100
+ #####################################################
101
+
102
+ # @return (Spaceship::AppVersion) Receive the version that is currently live on the
103
+ # App Store. You can't modify all values there, so be careful.
104
+ def live_version
105
+ v = Spaceship::AppVersion.find(self, self.apple_id, true)
106
+ end
107
+
108
+ # @return (Spaceship::AppVersion) Receive the version that can fully be edited
109
+ def edit_version
110
+ # Apple's server will respond with the same version if there is only one, for both v=live and v=
111
+ # That's why we have to check in the app_summary.json request if there are 2 versions or just one
112
+ # if there is only one version, we'll return nil
113
+ if raw_data['versions'].count == 1
114
+ return nil # only live version, user should create a new version
115
+ end
116
+
117
+ Spaceship::AppVersion.find(self, self.apple_id, false)
118
+ end
119
+
120
+ # @return (Spaceship::AppVersion) This will return the `edit_version` if available
121
+ # and fallback to the `edit_version`. Use this to just access the latest data
122
+ def latest_version
123
+ edit_version || live_version
124
+ end
125
+
126
+ # @return (String) An URL to this specific resource. You can enter this URL into your browser
127
+ def url
128
+ "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/ng/app/#{self.apple_id}"
129
+ end
130
+
131
+ # @return (Hash) Contains the reason for rejection.
132
+ # if everything is alright, the result will be
133
+ # `{"sectionErrorKeys"=>[], "sectionInfoKeys"=>[], "sectionWarningKeys"=>[], "replyConstraints"=>{"minLength"=>1, "maxLength"=>4000}, "appNotes"=>{"threads"=>[]}, "betaNotes"=>{"threads"=>[]}, "appMessages"=>{"threads"=>[]}}`
134
+ def resolution_center
135
+ client.get_resolution_center(apple_id)
136
+ end
137
+
138
+ #####################################################
139
+ # @!group Modifying
140
+ #####################################################
141
+
142
+ # Create a new version of your app
143
+ def create_version!(version_number)
144
+ if edit_version
145
+ raise "Cannot create a new version for this app as there already is an `edit_version` available"
146
+ end
147
+
148
+ client.create_version!(apple_id, version_number)
149
+
150
+ # Since we have stored the outdated raw_data, we need to refresh this object
151
+ # otherwise `edit_version` will return nil
152
+ # TODO: implemented -reload method
153
+ end
154
+
155
+ #####################################################
156
+ # @!group Builds
157
+ #####################################################
158
+
159
+ # A reference to all the build trains
160
+ # @return [Hash] a hash, the version number being the key
161
+ def build_trains
162
+ Tunes::BuildTrain.all(self, self.apple_id)
163
+ end
164
+
165
+ def pre_processing_builds
166
+ data = client.build_trains(apple_id) # we need to fetch all trains here to get the builds
167
+
168
+ data.fetch('processingBuilds', []).collect do |attrs|
169
+ attrs.merge!(build_train: self)
170
+ Tunes::ProcessingBuild.factory(attrs)
171
+ end
172
+ end
173
+
174
+ #####################################################
175
+ # @!group Submit for Review
176
+ #####################################################
177
+
178
+ def create_submission
179
+ version = self.latest_version
180
+ if version.nil?
181
+ raise "Could not find a valid version to submit for review"
182
+ end
183
+
184
+ Spaceship::AppSubmission.create(self, self.apple_id, version)
185
+ end
186
+
187
+ #####################################################
188
+ # @!group General
189
+ #####################################################
190
+ def setup
191
+
192
+ end
193
+
194
+ #####################################################
195
+ # @!group Testers
196
+ #####################################################
197
+
198
+ # Add all testers (internal and external) to the current app list
199
+ def add_all_testers!
200
+ Tunes::Tester.external.add_all_to_app!(self.apple_id)
201
+ Tunes::Tester.internal.add_all_to_app!(self.apple_id)
202
+ end
203
+
204
+ # @return (Array) Returns all external testers available for this app
205
+ def external_testers
206
+ Tunes::Tester.external.all_by_app(self.apple_id)
207
+ end
208
+
209
+ # @return (Array) Returns all internal testers available for this app
210
+ def internal_testers
211
+ Tunes::Tester.internal.all_by_app(self.apple_id)
212
+ end
213
+
214
+ # @return (Spaceship::Tunes::Tester.external) Returns the external tester matching the parameter
215
+ # as either the Tester id or email
216
+ # @param identifier (String) (required): Value used to filter the tester
217
+ def find_external_tester(identifier)
218
+ Tunes::Tester.external.find_by_app(self.apple_id, identifier)
219
+ end
220
+
221
+ # @return (Spaceship::Tunes::Tester.internal) Returns the internal tester matching the parameter
222
+ # as either the Tester id or email
223
+ # @param identifier (String) (required): Value used to filter the tester
224
+ def find_internal_tester(identifier)
225
+ Tunes::Tester.internal.find_by_app(self.apple_id, identifier)
226
+ end
227
+
228
+ # Add external tester to the current app list, if it doesn't exist will be created
229
+ # @param email (String) (required): The email of the tester
230
+ # @param first_name (String) (optional): The first name of the tester (Ignored if user already exist)
231
+ # @param last_name (String) (optional): The last name of the tester (Ignored if user already exist)
232
+ def add_external_tester!(email: nil, first_name: nil, last_name: nil)
233
+ raise "Tester is already on #{self.name} betatesters" if find_external_tester(email)
234
+
235
+ tester = Tunes::Tester.external.find(email) || Tunes::Tester.external.create!(email: email,
236
+ first_name: first_name,
237
+ last_name: last_name)
238
+ tester.add_to_app!(self.apple_id)
239
+ end
240
+
241
+ # Remove external tester from the current app list that matching the parameter
242
+ # as either the Tester id or email
243
+ # @param identifier (String) (required): Value used to filter the tester
244
+ def remove_external_tester!(identifier)
245
+ tester = find_external_tester(identifier)
246
+
247
+ raise "Tester is not on #{self.name} betatesters" unless tester
248
+
249
+ tester.remove_from_app!(self.apple_id)
250
+ end
251
+ end
252
+ end
253
+ end
@@ -0,0 +1,128 @@
1
+ module Spaceship
2
+ module Tunes
3
+ # Represents a build which is inside the build train
4
+ class Build < TunesBase
5
+
6
+ #####################################################
7
+ # @!group General metadata
8
+ #####################################################
9
+
10
+ # @return (Spaceship::Tunes::Application) A reference to the build train this build is contained in
11
+ attr_accessor :build_train
12
+
13
+ # @return (Integer) The ID generated by iTunes Connect
14
+ attr_accessor :id
15
+
16
+ # @return (Boolean)
17
+ attr_accessor :valid
18
+
19
+ # @return (String) The build version (not the version number)
20
+ attr_accessor :build_version
21
+
22
+ # @return (String) The version number (e.g. 1.3)
23
+ attr_accessor :train_version
24
+
25
+ # @return (Integer) The number of ticks since 1970 (e.g. 1413966436000)
26
+ attr_accessor :upload_date
27
+
28
+ # @return (String) URL to the app icon of this build (150x150px)
29
+ attr_accessor :icon_url
30
+
31
+ # @return (String)
32
+ attr_accessor :app_name
33
+
34
+ # @return (String) The platform of this build (e.g. 'ios')
35
+ attr_accessor :platform
36
+
37
+ # @return (Integer) When is this build going to be invalid
38
+ attr_accessor :internal_expiry_date
39
+
40
+ # @return (Bool) Does this build support WatchKit?
41
+ attr_accessor :watch_kit_enabled
42
+
43
+ # @return (Bool):
44
+ attr_accessor :ready_to_install
45
+
46
+ #####################################################
47
+ # @!group Analytics
48
+ #####################################################
49
+
50
+ # @return (Integer) Number of installs of this build
51
+ attr_accessor :install_count
52
+
53
+ # @return (Integer) Number of installs for this build that come from internal users
54
+ attr_accessor :internal_install_count
55
+
56
+ # @return (Integer) Number of installs for this build that come from external users
57
+ attr_accessor :external_install_count
58
+
59
+ # @return (Integer) Might be nil. The number of sessions for this build
60
+ attr_accessor :session_count
61
+
62
+ # @return (Integer) Might be nil. The number of crashes of this build
63
+ attr_accessor :crash_count
64
+
65
+ attr_mapping(
66
+ 'uploadDate' => :upload_date,
67
+ 'iconUrl' => :icon_url,
68
+ 'buildVersion' => :build_version,
69
+ 'trainVersion' => :train_version,
70
+ 'appName' => :app_name,
71
+ 'platform' => :platform,
72
+ 'id' => :id,
73
+ 'valid' => :valid,
74
+
75
+ 'installCount' => :install_count,
76
+ 'internalInstallCount' => :internal_install_count,
77
+ 'externalInstallCount' => :external_install_count,
78
+ 'sessionCount' => :session_count,
79
+ 'crashCount' => :crash_count,
80
+ 'internalExpiry' => :internal_expiry_date,
81
+ 'watchKitEnabled' => :watch_kit_enabled,
82
+ 'readyToInstall' => :ready_to_install,
83
+ )
84
+
85
+ class << self
86
+ # Create a new object based on a hash.
87
+ # This is used to create a new object based on the server response.
88
+ def factory(attrs)
89
+ self.new(attrs)
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ # Example response
97
+ # "buildVersion": "0.9.10",
98
+ # "trainVersion": "0.9.10",
99
+ # "uploadDate": 1413966436000,
100
+ # "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",
101
+ # "appName": "Yeahaa",
102
+ # "platform": "ios",
103
+ # "betaEntitled": false,
104
+ # "id": 523299,
105
+ # "valid": true,
106
+ # "missingExportCompliance": false,
107
+ # "waitingForExportComplianceApproval": false,
108
+ # "addedInternalUsersCount": 0,
109
+ # "addedExternalUsersCount": 0,
110
+ # "invitedExternalUsersCount": 0,
111
+ # "invitedInternalUsersCount": 0,
112
+ # "acceptedInternalUsersCount": 0,
113
+ # "acceptedExternalUsersCount": 0,
114
+ # "installCount": 0,
115
+ # "internalInstallCount": 0,
116
+ # "externalInstallCount": 0,
117
+ # "sessionCount": null,
118
+ # "crashCount": null,
119
+ # "promotedVersion": null,
120
+ # "internalState": "noBetaEntitlement",
121
+ # "betaState": "noBetaEntitlement",
122
+ # "internalExpiry": 1416562036000,
123
+ # "externalExpiry": 0,
124
+ # "watchKitEnabled": false,
125
+ # "readyToInstall": false,
126
+ # "sdkBuildWhitelisted": true,
127
+ # "internalTesting": null,
128
+ # "externalTesting": null
@@ -0,0 +1,79 @@
1
+ module Spaceship
2
+ module Tunes
3
+ # Represents a build train of builds from iTunes Connect
4
+ # A build train is all builds for a given version number with different build numbers
5
+ class BuildTrain < TunesBase
6
+
7
+ # @return (Spaceship::Tunes::Application) A reference to the application
8
+ # this train is for
9
+ attr_accessor :application
10
+
11
+ # @return (Array) An array of all builds that are inside this train (Spaceship::Tunes::Build)
12
+ attr_reader :builds
13
+
14
+ # @return (String) The version number of this train
15
+ attr_reader :version_string
16
+
17
+ # @return (String) Platform (e.g. "ios")
18
+ attr_reader :platform
19
+
20
+ # @return (Bool) Is beta testing enabled for this train? Only one train can have enabled testing.
21
+ attr_reader :testing_enabled
22
+
23
+ # @return (Array) An array of all builds that are inside this train (Spaceship::Tunes::Build)
24
+ # I never got this to work to properly try and debug this
25
+ attr_reader :processing_builds
26
+
27
+ attr_mapping(
28
+ 'versionString' => :version_string,
29
+ 'platform' => :platform,
30
+ 'testing.value' => :testing_enabled
31
+ )
32
+
33
+ class << self
34
+ # Create a new object based on a hash.
35
+ # This is used to create a new object based on the server response.
36
+ def factory(attrs)
37
+ self.new(attrs)
38
+ end
39
+
40
+ # @param application (Spaceship::Tunes::Application) The app this train is for
41
+ # @param app_id (String) The unique Apple ID of this app
42
+ def all(application, app_id)
43
+ data = client.build_trains(app_id)
44
+ result = {}
45
+ data['trains'].each do |attrs|
46
+ attrs.merge!(application: application)
47
+ current = self.factory(attrs)
48
+ result[current.version_string] = current
49
+ end
50
+ result
51
+ end
52
+ end
53
+
54
+ # Setup all the builds and processing builds
55
+ def setup
56
+ @builds = self.raw_data['builds'].collect do |attrs|
57
+ attrs.merge!(build_train: self)
58
+ Tunes::Build.factory(attrs)
59
+ end
60
+
61
+ @processing_builds = self.raw_data['buildsInProcessing'].collect do |attrs|
62
+ attrs.merge!(build_train: self)
63
+ Tunes::Build.factory(attrs)
64
+ end
65
+ end
66
+
67
+ def update_testing_status!(new_value)
68
+ data = client.build_trains(self.application.apple_id)
69
+ data['trains'].each do |train|
70
+ train['testing']['value'] = false
71
+ train['testing']['value'] = new_value if train['versionString'] == version_string
72
+ end
73
+ result = client.update_build_trains!(application.apple_id, data)
74
+ self.testing_enabled = new_value
75
+ result
76
+ end
77
+ end
78
+ end
79
+ end