fastlane 2.28.9 → 2.29.0.beta.20170421010107

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/deliver/lib/assets/summary.html.erb +0 -3
  4. data/deliver/lib/deliver/options.rb +2 -2
  5. data/deliver/lib/deliver/upload_metadata.rb +1 -2
  6. data/fastlane/README.md +2 -6
  7. data/fastlane/lib/fastlane/actions/artifactory.rb +1 -17
  8. data/fastlane/lib/fastlane/actions/crashlytics.rb +1 -1
  9. data/fastlane/lib/fastlane/actions/download_dsyms.rb +1 -1
  10. data/fastlane/lib/fastlane/actions/ensure_git_status_clean.rb +3 -17
  11. data/fastlane/lib/fastlane/actions/hockey.rb +1 -1
  12. data/fastlane/lib/fastlane/actions/upload_symbols_to_crashlytics.rb +3 -3
  13. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +10 -16
  14. data/fastlane/lib/fastlane/version.rb +1 -1
  15. data/fastlane_core/lib/fastlane_core/build_watcher.rb +21 -39
  16. data/fastlane_core/lib/fastlane_core/helper.rb +5 -7
  17. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +1 -4
  18. data/fastlane_core/lib/fastlane_core/print_table.rb +9 -4
  19. data/fastlane_core/lib/fastlane_core/project.rb +4 -16
  20. data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +7 -11
  21. data/fastlane_core/lib/fastlane_core/ui/github_issue_inspector_reporter.rb +2 -2
  22. data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +0 -2
  23. data/fastlane_core/lib/fastlane_core/ui/ui.rb +2 -0
  24. data/gym/lib/gym/generators/build_command_generator.rb +0 -2
  25. data/gym/lib/gym/options.rb +0 -10
  26. data/gym/lib/gym/runner.rb +0 -2
  27. data/gym/lib/gym/xcode.rb +3 -1
  28. data/pilot/lib/pilot/build_manager.rb +17 -44
  29. data/pilot/lib/pilot/commands_generator.rb +1 -2
  30. data/pilot/lib/pilot/options.rb +2 -3
  31. data/pilot/lib/pilot/tester_manager.rb +44 -58
  32. data/snapshot/lib/assets/SnapshotHelper.swift +1 -1
  33. data/spaceship/lib/spaceship/spaceauth_runner.rb +1 -1
  34. data/spaceship/lib/spaceship/test_flight.rb +0 -2
  35. data/spaceship/lib/spaceship/test_flight/base.rb +0 -12
  36. data/spaceship/lib/spaceship/test_flight/build.rb +8 -22
  37. data/spaceship/lib/spaceship/test_flight/client.rb +40 -121
  38. data/spaceship/lib/spaceship/test_flight/group.rb +7 -49
  39. data/spaceship/lib/spaceship/test_flight/test_info.rb +0 -4
  40. data/spaceship/lib/spaceship/tunes/app_ratings.rb +2 -74
  41. data/spaceship/lib/spaceship/tunes/app_status.rb +2 -4
  42. data/spaceship/lib/spaceship/tunes/application.rb +1 -1
  43. data/spaceship/lib/spaceship/tunes/iap_detail.rb +11 -48
  44. data/spaceship/lib/spaceship/tunes/iap_family_details.rb +5 -24
  45. data/spaceship/lib/spaceship/tunes/tunes_client.rb +3 -14
  46. data/supply/lib/supply/setup.rb +2 -2
  47. metadata +16 -33
  48. data/spaceship/lib/spaceship/test_flight/app_test_info.rb +0 -27
  49. data/spaceship/lib/spaceship/test_flight/tester.rb +0 -34
@@ -1,126 +1,34 @@
1
1
  module Spaceship::TestFlight
2
2
  class Client < Spaceship::Client
3
- ##
4
- # Spaceship HTTP client for the testflight API.
5
- #
6
- # This client is solely responsible for the making HTTP requests and
7
- # parsing their responses. Parameters should be either named parameters, or
8
- # for large request data bodies, pass in anything that can resond to
9
- # `to_json`.
10
- #
11
- # Each request method should validate the required parameters. A required parameter is one that would result in 400-range response if it is not supplied.
12
- # Each request method should make only one request. For more high-level logic, put code in the data models.
13
-
14
3
  def self.hostname
15
4
  'https://itunesconnect.apple.com/testflight/v2/'
16
5
  end
17
6
 
18
- ##
19
- # @!group Build trains API
20
- ##
21
-
22
7
  # Returns an array of all available build trains (not the builds they include)
