spaceship 0.36.2 → 0.37.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a51a5af0da545a0926ac2b3f43e3fd9579038e8a
4
- data.tar.gz: 52015e9dbc1bdbf7cf4f31e33ccbc2283d83b703
3
+ metadata.gz: 5876ed2b557a73506b42f22b1845d8e532574b96
4
+ data.tar.gz: 8b70dd155a884a368c2b55ea67b320674581928a
5
5
  SHA512:
6
- metadata.gz: 095f8d076be50fa867bb4f28c81d4fc0377390487278b4f3003c558fa59e2bea9d27168d19a25db67bc138ba77c5daa143537c152ef27e3afb2a6d8f95250053
7
- data.tar.gz: 135ee2ce6245dc4e7a1b21b7124687e496eaf20172a365619d5d37aaeac8130791a73cbf4b74347ddf8a1d3ed2012fadbab4649b6e4664f83386f835f404d9fe
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 step 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.
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
- ### Spaceship in use
130
+ ### _spaceship_ in use
131
131
 
132
- Most [fastlane tools](https://fastlane.tools) already use `spaceship`, like `sigh`, `cert`, `produce`, `pilot` and `boarding`.
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
@@ -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
- `sips -s format bmp '#{path}' &> /dev/null` # &> /dev/null since there is warning because of the extension
37
- `sips -s format png '#{path}'`
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
- result = client.update_build_trains!(application.apple_id, testing_type, data)
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 = { contentProviderId: team_id, dsId: user_detail_data.ds_id }.to_json
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 ||= Spaceship::Tunes::UserDetail.factory(data)
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 create_tester!(tester: nil, email: nil, first_name: nil, last_name: nil)
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, :ds_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
@@ -1,4 +1,4 @@
1
1
  module Spaceship
2
- VERSION = "0.36.2".freeze
2
+ VERSION = "0.37.0".freeze
3
3
  DESCRIPTION = "Ruby library to access the Apple Dev Center and iTunes Connect".freeze
4
4
  end
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.36.2
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-10-25 00:00:00.000000000 Z
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.6.7
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