fastlane 0.11.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/assets/FastfileTemplate +3 -0
- data/lib/fastlane.rb +1 -0
- data/lib/fastlane/action.rb +5 -0
- data/lib/fastlane/action_collector.rb +3 -1
- data/lib/fastlane/actions/actions_helper.rb +5 -0
- data/lib/fastlane/actions/add_git_tag.rb +21 -15
- data/lib/fastlane/actions/cert.rb +2 -2
- data/lib/fastlane/actions/clean_build_artifacts.rb +1 -1
- data/lib/fastlane/actions/commit_version_bump.rb +15 -8
- data/lib/fastlane/actions/crashlytics.rb +51 -66
- data/lib/fastlane/actions/deliver.rb +32 -15
- data/lib/fastlane/actions/deploygate.rb +29 -22
- data/lib/fastlane/actions/ensure_git_status_clean.rb +1 -1
- data/lib/fastlane/actions/frameit.rb +2 -2
- data/lib/fastlane/actions/gcovr.rb +2 -2
- data/lib/fastlane/actions/hipchat.rb +36 -23
- data/lib/fastlane/actions/hockey.rb +37 -23
- data/lib/fastlane/actions/increment_build_number.rb +14 -19
- data/lib/fastlane/actions/increment_version_number.rb +42 -44
- data/lib/fastlane/actions/install_carthage.rb +1 -1
- data/lib/fastlane/actions/install_cocapods.rb +1 -1
- data/lib/fastlane/actions/ipa.rb +69 -47
- data/lib/fastlane/actions/notify.rb +1 -1
- data/lib/fastlane/actions/pem.rb +1 -1
- data/lib/fastlane/actions/produce.rb +3 -4
- data/lib/fastlane/actions/push_to_git_remote.rb +24 -14
- data/lib/fastlane/actions/register_devices.rb +23 -11
- data/lib/fastlane/actions/reset_git_repo.rb +13 -5
- data/lib/fastlane/actions/resign.rb +19 -16
- data/lib/fastlane/actions/s3.rb +56 -37
- data/lib/fastlane/actions/sigh.rb +1 -1
- data/lib/fastlane/actions/slack.rb +31 -13
- data/lib/fastlane/actions/snapshot.rb +13 -6
- data/lib/fastlane/actions/team_id.rb +1 -1
- data/lib/fastlane/actions/team_name.rb +1 -1
- data/lib/fastlane/actions/testmunk.rb +28 -14
- data/lib/fastlane/actions/typetalk.rb +1 -1
- data/lib/fastlane/actions/update_fastlane.rb +115 -0
- data/lib/fastlane/actions/update_project_code_signing.rb +22 -7
- data/lib/fastlane/actions/xcode_select.rb +1 -1
- data/lib/fastlane/actions/xcodebuild.rb +56 -12
- data/lib/fastlane/actions_list.rb +2 -2
- data/lib/fastlane/configuration_helper.rb +28 -0
- data/lib/fastlane/fast_file.rb +17 -0
- data/lib/fastlane/fastlane_folder.rb +3 -3
- data/lib/fastlane/setup.rb +11 -5
- data/lib/fastlane/version.rb +1 -1
- metadata +7 -5
@@ -5,7 +5,7 @@ module Fastlane
|
|
5
5
|
|
6
6
|
class TeamIdAction < Action
|
7
7
|
def self.run(params)
|
8
|
-
team = params.first
|
8
|
+
team = (params.first rescue nil)
|
9
9
|
raise "Please pass your Team ID (e.g. team_id 'Q2CBPK58CA')".red unless team.to_s.length > 0
|
10
10
|
|
11
11
|
Helper.log.info "Setting Team ID to '#{team}' for all build steps"
|
@@ -5,7 +5,7 @@ module Fastlane
|
|
5
5
|
|
6
6
|
class TeamNameAction < Action
|
7
7
|
def self.run(params)
|
8
|
-
team = params.first
|
8
|
+
team = (params.first rescue nil)
|
9
9
|
raise "Please pass your Team Name (e.g. team_name 'Felix Krause')".red unless team.to_s.length > 0
|
10
10
|
|
11
11
|
Helper.log.info "Setting Team Name to '#{team}' for all build steps"
|
@@ -12,20 +12,13 @@
|
|
12
12
|
module Fastlane
|
13
13
|
module Actions
|
14
14
|
class TestmunkAction < Action
|
15
|
-
def self.run(
|
16
|
-
raise "Please pass your Testmunk email address using `ENV['TESTMUNK_EMAIL'] = 'value'`" unless ENV['TESTMUNK_EMAIL']
|
17
|
-
raise "Please pass your Testmunk API Key using `ENV['TESTMUNK_API'] = 'value'`" unless ENV['TESTMUNK_API']
|
18
|
-
raise "Please pass your Testmunk app name using `ENV['TESTMUNK_APP'] = 'value'`" unless ENV['TESTMUNK_APP']
|
19
|
-
|
20
|
-
ipa_path = ENV['TESTMUNK_IPA'] || ENV[Actions::SharedValues::IPA_OUTPUT_PATH.to_s]
|
21
|
-
raise "Please pass a path to your ipa file using `ENV['TESTMUNK_IPA'] = 'value'`" unless ipa_path
|
22
|
-
|
15
|
+
def self.run(config)
|
23
16
|
Helper.log.info 'Testmunk: Uploading the .ipa and starting your tests'.green
|
24
17
|
|
25
18
|
response = system("#{"curl -H 'Accept: application/vnd.testmunk.v1+json'" +
|
26
|
-
" -F 'file=@#{
|
27
|
-
" -F 'email=#{
|
28
|
-
" https://#{
|
19
|
+
" -F 'file=@#{config[:ipa]}' -F 'autoStart=true'" +
|
20
|
+
" -F 'email=#{config[:email]}'" +
|
21
|
+
" https://#{config[:api]}@api.testmunk.com/apps/#{config[:app]}/testruns"}")
|
29
22
|
|
30
23
|
if response
|
31
24
|
Helper.log.info 'Your tests are being executed right now. Please wait for the mail with results and decide if you want to continue.'.green
|
@@ -40,9 +33,30 @@ module Fastlane
|
|
40
33
|
|
41
34
|
def self.available_options
|
42
35
|
[
|
43
|
-
|
44
|
-
|
45
|
-
|
36
|
+
FastlaneCore::ConfigItem.new(key: :ipa,
|
37
|
+
env_name: "TESTMUNK_IPA",
|
38
|
+
description: "Path to IPA",
|
39
|
+
verify_block: Proc.new do |value|
|
40
|
+
raise "Please pass to existing ipa" unless File.exists?value
|
41
|
+
end),
|
42
|
+
FastlaneCore::ConfigItem.new(key: :email,
|
43
|
+
env_name: "TESTMUNK_EMAIL",
|
44
|
+
description: "Your email address",
|
45
|
+
verify_block: Proc.new do |value|
|
46
|
+
raise "Please pass your Testmunk email address using `ENV['TESTMUNK_EMAIL'] = 'value'`" unless value
|
47
|
+
end),
|
48
|
+
FastlaneCore::ConfigItem.new(key: :api,
|
49
|
+
env_name: "TESTMUNK_API",
|
50
|
+
description: "Testmunk API Key",
|
51
|
+
verify_block: Proc.new do |value|
|
52
|
+
raise "Please pass your Testmunk API Key using `ENV['TESTMUNK_API'] = 'value'`" unless value
|
53
|
+
end),
|
54
|
+
FastlaneCore::ConfigItem.new(key: :app,
|
55
|
+
env_name: "TESTMUNK_APP",
|
56
|
+
description: "Testmunk App Name",
|
57
|
+
verify_block: Proc.new do |value|
|
58
|
+
raise "Please pass your Testmunk app name using `ENV['TESTMUNK_APP'] = 'value'`" unless value
|
59
|
+
end),
|
46
60
|
]
|
47
61
|
end
|
48
62
|
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'rubygems/spec_fetcher'
|
2
|
+
require 'rubygems/commands/update_command'
|
3
|
+
|
4
|
+
module Fastlane
|
5
|
+
module Actions
|
6
|
+
# Makes sure fastlane tools are up-to-date when running fastlane
|
7
|
+
class UpdateFastlaneAction < Action
|
8
|
+
|
9
|
+
ALL_TOOLS = [
|
10
|
+
"fastlane",
|
11
|
+
"fastlane_core",
|
12
|
+
"deliver",
|
13
|
+
"snapshot",
|
14
|
+
"frameit",
|
15
|
+
"pem",
|
16
|
+
"sigh",
|
17
|
+
"produce",
|
18
|
+
"cert",
|
19
|
+
"codes",
|
20
|
+
"credentials_manager"
|
21
|
+
]
|
22
|
+
|
23
|
+
def self.run(options)
|
24
|
+
if options[:no_update]
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
28
|
+
tools_to_update = options[:tools].split ',' unless options[:tools].nil?
|
29
|
+
tools_to_update ||= all_installed_tools
|
30
|
+
|
31
|
+
if tools_to_update.count == 0
|
32
|
+
Helper.log.error "No tools specified or couldn't find any installed fastlane.tools".red
|
33
|
+
return
|
34
|
+
end
|
35
|
+
|
36
|
+
updater = Gem::Commands::UpdateCommand.new
|
37
|
+
|
38
|
+
sudo_needed = !File.writable?(Gem.dir)
|
39
|
+
|
40
|
+
if sudo_needed
|
41
|
+
Helper.log.warn "It seems that your Gem directory is not writable by your current User."
|
42
|
+
Helper.log.warn "Fastlane would need sudo rights to update itself, however, running 'sudo fastlane' is not recommended."
|
43
|
+
Helper.log.warn "If you still want to use this action, please read the Actions.md documentation on a guide how to set this up."
|
44
|
+
return
|
45
|
+
end
|
46
|
+
|
47
|
+
highest_versions = updater.highest_installed_gems.keep_if {|key| tools_to_update.include? key }
|
48
|
+
update_needed = updater.which_to_update(highest_versions, tools_to_update)
|
49
|
+
|
50
|
+
if update_needed.count == 0
|
51
|
+
Helper.log.info "Nothing to update! 😮".yellow
|
52
|
+
return
|
53
|
+
end
|
54
|
+
|
55
|
+
#suppress updater output - very noisy
|
56
|
+
Gem::DefaultUserInteraction.ui = Gem::SilentUI.new
|
57
|
+
|
58
|
+
update_needed.each do |tool_info|
|
59
|
+
tool = tool_info[0]
|
60
|
+
local_version = Gem::Version.new(highest_versions[tool].version)
|
61
|
+
latest_version = FastlaneCore::UpdateChecker.fetch_latest(tool)
|
62
|
+
Helper.log.info "Updating #{tool} from #{local_version} to #{latest_version} ... 🚀"
|
63
|
+
|
64
|
+
# Approximate_recommendation will create a string like "~> 0.10" from a version 0.10.0, e.g. one that is valid for versions >= 0.10 and <1.0
|
65
|
+
updater.update_gem tool, Gem::Requirement.new(local_version.approximate_recommendation)
|
66
|
+
|
67
|
+
Helper.log.info "Finished updating #{tool}"
|
68
|
+
end
|
69
|
+
|
70
|
+
any_updates = updater.installer.installed_gems.any? do |updated_tool|
|
71
|
+
updated_tool.version > highest_versions[updated_tool.name].version
|
72
|
+
end
|
73
|
+
|
74
|
+
if any_updates
|
75
|
+
Helper.log.info "fastlane.tools succesfully updated! I will now restart myself... 😴"
|
76
|
+
|
77
|
+
# Set no_update to true so we don't try to update again
|
78
|
+
exec "FL_NO_UPDATE=true #{$PROGRAM_NAME} #{ARGV.join ' '}"
|
79
|
+
else
|
80
|
+
Helper.log.info "All fastlane tools are up-to-date!"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.all_installed_tools
|
85
|
+
Gem::Specification.select { |s| ALL_TOOLS.include? s.name }.map {|s| s.name}.uniq
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.description
|
89
|
+
"Makes sure fastlane-tools are up-to-date when running fastlane"
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.available_options
|
93
|
+
[
|
94
|
+
FastlaneCore::ConfigItem.new(key: :tools,
|
95
|
+
env_name: "FL_TOOLS_TO_UPDATE",
|
96
|
+
description: "Comma separated list of fastlane tools to update (e.g. fastlane,deliver,sigh). If not specified, all currently installed fastlane-tools will be updated",
|
97
|
+
optional: true),
|
98
|
+
FastlaneCore::ConfigItem.new(key: :no_update,
|
99
|
+
env_name: "FL_NO_UPDATE",
|
100
|
+
description: "Don't update during this run. Defaults to false",
|
101
|
+
is_string: false,
|
102
|
+
default_value: false),
|
103
|
+
]
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.author
|
107
|
+
"milch"
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.is_supported?(platform)
|
111
|
+
true
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -5,19 +5,16 @@ module Fastlane
|
|
5
5
|
|
6
6
|
class UpdateProjectCodeSigningAction < Action
|
7
7
|
def self.run(params)
|
8
|
-
path = params
|
8
|
+
path = params[:path]
|
9
9
|
path = File.join(path, "project.pbxproj")
|
10
10
|
raise "Could not find path to project config '#{path}'. Pass the path to your project (not workspace)!".red unless File.exists?(path)
|
11
11
|
|
12
|
-
|
13
|
-
udid ||= ENV["SIGH_UDID"]
|
14
|
-
|
15
|
-
Helper.log.info("Updating provisioning profile UDID (#{udid}) for the given project '#{path}'")
|
12
|
+
Helper.log.info("Updating provisioning profile UDID (#{params[:udid]}) for the given project '#{path}'")
|
16
13
|
|
17
14
|
p = File.read(path)
|
18
|
-
File.write(path, p.gsub(/PROVISIONING_PROFILE = ".*";/, "PROVISIONING_PROFILE = \"#{udid}\";"))
|
15
|
+
File.write(path, p.gsub(/PROVISIONING_PROFILE = ".*";/, "PROVISIONING_PROFILE = \"#{params[:udid]}\";"))
|
19
16
|
|
20
|
-
Helper.log.info("Successfully updated project settings to use UDID '#{udid}'".green)
|
17
|
+
Helper.log.info("Successfully updated project settings to use UDID '#{params[:udid]}'".green)
|
21
18
|
end
|
22
19
|
|
23
20
|
def self.description
|
@@ -28,6 +25,24 @@ module Fastlane
|
|
28
25
|
"This feature is not yet 100% finished"
|
29
26
|
end
|
30
27
|
|
28
|
+
def self.available_options
|
29
|
+
[
|
30
|
+
FastlaneCore::ConfigItem.new(key: :path,
|
31
|
+
env_name: "FL_PROJECT_SIGNING_PROJECT_PATH",
|
32
|
+
description: "Path to your Xcode project",
|
33
|
+
verify_block: Proc.new do |value|
|
34
|
+
raise "Path is invalid".red unless File.exists?(value)
|
35
|
+
end),
|
36
|
+
FastlaneCore::ConfigItem.new(key: :udid,
|
37
|
+
env_name: "FL_PROJECT_SIGNING_UDID",
|
38
|
+
description: "The UDID of the provisioning profile you want to use",
|
39
|
+
default_value: ENV["SIGH_UDID"],
|
40
|
+
verify_block: Proc.new do |value|
|
41
|
+
raise "Path is invalid".red unless File.exists?(value)
|
42
|
+
end)
|
43
|
+
]
|
44
|
+
end
|
45
|
+
|
31
46
|
def self.author
|
32
47
|
"KrauseFx"
|
33
48
|
end
|
@@ -19,7 +19,7 @@ module Fastlane
|
|
19
19
|
#
|
20
20
|
class XcodeSelectAction < Action
|
21
21
|
def self.run(params)
|
22
|
-
xcode_path = params.first
|
22
|
+
xcode_path = (params.first rescue nil)
|
23
23
|
|
24
24
|
# Verify that a param was passed in
|
25
25
|
raise "Path to Xcode application required (e.x. \"/Applications/Xcode.app\")".red unless xcode_path.to_s.length > 0
|
@@ -66,7 +66,7 @@ module Fastlane
|
|
66
66
|
end
|
67
67
|
|
68
68
|
|
69
|
-
if params
|
69
|
+
if params
|
70
70
|
# Operation bools
|
71
71
|
archiving = params.key? :archive
|
72
72
|
exporting = params.key? :export_archive
|
@@ -246,9 +246,9 @@ module Fastlane
|
|
246
246
|
|
247
247
|
class XcarchiveAction < Action
|
248
248
|
def self.run(params)
|
249
|
-
params_hash = params
|
249
|
+
params_hash = params || {}
|
250
250
|
params_hash[:archive] = true
|
251
|
-
XcodebuildAction.run(
|
251
|
+
XcodebuildAction.run(params_hash)
|
252
252
|
end
|
253
253
|
|
254
254
|
def self.description
|
@@ -262,13 +262,22 @@ module Fastlane
|
|
262
262
|
def self.is_supported?(platform)
|
263
263
|
platform == :ios
|
264
264
|
end
|
265
|
+
|
266
|
+
def self.available_options
|
267
|
+
[
|
268
|
+
['archive_path', 'The path to archive the to. Must contain `.xcarchive`'],
|
269
|
+
['workspace', 'The workspace to use'],
|
270
|
+
['scheme', 'The scheme to build'],
|
271
|
+
['build_settings', 'Hash of additional build information']
|
272
|
+
]
|
273
|
+
end
|
265
274
|
end
|
266
275
|
|
267
276
|
class XcbuildAction < Action
|
268
277
|
def self.run(params)
|
269
|
-
params_hash = params
|
278
|
+
params_hash = params || {}
|
270
279
|
params_hash[:build] = true
|
271
|
-
XcodebuildAction.run(
|
280
|
+
XcodebuildAction.run(params_hash)
|
272
281
|
end
|
273
282
|
|
274
283
|
def self.description
|
@@ -282,13 +291,23 @@ module Fastlane
|
|
282
291
|
def self.is_supported?(platform)
|
283
292
|
platform == :ios
|
284
293
|
end
|
294
|
+
|
295
|
+
def self.available_options
|
296
|
+
[
|
297
|
+
['archive', 'Set to true to build archive'],
|
298
|
+
['archive_path', 'The path to archive the to. Must contain `.xcarchive`'],
|
299
|
+
['workspace', 'The workspace to use'],
|
300
|
+
['scheme', 'The scheme to build'],
|
301
|
+
['build_settings', 'Hash of additional build information']
|
302
|
+
]
|
303
|
+
end
|
285
304
|
end
|
286
305
|
|
287
306
|
class XccleanAction < Action
|
288
307
|
def self.run(params)
|
289
|
-
params_hash = params
|
308
|
+
params_hash = params || {}
|
290
309
|
params_hash[:clean] = true
|
291
|
-
XcodebuildAction.run(
|
310
|
+
XcodebuildAction.run(params_hash)
|
292
311
|
end
|
293
312
|
|
294
313
|
def self.description
|
@@ -302,13 +321,23 @@ module Fastlane
|
|
302
321
|
def self.is_supported?(platform)
|
303
322
|
platform == :ios
|
304
323
|
end
|
324
|
+
|
325
|
+
def self.available_options
|
326
|
+
[
|
327
|
+
['archive', 'Set to true to build archive'],
|
328
|
+
['archive_path', 'The path to archive the to. Must contain `.xcarchive`'],
|
329
|
+
['workspace', 'The workspace to use'],
|
330
|
+
['scheme', 'The scheme to build'],
|
331
|
+
['build_settings', 'Hash of additional build information']
|
332
|
+
]
|
333
|
+
end
|
305
334
|
end
|
306
335
|
|
307
336
|
class XcexportAction < Action
|
308
337
|
def self.run(params)
|
309
|
-
params_hash = params
|
338
|
+
params_hash = params || {}
|
310
339
|
params_hash[:export_archive] = true
|
311
|
-
XcodebuildAction.run(
|
340
|
+
XcodebuildAction.run(params_hash)
|
312
341
|
end
|
313
342
|
|
314
343
|
def self.description
|
@@ -319,6 +348,16 @@ module Fastlane
|
|
319
348
|
"dtrenz"
|
320
349
|
end
|
321
350
|
|
351
|
+
def self.available_options
|
352
|
+
[
|
353
|
+
['archive', 'Set to true to build archive'],
|
354
|
+
['archive_path', 'The path to archive the to. Must contain `.xcarchive`'],
|
355
|
+
['workspace', 'The workspace to use'],
|
356
|
+
['scheme', 'The scheme to build'],
|
357
|
+
['build_settings', 'Hash of additional build information']
|
358
|
+
]
|
359
|
+
end
|
360
|
+
|
322
361
|
def self.is_supported?(platform)
|
323
362
|
platform == :ios
|
324
363
|
end
|
@@ -326,17 +365,22 @@ module Fastlane
|
|
326
365
|
|
327
366
|
class XctestAction < Action
|
328
367
|
def self.run(params)
|
329
|
-
params_hash = params
|
368
|
+
params_hash = params || {}
|
330
369
|
params_hash[:test] = true
|
331
|
-
XcodebuildAction.run(
|
370
|
+
XcodebuildAction.run(params_hash)
|
332
371
|
end
|
333
372
|
|
334
373
|
def self.description
|
335
374
|
"Runs tests on the given simulator"
|
336
375
|
end
|
337
376
|
|
338
|
-
def available_options
|
377
|
+
def self.available_options
|
339
378
|
[
|
379
|
+
['archive', 'Set to true to build archive'],
|
380
|
+
['archive_path', 'The path to archive the to. Must contain `.xcarchive`'],
|
381
|
+
['workspace', 'The workspace to use'],
|
382
|
+
['scheme', 'The scheme to build'],
|
383
|
+
['build_settings', 'Hash of additional build information'],
|
340
384
|
['destination', 'The simulator to use, e.g. "name=iPhone 5s,OS=8.1"']
|
341
385
|
]
|
342
386
|
end
|
@@ -107,7 +107,7 @@ module Fastlane
|
|
107
107
|
end
|
108
108
|
|
109
109
|
private
|
110
|
-
def self.parse_options(options,
|
110
|
+
def self.parse_options(options, fill_all = true)
|
111
111
|
rows = []
|
112
112
|
rows << [options] if options.kind_of?String
|
113
113
|
|
@@ -119,7 +119,7 @@ module Fastlane
|
|
119
119
|
raise "Invalid number of elements in this row: #{current}. Must be 2 or 3".red unless ([2, 3].include?current.count)
|
120
120
|
rows << current
|
121
121
|
rows.last[0] = rows.last.first.yellow # color it yellow :)
|
122
|
-
rows.last << nil
|
122
|
+
rows.last << nil while (fill_all and rows.last.count < 3) # to have a nice border in the table
|
123
123
|
end
|
124
124
|
end
|
125
125
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Fastlane
|
2
|
+
class ConfigurationHelper
|
3
|
+
def self.parse(action, params)
|
4
|
+
begin
|
5
|
+
first_element = (action.available_options.first rescue nil) # might also be nil
|
6
|
+
|
7
|
+
if first_element and first_element.kind_of?FastlaneCore::ConfigItem
|
8
|
+
# default use case
|
9
|
+
return FastlaneCore::Configuration.create(action.available_options, params)
|
10
|
+
|
11
|
+
elsif first_element
|
12
|
+
Helper.log.error "Action '#{action}' uses the old configuration format."
|
13
|
+
puts "Old configuration format for action '#{action}'".red if Helper.is_test?
|
14
|
+
return params
|
15
|
+
else
|
16
|
+
|
17
|
+
# No parameters... we still need the configuration object array
|
18
|
+
FastlaneCore::Configuration.create(action.available_options, {})
|
19
|
+
|
20
|
+
end
|
21
|
+
rescue => ex
|
22
|
+
Helper.log.fatal "You provided an option to action #{action.action_name} which is not supported.".red
|
23
|
+
Helper.log.fatal "Check out the available options below or run `fastlane action #{action.action_name}`".red
|
24
|
+
raise ex
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|