fastlane 2.56.0.beta.20170907010003 → 2.56.0.beta.20170908010003

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2839e587204146a6814c5a55b3e178da5aedf736
4
- data.tar.gz: d0ec06f58ae3104b329b1e990858b4645cfa67da
3
+ metadata.gz: 72272fe0f501813a435dd4c3070400647818d4d4
4
+ data.tar.gz: 10e25aa18e05dc977efcc70e0424a377985dd0fd
5
5
  SHA512:
6
- metadata.gz: ebc67ba6999698a3f4d79bb5b4cf3c952999695d8293099db5274668dd141dff6d75f9f4de6be447d312f81754f4665f580d696c475abc0d152264b7ff0002cf
7
- data.tar.gz: b1c03e9c386a9531a640cb0eba3b22178558f73df04fb3f29745914aa2467042d5583e516be21470086d5d29dc9e4aeb4f7e4d50df36a355e650eecc8f512ce6
6
+ metadata.gz: 25b341e98475a2c8588b94b77f97a96d61a1c8d0e076935cb952c0543391b98d89cec0a444e025854884d57b0f8b72f5d4a08e769e67826f27f82c3eb1132af6
7
+ data.tar.gz: f41ecd0b5405ac0481b9db7e4ced3b135cb1531e1c55df1a08db51237cc373474098adaab5e6f712bffeefddad0de99b2c956f5da0daf517c96e903c702d7615
@@ -33,7 +33,9 @@ module CredentialsManager
33
33
  end
34
34
 
35
35
  def fetch_password_from_env
36
- ENV["FASTLANE_PASSWORD"] || ENV["DELIVER_PASSWORD"]
36
+ password = ENV["FASTLANE_PASSWORD"] || ENV["DELIVER_PASSWORD"]
37
+ return password if password.to_s.length > 0
38
+ return nil
37
39
  end
38
40
 
39
41
  def password(ask_if_missing: true)
@@ -102,7 +102,10 @@ module Deliver
102
102
  end
103
103
 
104
104
  require 'deliver/setup'
105
+
105
106
  options = FastlaneCore::Configuration.create(deliverfile_options, options.__hash__)
107
+ options[:run_precheck_before_submit] = false # precheck doesn't need to run during init
108
+
106
109
  Deliver::Runner.new(options) # to login...
107
110
  Deliver::Setup.new.run(options)
108
111
  end
@@ -1,3 +1,5 @@
1
+ require 'thread'
2
+
1
3
  module Fastlane
2
4
  module Actions
3
5
  class UploadSymbolsToCrashlyticsAction < Action
@@ -20,8 +22,13 @@ module Fastlane
20
22
  dsym_paths = dsym_paths.collect { |a| File.expand_path(a) }
21
23
  dsym_paths.uniq!
22
24
 
25
+ max_worker_threads = params[:dsym_worker_threads]
26
+ if max_worker_threads > 1
27
+ UI.message("Using #{max_worker_threads} threads for Crashlytics dSYM upload 🏎")
28
+ end
29
+
23
30
  dsym_paths.each do |current_path|
24
- handle_dsym(params, current_path)
31
+ handle_dsym(params, current_path, max_worker_threads)
25
32
  end
26
33
 
27
34
  UI.success("Successfully uploaded dSYM files to Crashlytics 💯")
@@ -29,7 +36,7 @@ module Fastlane
29
36
 
30
37
  # @param current_path this is a path to either a dSYM or a zipped dSYM
31
38
  # this might also be either nested or not, we're flexible
32
- def self.handle_dsym(params, current_path)
39
+ def self.handle_dsym(params, current_path, max_worker_threads)
33
40
  if current_path.end_with?(".dSYM")
34
41
  upload_dsym(params, current_path)
35
42
  elsif current_path.end_with?(".zip")
@@ -39,9 +46,11 @@ module Fastlane
39
46
  Dir.mktmpdir do |dir|
40
47
  Dir.chdir(dir) do
41
48
  Actions.sh("unzip -qo #{current_path.shellescape}")
49
+ work_q = Queue.new
42
50
  Dir["*.dSYM"].each do |sub|
