fastlane 2.28.9 → 2.29.0.beta.20170421010107

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.
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,