fastlane 0.1.18 → 0.1.19

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: c08d6deb51fb737343ca2c4ae1ce4bb55d847413
4
- data.tar.gz: ab06affaf917a58a9a96b869961b00e6ce800878
3
+ metadata.gz: 631af16c08f15cee9b7af0fea8278741b84dde70
4
+ data.tar.gz: eed07c5e6b46944c88ae0f12462222153d8d0b52
5
5
  SHA512:
6
- metadata.gz: bad73425aa485e3ee0a037b9d27fcf47f9de96d6079663056f596f99371eab435b3676940e6a381baf6cccc291d6a65b826f8280579cd39d31333b4e5f440f8d
7
- data.tar.gz: ec15de6387730d65926ca9f49f857552d317d9f3174614647bb3deea7da4c9c9836a6309b26e9ceb496eac87f71f687d124e8dfc6a33ba4727fee3fb4e2b3ff8
6
+ metadata.gz: f679dec6d8d5b9cf95d78ea1a770cfb22cbb0fb13f7c0edf20b5fcecb36426ac6b2126f99f72c1b950d92c590b5b1026fb210e0c297221a7643e856de2358faa
7
+ data.tar.gz: 6e633288c054b437e9831536e3a62511bfa0a3c0fc2f8a0b1aa4da2b85cd222f84a6ca580afa665e5002dcea4cb3062d68185c4fd82a82cdedc3cbe16b90a331
data/README.md CHANGED
@@ -55,7 +55,7 @@ Get in contact with the developer on Twitter: [@KrauseFx](https://twitter.com/Kr
55
55
  - Very flexible configuration using a fully customizable `Fastfile`
56
56
  - Once up and running, you have a fully working **Continuous Deployment** process. Just trigger ```fastlane``` and you're good to go.
57
57
 
58
- ##### Take a look at the [fastlane website](http://fastlane.tools) for more information about why and when to use `fastlane`.
58
+ ##### Take a look at the [fastlane website](https://fastlane.tools) for more information about why and when to use `fastlane`.
59
59
 
60
60
  ##### [Like this tool? Be the first to know about updates and new fastlane tools](https://tinyletter.com/krausefx)
61
61
 
@@ -257,6 +257,90 @@ increment_build_number # automatically increment by one
257
257
  increment_build_number '75' # set a specific number
258
258
  ```
259
259
 
260
+ #### [resign]
261
+ This will resign an ipa with another signing identity and provisioning profile.
262
+
263
+ If you have used the `ipa` and `sigh` actions, then this action automatically gets the `ipa` and `provisioning_profile` values respectively from those actions and you don't need to manually set them (althout you can always override them).
264
+
265
+ ```ruby
266
+ resign(
267
+ ipa: 'path/to/ipa', # can omit if using the `ipa` action
268
+ signing_identity: 'iPhone Distribution: Luka Mirosevic (0123456789)',
269
+ provisioning_profile: 'path/to/profile', # can omit if using the `sigh` action
270
+ )
271
+ ```
272
+
273
+ #### [clean_build_artifacts]
274
+ This action deletes the files that get created in your repo as a result of running the `ipa` and `sigh` commands. It doesn't delete the `fastlane/report.xml` though, this is probably more suited for the .gitignore.
275
+
276
+ Useful if you quickly want to send out a test build by dropping down to the command line and typing something like `fastlane beta`, without leaving your repo in a messy state afterwards.
277
+
278
+ ```ruby
279
+ clean_build_artifacts
280
+ ```
281
+
282
+ #### [ensure_git_status_clean]
283
+ A sanity check to make sure you are working in a repo that is clean. Especially useful to put at the beginning of your fastfile in the `before_all` block, if some of your other actions will touch your filesystem, do things to your git repo, or just as a general reminder to save your work. Also needed as a prerequisite for some other actions like `reset_git_repo`.
284
+
285
+ ```ruby
286
+ ensure_git_status_clean
287
+ ```
288
+
289
+ #### [commit_version_bump]
290
+ This action will create a "Version Bump" commit in your repo. Useful in conjunction with `increment_build_number`.
291
+
292
+ It checks the repo to make sure that only the relevant files have changed, these are the files that `increment_build_number` (`agvtool`) touches:
293
+ - All .plist files
294
+ - The `.xcodeproj/project.pbxproj` file
295
+
296
+ Then commits those files to the repo.
297
+
298
+ Customise the message with the `:message` option, defaults to "Version Bump"
299
+
300
+ If you have other uncommitted changes in your repo, this action will fail. If you started off in a clean repo, and used the `ipa` and or `sigh` actions, then you can use the `clean_build_artifacts` action to clean those temporary files up before running this action.
301
+
302
+ ```ruby
303
+ commit_version_bump
304
+
305
+ commit_version_bump(
306
+ message: 'New version yo!', # create a commit with a custom message
307
+ )
308
+ ```
309
+
310
+ #### [add_git_tag]
311
+ This will automatically tag your build with the following format: `<grouping>/<lane>/<prefix><build_number>`, where:
312
+ - `grouping` is just to keep your tags organised under one "folder", defaults to 'builds'
313
+ - `lane` is the name of the current fastlane lane
314
+ - `prefix` is anything you want to stick in front of the version number, e.g. "v"
315
+ - `build_number` is the build number, which defaults to the value emitted by the `increment_build_number` action
316
+
317
+ For example for build 1234 in the "appstore" lane it will tag the commit with `builds/appstore/1234`
318
+
319
+ ```ruby
320
+ add_git_tag # simple tag with default values
321
+
322
+ add_git_tag(
323
+ grouping: 'fastlane-builds',
324
+ prefix: 'v',
325
+ build_number: 123
326
+ )
327
+ ```
328
+
329
+ #### [reset_git_repo]
330
+ This action will reset your git repo to a clean state, discarding any uncommitted and untracked changes. Useful in case you need to revert the repo back to a clean state, e.g. after the fastlane run.
331
+
332
+ It's a pretty drastic action so it comes with a sort of safety latch. It will only proceed with the reset if either of these conditions are met:
333
+
334
+ - You have called the `ensure_git_status_clean` action prior to calling this action. This ensures that your repo started off in a clean state, so the only things that will get destroyed by this action are files that are created as a byproduct of the fastlane run.
335
+ - You call it with the `:force` option, in which case "you have been warned".
336
+
337
+ Also useful for putting in your `error` block, to bring things back to a pristine state (again with the caveat that you have called `ensure_git_status_clean` before)
338
+
339
+ ```ruby
340
+ reset_git_repo
341
+ reset_git_repo :force # if you don't care about warnings and are absolutely sure that you want to discard all changes. This will reset the repo even if you have valuable uncommitted changes, so use with care!
342
+ ```
343
+
260
344
  #### [HockeyApp](http://hockeyapp.net)
261
345
  ```ruby
262
346
  hockey({
@@ -279,7 +363,30 @@ crashlytics({
279
363
  ipa_path: './app.ipa'
280
364
  })
281
365
  ```
282
- Additionally you can specify `notes_path`, `emails` and `groups`.
366
+ Additionally you can specify `notes_path`, `emails`, `groups` and `notifications`.
367
+
368
+ #### AWS S3 Distribution
369
+
370
+ Add the `s3` action after the `ipa` step:
371
+
372
+ ```ruby
373
+ s3
374
+ ```
375
+
376
+ You can also customize a lot of options:
377
+ ```ruby
378
+ s3({
379
+ # All of these are used to make Shenzhen's `ipa distribute:s3` command
380
+ access_key: ENV['S3_ACCESS_KEY'], # Required from user
381
+ secret_access_key: ENV['S3_SECRET_ACCESS_KEY'], # Required from user
382
+ bucket: ENV['S3_BUCKET'], # Required from user
383
+ file: 'AppName.ipa', # This would come from IpaAction
384
+ dsym: 'AppName.app.dSYM.zip', # This would come from IpaAction
385
+ path: 'v{CFBundleShortVersionString}_b{CFBundleVersion}/' # This is actually the default
386
+ })
387
+ ```
388
+
389
+ It is recommended to **not** store the AWS access keys in the `Fastfile`.
283
390
 
284
391
  #### [DeployGate](https://deploygate.com/)
285
392
 
@@ -331,6 +438,7 @@ Send a message to **topic** with success (:smile:) or failure (:rage:) status.
331
438
  ```ruby
332
439
  typetalk({
333
440
  message: "App successfully released!",
441
+ note_path: 'ChangeLog.md',
334
442
  topicId: 1,
335
443
  success: true,
336
444
  typetalk_token: 'Your Typetalk Token'
@@ -472,7 +580,7 @@ Save and run. The result should look like this:
472
580
 
473
581
  # Tips
474
582
 
475
- ## [`fastlane`](http://fastlane.tools) Toolchain
583
+ ## [`fastlane`](https://fastlane.tools) Toolchain
476
584
 
477
585
  - [`deliver`](https://github.com/KrauseFx/deliver): Upload screenshots, metadata and your app to the App Store using a single command
478
586
  - [`snapshot`](https://github.com/KrauseFx/snapshot): Automate taking localized screenshots of your iOS app on every device
@@ -512,8 +620,12 @@ before_all do |lane|
512
620
  ENV["SLACK_URL"] = "https://hooks.slack.com/services/..."
513
621
  team_id "Q2CBPK58CA"
514
622
 
623
+ ensure_git_status_clean
624
+
515
625
  increment_build_number
626
+
516
627
  cocoapods
628
+
517
629
  xctool :test
518
630
 
519
631
  ipa({
@@ -522,8 +634,12 @@ before_all do |lane|
522
634
  end
523
635
 
524
636
  lane :beta do
637
+ cert
638
+
525
639
  sigh :adhoc
640
+
526
641
  deliver :beta
642
+
527
643
  hockey({
528
644
  api_token: '...',
529
645
  ipa: './app.ipa' # optional
@@ -531,13 +647,24 @@ lane :beta do
531
647
  end
532
648
 
533
649
  lane :deploy do
650
+ cert
651
+
534
652
  sigh
653
+
535
654
  snapshot
655
+
536
656
  deliver :force
657
+
537
658
  frameit
538
659
  end
539
660
 
540
661
  after_all do |lane|
662
+ clean_build_artifacts
663
+
664
+ commit_version_bump
665
+
666
+ add_git_tag
667
+
541
668
  slack({
542
669
  message: "Successfully deployed a new version."
543
670
  })
@@ -545,6 +672,8 @@ after_all do |lane|
545
672
  end
546
673
 
547
674
  error do |lane, exception|
675
+ reset_git_repo
676
+
548
677
  slack({
549
678
  message: "An error occured"
550
679
  })
data/bin/fastlane CHANGED
@@ -16,7 +16,7 @@ class FastlaneApplication
16
16
  program :version, Fastlane::VERSION
17
17
  program :description, 'CLI for \'fastlane\' - Connect all iOS deployment tools into one streamlined workflow'
18
18
  program :help, 'Author', 'Felix Krause <fastlane@krausefx.com>'
19
- program :help, 'Website', 'http://fastlane.tools'
19
+ program :help, 'Website', 'https://fastlane.tools'
20
20
  program :help, 'GitHub', 'https://github.com/krausefx/fastlane'
21
21
  program :help_formatter, :compact
22
22
 
@@ -0,0 +1,20 @@
1
+ module Fastlane
2
+ module Actions
3
+ # Adds a git tag to the current commit
4
+ class AddGitTagAction
5
+ def self.run(params)
6
+ params = params.first
7
+
8
+ grouping = (params && params[:grouping]) || 'builds'
9
+ prefix = (params && params[:prefix]) || ''
10
+ build_number = (params && params[:build_number]) || Actions.lane_context[Actions::SharedValues::BUILD_NUMBER]
11
+
12
+ lane_name = Actions.lane_context[Actions::SharedValues::LANE_NAME]
13
+
14
+ Actions.sh("git tag #{grouping}/#{lane_name}/#{prefix}#{build_number}")
15
+
16
+ Helper.log.info 'Added git tag 🎯.'
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module Fastlane
2
+ module Actions
3
+ class CleanBuildArtifactsAction
4
+ def self.run(_params)
5
+ [
6
+ Actions.lane_context[Actions::SharedValues::IPA_OUTPUT_PATH],
7
+ Actions.lane_context[Actions::SharedValues::SIGH_PROFILE_PATH],
8
+ Actions.lane_context[Actions::SharedValues::DSYM_OUTPUT_PATH],
9
+ ].reject { |file| file.nil? || !File.exist?(file) }.each { |file| File.delete(file) }
10
+
11
+ Helper.log.info 'Cleaned up build artefacts 🐙'.green
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,61 @@
1
+ module Fastlane
2
+ module Actions
3
+ # Commits the current changes in the repo as a version bump, checking to make sure only files which contain version information have been changed.
4
+ class CommitVersionBumpAction
5
+ def self.run(params)
6
+ require 'xcodeproj'
7
+ require 'pathname'
8
+ require 'set'
9
+ require 'shellwords'
10
+
11
+ params = params.first
12
+
13
+ commit_message = (params && params[:message]) || 'Version Bump'
14
+
15
+ # find the repo root path
16
+ repo_path = `git rev-parse --show-toplevel`.strip
17
+
18
+ # find an xcodeproj (ignoreing the Cocoapods one)
19
+ xcodeproj_paths = Dir[File.expand_path(File.join(repo_path, '**/*.xcodeproj'))].reject { |path| /.*Pods.xcodeproj/ =~ path }
20
+
21
+ raise 'Could not find a .xcodeproj in the current repository\'s working directory.'.red if xcodeproj_paths.count == 0
22
+ raise 'Found multiple .xcodeproj projects in the current repository\'s working directory. This tool only support project folders with a single .xcodeproj.'.red if xcodeproj_paths.count > 1
23
+ xcodeproj_path = xcodeproj_paths.first
24
+
25
+ # find the pbxproj path, relative to git directory
26
+ git_pathname = Pathname.new(repo_path)
27
+ pbxproj_pathname = Pathname.new(File.join(xcodeproj_path, 'project.pbxproj'))
28
+ pbxproj_path = pbxproj_pathname.relative_path_from(git_pathname).to_s
29
+
30
+ # find the info_plist files
31
+ project = Xcodeproj::Project.open(xcodeproj_path)
32
+ info_plist_files = project.objects.select { |object| object.isa == 'XCBuildConfiguration' }.map(&:to_hash).map { |object_hash| object_hash['buildSettings'] }.select { |build_settings| build_settings.has_key?('INFOPLIST_FILE') }.map { |build_settings| build_settings['INFOPLIST_FILE'] }.uniq
33
+
34
+ # create our list of files that we expect to have changed, they should all be relative to the project root, which should be equal to the git workdir root
35
+ expected_changed_files = []
36
+ expected_changed_files << pbxproj_path
37
+ expected_changed_files << info_plist_files
38
+ expected_changed_files.flatten!.uniq!
39
+
40
+ # get the list of files that have actually changed in our git workdir
41
+ git_dirty_files = `git diff --name-only HEAD`.split("\n") + `git ls-files --other --exclude-standard`.split("\n")
42
+
43
+ # little user hint
44
+ raise 'No file changes picked up. Make sure you run the `increment_build_number` action first.'.red if git_dirty_files.empty?
45
+
46
+ # check if the files changed are the ones we expected to change (these should be only the files that have version info in them)
47
+ changed_files_as_expected = (Set.new(git_dirty_files) == Set.new(expected_changed_files))
48
+ raise "Found unexpected uncommited changes in the working directory. Expected these files to have changed: #{expected_changed_files}. But found these actual changes: #{git_dirty_files}. Make sure you have cleaned up the build artifacts and are only left with the changed version files at this stage in your lane, and don't touch the working directory while your lane is running.".red unless changed_files_as_expected
49
+
50
+ # get the absolute paths to the files
51
+ git_add_paths = expected_changed_files.map { |path| File.expand_path(File.join(git_pathname, path)) }
52
+
53
+ # then create a commit with a message
54
+ Actions.sh("git add #{git_add_paths.map(&:shellescape).join(' ')}")
55
+ Actions.sh("git commit -m '#{commit_message}'")
56
+
57
+ Helper.log.info "Committed \"#{commit_message}\" 💾.".green
58
+ end
59
+ end
60
+ end
61
+ end
@@ -20,6 +20,7 @@ module Fastlane
20
20
  notes_path = params[:notes_path]
21
21
  emails = params[:emails]
22
22
  groups = params[:groups]
23
+ notifications = params[:notifications]
23
24
 
24
25
  assert_valid_params!(crashlytics_path, api_token, build_secret, ipa_path)
25
26
 
@@ -29,7 +30,7 @@ module Fastlane
29
30
 
30
31
  client = Shenzhen::Plugins::Crashlytics::Client.new(crashlytics_path, api_token, build_secret)
31
32
 
32
- response = client.upload_build(ipa_path, file: ipa_path, notes: notes_path, emails: emails, groups: groups)
33
+ response = client.upload_build(ipa_path, file: ipa_path, notes: notes_path, emails: emails, groups: groups, notifications: notifications)
33
34
 
34
35
  if response
35
36
  Helper.log.info 'Build successfully uploaded to Crashlytics'.green
@@ -0,0 +1,21 @@
1
+ module Fastlane
2
+ module Actions
3
+ module SharedValues
4
+ GIT_REPO_WAS_CLEAN_ON_START = :GIT_REPO_WAS_CLEAN_ON_START
5
+ end
6
+
7
+ # Raises an exception and stop the lane execution if the repo is not in a clean state
8
+ class EnsureGitStatusCleanAction
9
+ def self.run(_params)
10
+ repo_clean = `git status --porcelain`.empty?
11
+
12
+ if repo_clean
13
+ Helper.log.info 'Git status is clean, all good! 💪'.green
14
+ Actions.lane_context[SharedValues::GIT_REPO_WAS_CLEAN_ON_START] = true
15
+ else
16
+ raise 'Git repository is dirty! Please ensure the repo is in a clean state by commiting/stashing/discarding all changes first.'.red
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ module Fastlane
2
+ module Actions
3
+ # Does a hard reset and clean on the repo
4
+ class ResetGitRepoAction
5
+ def self.run(params)
6
+ if params.include?(:force) || Actions.lane_context[SharedValues::GIT_REPO_WAS_CLEAN_ON_START]
7
+ Actions.sh('git reset --hard HEAD')
8
+ Actions.sh('git clean -qfdx')
9
+ Helper.log.info 'Git repo was reset and cleaned back to a pristine state.'.green
10
+ else
11
+ raise 'This is a destructive and potentially dangerous action. To protect from data loss, please add the `ensure_git_status_clean` action to the beginning of your lane, or if you\'re absolutely sure of what you\'re doing then call this action with the :force option.'.red
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ module Fastlane
2
+ module Actions
3
+ # Resigns the ipa
4
+ class ResignAction
5
+ def self.run(params)
6
+ require 'sigh'
7
+
8
+ params = params.first
9
+
10
+ raise 'You must pass valid params to the resign action. Please check the README.md'.red if (params.nil? || params.empty?)
11
+
12
+ ipa = params[:ipa] || Actions.lane_context[SharedValues::IPA_OUTPUT_PATH]
13
+ signing_identity = params[:signing_identity]
14
+ provisioning_profile = params[:provisioning_profile] || Actions.lane_context[SharedValues::SIGH_PROFILE_PATH]
15
+
16
+ raise 'Please pass a valid ipa which should be a path to an ipa on disk'.red unless ipa
17
+ raise 'Please pass a valid signing_identity'.red unless signing_identity
18
+ raise 'Please pass a valid provisioning_profile which should be a path to a profile on disk.'.red unless provisioning_profile
19
+
20
+ # try to resign the ipa
21
+ if Sigh::Resign.resign(ipa, signing_identity, provisioning_profile)
22
+ Helper.log.info 'Successfully re-signed .ipa 🔏.'.green
23
+ else
24
+ raise 'Failed to re-sign .ipa'.red
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -4,6 +4,7 @@ module Fastlane
4
4
  def self.run(params)
5
5
  options = {
6
6
  message: nil,
7
+ note_path: nil,
7
8
  success: true,
8
9
  topicId: nil,
9
10
  typetalk_token: nil,
@@ -15,6 +16,13 @@ module Fastlane
15
16
 
16
17
  emoticon = (options[:success] ? ':smile:' : ':rage:')
17
18
  message = "#{emoticon} #{options[:message].to_s}"
19
+
20
+ note_path = File.expand_path(options[:note_path]) if options[:note_path]
21
+ if note_path and File.exist?(note_path)
22
+ contents = File.read(note_path)
23
+ message += "\n\n```\n#{contents}\n```"
24
+ end
25
+
18
26
  topicId = options[:topicId]
19
27
  typetalk_token = options[:typetalk_token]
20
28
 
@@ -29,7 +37,7 @@ module Fastlane
29
37
 
30
38
  uri = URI.parse("https://typetalk.in/api/v1/topics/#{topicId}")
31
39
  response = Net::HTTP.post_form(uri, {'message' => message,
32
- 'typetalk_token' => typetalk_token})
40
+ 'typetalkToken' => typetalk_token})
33
41
 
34
42
  self.check_response(response)
35
43
  end
@@ -1,3 +1,3 @@
1
1
  module Fastlane
2
- VERSION = '0.1.18'
2
+ VERSION = '0.1.19'
3
3
  end
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: 0.1.18
4
+ version: 0.1.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix Krause
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - ~>
32
32
  - !ruby/object:Gem::Version
33
- version: 0.11.0
33
+ version: 0.12.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ~>
39
39
  - !ruby/object:Gem::Version
40
- version: 0.11.0
40
+ version: 0.12.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: slack-notifier
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ~>
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: xcodeproj
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '0.22'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '0.22'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: fastlane_core
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -309,10 +323,14 @@ files:
309
323
  - lib/fastlane.rb
310
324
  - lib/fastlane/actions/README
311
325
  - lib/fastlane/actions/actions_helper.rb
326
+ - lib/fastlane/actions/add_git_tag.rb
312
327
  - lib/fastlane/actions/cert.rb
328
+ - lib/fastlane/actions/clean_build_artifacts.rb
329
+ - lib/fastlane/actions/commit_version_bump.rb
313
330
  - lib/fastlane/actions/crashlytics.rb
314
331
  - lib/fastlane/actions/deliver.rb
315
332
  - lib/fastlane/actions/deploygate.rb
333
+ - lib/fastlane/actions/ensure_git_status_clean.rb
316
334
  - lib/fastlane/actions/frameit.rb
317
335
  - lib/fastlane/actions/gcovr.rb
318
336
  - lib/fastlane/actions/hipchat.rb
@@ -321,6 +339,8 @@ files:
321
339
  - lib/fastlane/actions/install_cocapods.rb
322
340
  - lib/fastlane/actions/ipa.rb
323
341
  - lib/fastlane/actions/produce.rb
342
+ - lib/fastlane/actions/reset_git_repo.rb
343
+ - lib/fastlane/actions/resign.rb
324
344
  - lib/fastlane/actions/s3.rb
325
345
  - lib/fastlane/actions/say.rb
326
346
  - lib/fastlane/actions/sigh.rb