23
- def get_build_trains(app_id: nil, platform: "ios")
8
+ def get_build_trains(app_id: nil, platform: nil)
24
9
  assert_required_params(__method__, binding)
25
-
10
+ platform ||= "ios"
26
11
  response = request(:get, "providers/#{team_id}/apps/#{app_id}/platforms/#{platform}/trains")
27
12
  handle_response(response)
28
13
  end
29
14
 
30
- def get_builds_for_train(app_id: nil, platform: "ios", train_version: nil)
15
+ def get_builds_for_train(app_id: nil, platform: nil, train_version: nil)
31
16
  assert_required_params(__method__, binding)
17
+ platform ||= "ios"
32
18
 
33
19
  response = request(:get, "providers/#{team_id}/apps/#{app_id}/platforms/#{platform}/trains/#{train_version}/builds")
34
20
  handle_response(response)
35
21
  end
36
22
 
37
- ##
38
- # @!group Builds API
39
- ##
40
-
41
- def get_build(app_id: nil, build_id: nil)
42
- assert_required_params(__method__, binding)
43
-
44
- response = request(:get, "providers/#{team_id}/apps/#{app_id}/builds/#{build_id}")
45
- handle_response(response)
46
- end
47
-
48
- def put_build(app_id: nil, build_id: nil, build: nil)
49
- assert_required_params(__method__, binding)
50
-
51
- response = request(:put) do |req|
52
- req.url "providers/#{team_id}/apps/#{app_id}/builds/#{build_id}"
53
- req.body = build.to_json
54
- req.headers['Content-Type'] = 'application/json'
55
- end
56
- handle_response(response)
57
- end
58
-
59
- def post_for_testflight_review(app_id: nil, build_id: nil, build: nil)
60
- assert_required_params(__method__, binding)
61
-
62
- response = request(:post) do |req|
63
- req.url "providers/#{team_id}/apps/#{app_id}/builds/#{build_id}/review"
64
- req.body = build.to_json
65
- req.headers['Content-Type'] = 'application/json'
66
- end
67
- handle_response(response)
68
- end
69
-
70
- ##
71
- # @!group Groups API
72
- ##
73
-
74
- def get_groups(app_id: nil)
75
- assert_required_params(__method__, binding)
76
-
77
- response = request(:get, "/testflight/v2/providers/#{team_id}/apps/#{app_id}/groups")
78
- handle_response(response)
79
- end
80
-
81
- def add_group_to_build(app_id: nil, group_id: nil, build_id: nil)
82
- assert_required_params(__method__, binding)
83
-
84
- body = {
85
- 'groupId' => group_id,
86
- 'buildId' => build_id
87
- }
88
- response = request(:put) do |req|
89
- req.url "providers/#{team_id}/apps/#{app_id}/groups/#{group_id}/builds/#{build_id}"
90
- req.body = body.to_json
91
- req.headers['Content-Type'] = 'application/json'
92
- end
93
- handle_response(response)
94
- end
95
-
96
- ##
97
- # @!group Testers API
98
- ##
99
-
100
- def testers_for_app(app_id: nil)
101
- assert_required_params(__method__, binding)
102
- url = "providers/#{team_id}/apps/#{app_id}/testers?limit=10000"
103
- response = request(:get, url)
104
- handle_response(response)
105
- end
106
-
107
- def delete_tester_from_app(app_id: nil, tester_id: nil)
108
- assert_required_params(__method__, binding)
109
- url = "providers/#{team_id}/apps/#{app_id}/testers/#{tester_id}"
110
- response = request(:delete, url)
111
- handle_response(response)
112
- end
113
-
114
23
  def post_tester(app_id: nil, tester: nil)
115
24
  assert_required_params(__method__, binding)
116
-
117
25
  url = "providers/#{team_id}/apps/#{app_id}/testers"
118
26
  response = request(:post) do |req|
119
27
  req.url url
120
28
  req.body = {
121
29
  "email" => tester.email,
122
- "firstName" => tester.first_name,
123
- "lastName" => tester.last_name
30
+ "firstName" => tester.last_name,
31
+ "lastName" => tester.first_name
124
32
  }.to_json
125
33
  req.headers['Content-Type'] = 'application/json'
126
34
  end
@@ -129,7 +37,6 @@ module Spaceship::TestFlight
129
37
 
130
38
  def put_tester_to_group(app_id: nil, tester_id: nil, group_id: nil)
131
39
  assert_required_params(__method__, binding)
132
-
133
40
  # Then we can add the tester to the group that allows the app to test