43
- handle_dsym(params, sub)
51
+ work_q.push sub
44
52
  end
53
+ execute_uploads(params, max_worker_threads, work_q)
45
54
  end
46
55
  end
47
56
  else
@@ -49,6 +58,23 @@ module Fastlane
49
58
  end
50
59
  end
51
60
 
61
+ def self.execute_uploads(params, max_worker_threads, work_q)
62
+ number_of_threads = [max_worker_threads, work_q.size].min
63
+ workers = (0...number_of_threads).map do
64
+ Thread.new do
65
+ begin
66
+ while work_q.size > 0
67
+ current_path = work_q.pop(true)
68
+ upload_dsym(params, current_path)
69
+ end
70
+ rescue => ex
71
+ UI.error ex.to_s
72
+ end
73
+ end
74
+ end
75
+ workers.map(&:join)
76
+ end
77
+
52
78
  def self.upload_dsym(params, path)
53
79
  UI.message("Uploading '#{path}'...")
54
80
  command = []
@@ -133,6 +159,18 @@ module Fastlane
133
159
  verify_block: proc do |value|
134
160
  available = ['ios', 'appletvos', 'mac']
135
161
  UI.user_error!("Invalid platform '#{value}', must be #{available.join(', ')}") unless available.include?(value)
162
+ end),
163
+ FastlaneCore::ConfigItem.new(key: :dsym_worker_threads,
164
+ env_name: "FL_UPLOAD_SYMBOLS_TO_CRASHLYTICS_DSYM_WORKER_THREADS",
165
+ type: Integer,
166
+ default_value: 1,
167
+ optional: true,
168
+ description: "The number of threads to use for simultaneous dSYM upload",
169
+ verify_block: proc do |value|
170
+ min_threads = 1
171
+ max_threads = 15
172
+ UI.user_error!("Too few threads (#{value}) minimum number of threads: #{min_threads}") unless value >= min_threads
173
+ UI.user_error!("Too many threads (#{value}) maximum number of threads: #{max_threads}") unless value <= max_threads
136
174
  end)
137
175
  ]
138
176
  end
@@ -258,7 +258,7 @@ module Fastlane
258
258
  env_output << "\n"
259
259
  env_output << "```ruby\n"
260
260
  env_output << File.read(fastlane_path)
261
- env_output << "```\n"
261
+ env_output << "\n```\n"
262
262
  env_output << "</details>"
263
263
  else
264
264
  env_output << "**No Fastfile found**\n"
@@ -272,7 +272,7 @@ module Fastlane
272
272
  env_output << "\n"
273
273
  env_output << "```ruby\n"
274
274
  env_output << File.read(appfile_path)
275
- env_output << "```\n"
275
+ env_output << "\n```\n"
276
276
  env_output << "</details>"
277
277
  else
278
278
  env_output << "**No Appfile found**\n"
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
- VERSION = '2.56.0.beta.20170907010003'.freeze
2
+ VERSION = '2.56.0.beta.20170908010003'.freeze
3
3
  DESCRIPTION = "The easiest way to automate beta deployments and releases for your iOS and Android apps".freeze
4
4
  MINIMUM_XCODE_RELEASE = "7.0".freeze
5
5
  end
@@ -61,7 +61,7 @@ module FastlaneCore
61
61
  filename = file.path
62
62
  keychain = wwdr_keychain
63
63
  keychain = "-k #{keychain.shellescape}" unless keychain.empty?
64
- Helper.backticks("curl -o #{filename} #{url} && security import #{filename} #{keychain}", print: FastlaneCore::Globals.verbose?)
64
+ Helper.backticks("curl -f -o #{filename} #{url} && security import #{filename} #{keychain}", print: FastlaneCore::Globals.verbose?)
65
65
  UI.user_error!("Could not install WWDR certificate") unless $?.success?
66
66
  end
67
67
 
@@ -214,8 +214,9 @@ module Gym
214
214
  def print_environment_information
215
215
  if Gym.config[:export_method].to_s == "development"
216
216
  UI.message("")