134
41
  # This is easy enough, we already have all this data. We don't need any response from the previous request
135
42
  url = "providers/#{team_id}/apps/#{app_id}/groups/#{group_id}/testers/#{tester_id}"
@@ -146,7 +53,6 @@ module Spaceship::TestFlight
146
53
 
147
54
  def delete_tester_from_group(group_id: nil, tester_id: nil, app_id: nil)
148
55
  assert_required_params(__method__, binding)
149
-
150
56
  url = "providers/#{team_id}/apps/#{app_id}/groups/#{group_id}/testers/#{tester_id}"
151
57
  response = request(:delete) do |req|
152
58
  req.url url
@@ -155,32 +61,53 @@ module Spaceship::TestFlight
155
61
  handle_response(response)
156
62
  end
157
63
 
158
- ##
159
- # @!group AppTestInfo
160
- ##
64
+ def get_build(app_id: nil, build_id: nil)
65
+ assert_required_params(__method__, binding)
66
+ response = request(:get, "providers/#{team_id}/apps/#{app_id}/builds/#{build_id}")
67
+ handle_response(response)
68
+ end
161
69
 
162
- def get_app_test_info(app_id: nil)
70
+ def put_build(app_id: nil, build_id: nil, build: nil)
163
71
  assert_required_params(__method__, binding)
72
+ response = request(:put) do |req|
73
+ req.url "providers/#{team_id}/apps/#{app_id}/builds/#{build_id}"
74
+ req.body = build.to_json
75
+ req.headers['Content-Type'] = 'application/json'
76
+ end
77
+ handle_response(response)
78
+ end
164
79
 
165
- response = request(:get, "providers/#{team_id}/apps/#{app_id}/testInfo")
80
+ def post_for_testflight_review(app_id: nil, build_id: nil, build: nil)
81
+ assert_required_params(__method__, binding)
82
+ response = request(:post) do |req|
83
+ req.url "providers/#{team_id}/apps/#{app_id}/builds/#{build_id}/review"
84
+ req.body = build.to_json
85
+ req.headers['Content-Type'] = 'application/json'
86
+ end
166
87
  handle_response(response)
167
88
  end
168
89
 
169
- def put_app_test_info(app_id: nil, app_test_info: nil)
90
+ def get_groups(app_id: nil)
170
91
  assert_required_params(__method__, binding)
92
+ response = request(:get, "/testflight/v2/providers/#{team_id}/apps/#{app_id}/groups")
93
+ handle_response(response)
94
+ end
171
95
 
96
+ def add_group_to_build(app_id: nil, group_id: nil, build_id: nil)
97
+ body = {
98
+ 'groupId' => group_id,
99
+ 'buildId' => build_id
100
+ }
172
101
  response = request(:put) do |req|
173
- req.url "providers/#{team_id}/apps/#{app_id}/testInfo"
174
- req.body = app_test_info.to_json
102
+ req.url "providers/#{team_id}/apps/#{app_id}/groups/#{group_id}/builds/#{build_id}"
103
+ req.body = body.to_json
175
104
  req.headers['Content-Type'] = 'application/json'
176
105
  end
177
106
  handle_response(response)
178
107
  end
179
108
 
180
- protected
181
-
182
109
  def handle_response(response)
183
- if (200...300).cover?(response.status) && (response.body.nil? || response.body.empty?)
110
+ if (200..300).cover?(response.status) && response.body.empty?
184
111
  return
185
112
  end
186
113
 
@@ -201,20 +128,12 @@ module Spaceship::TestFlight
201
128
  #
202
129
  # @raises NameError if the values are nil
203
130
  def assert_required_params(method_name, binding)
204
- parameter_names = method(method_name).parameters.map { |k, v| v }
131
+ parameter_names = Hash[method(method_name).parameters].values
205
132
  parameter_names.each do |name|
206
- if local_variable_get(binding, name).nil?
133
+ if binding.local_variable_get(name).nil?
207
134
  raise NameError, "`#{name}' is a required parameter"
208
135
  end
209
136
  end
210
137
  end
211
-
212
- def local_variable_get(binding, name)
213
- if binding.respond_to?(:local_variable_get)
214
- binding.local_variable_get(name)
215
- else
216
- binding.eval(name.to_s)
217
- end
218
- end
219
138
  end
220
139
  end
@@ -3,21 +3,22 @@ module Spaceship::TestFlight
3
3
  attr_accessor :id
4
4
  attr_accessor :name
5
5
  attr_accessor :is_default_external_group
6
- attr_accessor :is_internal_group
7
6
 
8
7
  attr_accessor :app_id
9
8
 
10
9
  attr_mapping({
11
10
  'id' => :id,
12
11
  'name' => :name,
13
- 'isInternalGroup' => :is_internal_group,
14
- 'appAdamId' => :app_id,
15
12
  'isDefaultExternalGroup' => :is_default_external_group
16
13
  })
17
14
 
18
15
  def self.all(app_id: nil)
19
16
  groups = client.get_groups(app_id: app_id)
20
- groups.map { |g| self.new(g) }
17
+ groups.map do |g|
18
+ current_element = self.new(g)
19
+ current_element.app_id = app_id
20
+ current_element
21
+ end
21
22
  end
22
23
 
23
24
  def self.find(app_id: nil, group_name: nil)
@@ -35,11 +36,6 @@ module Spaceship::TestFlight
35
36
  groups.select(&block)
36
37
  end
37
38
 
38
- def self.internal_group(app_id: nil)
39
- groups = self.all(app_id: app_id)
40
- groups.find(&:internal_group?)
41
- end
42
-
43
39
  # First we need to add the tester to the app
44
40
  # It's ok if the tester already exists, we just have to do this... don't ask
45
41
  # This will enable testing for the tester for a given app, as just creating the tester on an account-level
@@ -47,55 +43,17 @@ module Spaceship::TestFlight
47
43
  # This is a bug we reported to the iTunes Connect team, as it also happens on the iTunes Connect UI on 18. April 2017
48
44
  def add_tester!(tester)
49
45
  # This post request makes the account-level tester available to the app
50
- tester_data = client.post_tester(app_id: self.app_id, tester: tester)
46
+ client.post_tester(app_id: self.app_id, tester: tester)
51
47
  # This put request adds the tester to the group
52
- client.put_tester_to_group(group_id: self.id, tester_id: tester_data['id'], app_id: self.app_id)
48
+ client.put_tester_to_group(group_id: self.id, tester_id: tester.tester_id, app_id: self.app_id)
53
49
  end
54
50
 
55
51
  def remove_tester!(tester)
56
52
  client.delete_tester_from_group(group_id: self.id, tester_id: tester.tester_id, app_id: self.app_id)
57
53
  end
58
54
 
59
- def self.add_tester_to_groups!(tester: nil, app: nil, groups: nil)
60
- if tester.kind_of?(Spaceship::Tunes::Tester::Internal)
61
- self.internal_group(app_id: app.apple_id).add_tester!(tester)
62
- else
63
- self.perform_for_groups_in_app(app: app, groups: groups) { |group| group.add_tester!(tester) }
64
- end
65
- end
66
-
67
- def self.remove_tester_from_groups!(tester: nil, app: nil, groups: nil)
68
- if tester.kind_of?(Spaceship::Tunes::Tester::Internal)
69
- self.internal_group(app_id: app.apple_id).remove_tester!(tester)
70
- else
71
- self.perform_for_groups_in_app(app: app, groups: groups) { |group| group.remove_tester!(tester) }
72
- end
73
- end
74
-
75
55
  def default_external_group?
76
56
  is_default_external_group
77
57
  end
78
-
79
- def internal_group?
80
- is_internal_group
81
- end
82
-
83
- def self.perform_for_groups_in_app(app: nil, groups: nil, &block)
84
- if groups.nil?
85
- default_external_group = app.default_external_group
86
- if default_external_group.nil?
87
- raise "The app #{app.name} does not have a default external group. Please make sure to pass group names to the `:groups` option."
88
- end
89
- test_flight_groups = [default_external_group]
90
- else
91
- test_flight_groups = self.filter_groups(app_id: app.apple_id) do |group|
92
- groups.include?(group.name)
93
- end
94
-
95
- raise "There are no groups available matching the names passed to the `:groups` option." if test_flight_groups.empty?
96
- end
97
-
98
- test_flight_groups.each(&block)
99
- end
100
58
  end
101
59
  end
@@ -30,9 +30,5 @@ module Spaceship::TestFlight
30
30
  def whats_new=(value)
31
31
  raw_data.each { |locale| locale['whatsNew'] = value }
32
32
  end
33
-
34
- def deep_copy
35
- TestInfo.new(raw_data.map(&:dup))
36
- end
37
33
  end
38
34
  end
@@ -47,81 +47,9 @@ module Spaceship
47
47
  instance_variable_set(:@store_fronts, unfolded_store_fronts)
48
48
  end
49
49
 