217
- UI.error("Your `export_method` in gym is defined as `:development`")
218
- UI.error("which can't be used for `ipa` files for beta or App Store distribution")
217
+ UI.error("Your `export_method` in gym is defined as `development`")
218
+ UI.error("which might cause problems when signing your application")
219
+ UI.error("Are you sure want to build and export for development?")
219
220
  UI.error("Please make sure to define the correct export methods when calling")
220
221
  UI.error("gym in your Fastfile or from the command line")
221
222
  UI.message("")
data/match/README.md CHANGED
@@ -274,6 +274,8 @@ end
274
274
 
275
275
  By using the `force_for_new_devices` parameter, `match` will check if the device count has changed since the last time you ran `match`, and automatically re-generate the provisioning profile if necessary. You can also use `force: true` to re-generate the provisioning profile on each run.
276
276
 
277
+ _**Important:** The `force_for_new_devices` parameter is ignored for App Store provisioning profiles since they don't contain any device information._
278
+
277
279
  If you're not using `fastlane`, you can also use the `force_for_new_devices` option from the command line:
278
280
 
279
281
  ```
@@ -125,7 +125,7 @@ module Match
125
125
  optional: true),
126
126
  FastlaneCore::ConfigItem.new(key: :force_for_new_devices,
127
127
  env_name: "MATCH_FORCE_FOR_NEW_DEVICES",
128
- description: "Renew the provisioning profiles if the device count on the developer portal has changed",
128
+ description: "Renew the provisioning profiles if the device count on the developer portal has changed. Ignored for profile type 'appstore'",
129
129
  is_string: false,
130
130
  default_value: false),
131
131
  FastlaneCore::ConfigItem.new(key: :skip_docs,
@@ -120,7 +120,14 @@ module Match
120
120
  profile = profiles.last
121
121
 
122
122
  if params[:force_for_new_devices] && !params[:readonly]
123
- params[:force] = device_count_different?(profile: profile) unless params[:force]
123
+ if prov_type != :appstore
124
+ params[:force] = device_count_different?(profile: profile) unless params[:force]
125
+ else
126
+ # App Store provisioning profiles don't contain device identifiers and
127
+ # thus shouldn't be renewed if the device count has changed.
128
+ UI.important "Warning: `force_for_new_devices` is set but is ignored for App Store provisioning profiles."
129
+ UI.important "You can safely stop specifying `force_for_new_devices` when running Match for type 'appstore'."
130
+ end
124
131
  end
125
132
 
126
133
  if profile.nil? or params[:force]
@@ -55,7 +55,7 @@ module Precheck
55
55
  rules.each do |rule|
56
56
  rule_config = Precheck.config[rule.key]
57
57
  rule_level = rule_config[:level].to_sym unless rule_config.nil?
58
- rule_level ||= Precheck.config[:default_rule_level]
58
+ rule_level ||= Precheck.config[:default_rule_level].to_sym
59
59
 
60
60
  if rule_level == RULE_LEVELS[:skip]
61
61
  skipped_rules << rule
@@ -87,13 +87,18 @@ module Precheck
87
87
 
88
88
  # if we passed, then go to the next item, otherwise, recode the failure
89
89
  next unless result.status == VALIDATION_STATES[:failed]
90
- add_new_result_to_rule_hash(rule_hash: error_results, result: result) if rule_level == RULE_LEVELS[:error]
91
- add_new_result_to_rule_hash(rule_hash: warning_results, result: result) if rule_level == RULE_LEVELS[:warn]
90
+ error_results = add_new_result_to_rule_hash(rule_hash: error_results, result: result) if rule_level == RULE_LEVELS[:error]
91
+ warning_results = add_new_result_to_rule_hash(rule_hash: warning_results, result: result) if rule_level == RULE_LEVELS[:warn]
92
92
  rule_failed_at_least_once = true
93
93
  end
94
94
 
95
95
  if rule_failed_at_least_once
96
- UI.error "😵 Failed: #{rule.class.friendly_name}-> #{rule.description}"
96
+ message = "😵 Failed: #{rule.class.friendly_name}-> #{rule.description}"
97
+ if rule_level == RULE_LEVELS[:error]
98
+ UI.error message
99
+ else
100
+ UI.important message
101
+ end
97
102
  else
98
103
  UI.message "✅ Passed: #{rule.class.friendly_name}"
99
104
  end
@@ -109,9 +114,12 @@ module Precheck
109
114
 
110
115
  # hash will be { rule: [result, result, result] }
111
116
  def self.add_new_result_to_rule_hash(rule_hash: nil, result: nil)
112
- result_array = rule_hash[result.rule] ||= []
113
- result_array << result
114
- rule_hash[result.rule] = result_array
117
+ unless rule_hash.include?(result.rule)
118
+ rule_hash[result.rule] = []
119
+ end
120
+ rule_results = rule_hash[result.rule]
121
+ rule_results << result
122
+ return rule_hash
115
123
  end
116
124
 
117
125
  def self.generate_url_items_to_check(app: nil, app_version: nil)
@@ -40,10 +40,14 @@ module Precheck
40
40
  end
41
41
 
42
42
  if processor_result.should_trigger_user_error?
43
- UI.user_error!("precheck found one or more potential problems that must be addressed before submitting to review")
43
+ UI.user_error!("precheck 👮‍♀️ 👮 found one or more potential problems that must be addressed before submitting to review")
44
44
  return false
45
45
  end
46
46
 
47
+ if processor_result.has_errors_or_warnings?
48
+ UI.important "precheck 👮‍♀️ 👮 found one or more potential metadata problems, but this won't prevent fastlane from completing 👍".yellow
49
+ end
50
+
47
51
  if !processor_result.has_errors_or_warnings? && !processor_result.items_not_checked?
48
52
  UI.message "precheck 👮‍♀️ 👮 finished without detecting any potential problems 🛫".green
49
53
  end
@@ -77,8 +81,14 @@ module Precheck
77
81
  if rows.length == 0
78
82
  return nil
79
83
  else
84
+ title_text = "Potential problems"
85
+ if error_results.length > 0
86
+ title_text = title_text.red
87
+ else
88
+ title_text = title_text.yellow
89
+ end
80
90
  return Terminal::Table.new(
81
- title: "Potential problems".red,
91
+ title: title_text,
82
92
  headings: ["Field", "Failure reason"],
83
93
  rows: FastlaneCore::PrintTable.transform_output(rows)
84
94
  ).to_s
@@ -686,7 +686,7 @@ module Spaceship
686
686
  end
687
687
 
688
688
  if response.body.to_s.include?("<title>302 Found</title>")
689
- raise AppleTimeoutError.new, "Apple 302 detected"
689
+ raise AppleTimeoutError.new, "Apple 302 detected - this might be temporary server error, check https://developer.apple.com/system-status/ to see if there is a known downtime"
690
690
  end
691
691
  return response
692
692
  end
@@ -25,6 +25,9 @@ module Spaceship
25
25
  # In-app purchase rejected for whatever reason
26
26
  REJECTED = "Rejected"
27
27
 
28
+ # The developer took the app from the App Store
29
+ DEVELOPER_REMOVED_FROM_SALE = "Developer Removed From Sale"
30
+
28
31
  # Get the iap status matching based on a string (given by iTunes Connect)
29
32
  def self.get_from_string(text)
30
33
  mapping = {
@@ -34,7 +37,8 @@ module Spaceship
34
37
  'inReview' => IN_REVIEW,
35
38
  'readyForSale' => APPROVED,
36
39
  'deleted' => DELETED,
37
- 'rejected' => REJECTED
40
+ 'rejected' => REJECTED,
41
+ 'developerRemovedFromSale' => DEVELOPER_REMOVED_FROM_SALE
38
42
  }
39
43
 
40
44
  mapping.each do |itc_status, readable_status|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.56.0.beta.20170907010003
4
+ version: 2.56.0.beta.20170908010003
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix Krause
@@ -15,7 +15,7 @@ authors:
15
15
  autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
- date: 2017-09-07 00:00:00.000000000 Z
18
+ date: 2017-09-08 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: slack-notifier