50
- # @return (Array) of Review Objects
50
+ # @return (Array) of raw hashes representing user reviews for the given store front (and optional versionId)
51
51
  def reviews(store_front, versionId = '')
52
- raw_reviews = client.get_reviews(application.apple_id, application.platform, store_front, versionId)
53
- raw_reviews.map do |review|
54
- review["value"]["application"] = self.application
55
- AppReview.factory(review["value"])
56
- end
57
- end
58
- end
59
-
60
- class DeveloperResponse < TunesBase
61
- attr_reader :id
62
- attr_reader :response
63
- attr_reader :last_modified
64
- attr_reader :hidden
65
- attr_reader :state
66
- attr_accessor :application
67
- attr_accessor :review_id
68
-
69
- attr_mapping({
70
- 'responseId' => :id,
71
- 'response' => :response,
72
- 'lastModified' => :last_modified,
73
- 'isHidden' => :hidden,
74
- 'pendingState' => :state
75
- })
76
- end
77
-
78
- class AppReview < TunesBase
79
- attr_accessor :application
80
- attr_reader :rating
81
- attr_reader :id
82
- attr_reader :title
83
- attr_reader :review
84
- attr_reader :nickname
85
- attr_reader :store_front
86
- attr_reader :app_version
87
- attr_reader :last_modified
88
- attr_reader :helpful_views
89
- attr_reader :total_views
90
- attr_reader :edited
91
- attr_reader :raw_developer_response
92
- attr_accessor :developer_response
93
-
94
- attr_mapping({
95
- 'id' => :id,
96
- 'rating' => :rating,
97
- 'title' => :title,
98
- 'review' => :review,
99
- 'nickname' => :nickname,
100
- 'storeFront' => :store_front,
101
- 'appVersionString' => :app_version,
102
- 'lastModified' => :last_modified,
103
- 'helpfulViews' => :helpful_views,
104
- 'totalViews' => :total_views,
105
- 'developerResponse' => :raw_developer_response,
106
- 'edited' => :edited
107
- })
108
- class << self
109
- # Create a new object based on a hash.
110
- # This is used to create a new object based on the server response.
111
- def factory(attrs)
112
- obj = self.new(attrs)
113
- response_attrs = {}
114
- response_attrs = obj.raw_developer_response if obj.raw_developer_response
115
- response_attrs[:application] = obj.application
116
- response_attrs[:review_id] = obj.id
117
- obj.developer_response = DeveloperResponse.factory(response_attrs)
118
- return obj
119
- end
120
- end
121
-
122
- def responded?
123
- return true if raw_developer_response
124
- false
52
+ client.get_reviews(application.apple_id, application.platform, store_front, versionId)
125
53
  end
126
54
  end
127
55
 
@@ -33,7 +33,7 @@ module Spaceship
33
33
  PROCESSING_FOR_APP_STORE = "Processing for App Store"
34
34
  # WAITING_FOR_EXPORT_COMPLIANCE = "Waiting For Export Compliance"
35
35
  METADATA_REJECTED = "Metadata Rejected"
36
- REMOVED_FROM_SALE = "Removed From Sale"
36
+ # REMOVED_FROM_SALE = "Removed From Sale"
37
37
  # INVALID_BINARY = "Invalid Binary"
38
38
 
39
39
  # Get the app status matching based on a string (given by iTunes Connect)
@@ -46,10 +46,8 @@ module Spaceship
46
46
  'developerRemovedFromSale' => DEVELOPER_REMOVED_FROM_SALE,
47
47
  'waitingForReview' => WAITING_FOR_REVIEW,
48
48
  'inReview' => IN_REVIEW,
49
- 'rejected' => REJECTED,
50
49
  'pendingDeveloperRelease' => PENDING_DEVELOPER_RELEASE,
51
- 'metadataRejected' => METADATA_REJECTED,
52
- 'removedFromSale' => REMOVED_FROM_SALE
50
+ 'metadataRejected' => METADATA_REJECTED
53
51
  }
54
52
 
55
53
  mapping.each do |k, v|
@@ -78,7 +78,7 @@ module Spaceship
78
78
  # should it be an ios or an osx app
79
79
 
80
80
  def create!(name: nil, primary_language: nil, version: nil, sku: nil, bundle_id: nil, bundle_id_suffix: nil, company_name: nil, platform: nil)
81
- puts "The `version` parameter is deprecated. Use `ensure_version!` method instead" if version
81
+ UI.deprecated("The `version` parameter is deprecated. Use `ensure_version!` method instead") if version
82
82
  client.create_application!(name: name,
83
83
  primary_language: primary_language,
84
84
  sku: sku,