diff --git a/README.md b/README.md index 99858d90f85..3bdfc4363a4 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ A detailed description about how ```fastlane``` stores your credentials is avail ## Special Thanks -Thanks to all sponsors and contributors for extending and improving the `fastlane` suite: +Thanks to all contributors for extending and improving the `fastlane` suite: - [Detroit Labs](http://www.detroitlabs.com/) - Josh Holtz ([@joshdholtz](https://twitter.com/joshdholtz)) - Ash Furrow ([@ashfurrow](https://twitter.com/ashfurrow)) diff --git a/docs/Actions.md b/docs/Actions.md index f792d209955..5d2ceb44303 100644 --- a/docs/Actions.md +++ b/docs/Actions.md @@ -36,7 +36,20 @@ You can run any xctool action. This will require having [xctool](https://github. xctool :test ``` -It is recommended to have the `xctool` configuration stored in a [`xctool-args`](https://github.com/facebook/xctool#configuration-xctool-args) file. +It is recommended to have the `xctool` configuration stored in a [`.xctool-args`](https://github.com/facebook/xctool#configuration-xctool-args) file. + +If you prefer to have the build configuration stored in the `Fastfile`: + +```ruby +xctool :test, [ + "--workspace", "'AwesomeApp.xcworkspace'", + "--scheme", "'Schema Name'", + "--configuration", "Debug", + "--sdk", "iphonesimulator", + "--arch", "i386" + ].join(" ") +``` + ### [snapshot](https://github.com/KrauseFx/snapshot) diff --git a/fastlane.gemspec b/fastlane.gemspec index 0e93ef6ee38..027be3d8c74 100644 --- a/fastlane.gemspec +++ b/fastlane.gemspec @@ -27,7 +27,7 @@ Gem::Specification.new do |spec| spec.add_dependency 'aws-sdk', '~> 1.0' # Upload ipa files to S3 spec.add_dependency 'xcodeproj', '~> 0.20' # Needed for commit_version_bump action spec.add_dependency 'xcpretty', '~> 0.1' # prettify xcodebuild output - spec.add_dependency 'cupertino', '~> 1.3', '>= 1.3.1' # for registering iOS devices with the Apple Developer Center + spec.add_dependency 'cupertino', '>= 1.3.2', '>= 1.3.1' # for registering iOS devices with the Apple Developer Center spec.add_dependency 'terminal-notifier', '~> 1.6.2' # Mac OS X notifications spec.add_dependency 'terminal-table', '~> 1.4.5' # Actions documentation @@ -40,7 +40,7 @@ Gem::Specification.new do |spec| spec.add_dependency 'pem', '>= 0.4.0' spec.add_dependency 'sigh', '>= 0.4.8' spec.add_dependency 'produce', '>= 0.2.0' - spec.add_dependency 'cert', '>= 0.1.4' + spec.add_dependency 'cert', '>= 0.1.5' # Development only spec.add_development_dependency 'bundler' diff --git a/lib/assets/custom_action_template.rb b/lib/assets/custom_action_template.rb index 23ccbb0b5be..ac0e4c9ecf5 100644 --- a/lib/assets/custom_action_template.rb +++ b/lib/assets/custom_action_template.rb @@ -6,12 +6,47 @@ module SharedValues class [[NAME_CLASS]] < Action def self.run(params) + params = params.first + puts "My Ruby Code!" - # puts "Parameter: #{params.first}" + # puts "Parameter Path: #{params[:first]}" # sh "shellcommand ./path" # Actions.lane_context[SharedValues::[[NAME_UP]]_CUSTOM_VALUE] = "my_val" end + + + + ##################################################### + # @!group Documentation + ##################################################### + + def self.description + "A short description with <= 80 characters of what this action does" + end + + def self.available_options + # Define all options your action supports. + # The environment variable (last parameters) is optional, remove it if you don't need it + # You can add as many parameters as you want + [ + ['path', 'Describe what this parameter is useful for', 'ENVIRONMENT_VARIABLE_NAME'], + ['second', 'Describe what this parameter is useful for'] + ] + end + + def self.output + # Define the shared values you are going to provide + # Example + [ + ['[[NAME_UP]]_CUSTOM_VALUE', 'A description of what this value contains'] + ] + end + + def self.author + # So no one will ever forget your contribution to fastlane :) You are awesome btw! + '[Your GitHub Name]' + end end end end \ No newline at end of file diff --git a/lib/fastlane/action.rb b/lib/fastlane/action.rb index ea113bf9917..88d792f9a5e 100644 --- a/lib/fastlane/action.rb +++ b/lib/fastlane/action.rb @@ -8,6 +8,10 @@ def self.description "No description provided".red end + def self.details + nil # this is your change to provide a more detailed description of this action + end + def self.available_options # Return an array of 2-3 element arrays, like: # [ diff --git a/lib/fastlane/actions/commit_version_bump.rb b/lib/fastlane/actions/commit_version_bump.rb index acacc626aeb..47c0bb91e45 100644 --- a/lib/fastlane/actions/commit_version_bump.rb +++ b/lib/fastlane/actions/commit_version_bump.rb @@ -74,6 +74,21 @@ def self.run(params) Helper.log.info "Committed \"#{commit_message}\" 💾.".green end + + def self.description + "Creates a 'Version Bump' commit. Run after `increment_build_number`" + end + + def self.available_options + [ + ['message', 'The commit message. Defaults to "Version Bump"'], + ['xcodeproj', 'The path to your project file (Not the workspace). If you have only one, this is optional'] + ] + end + + def self.author + "lmirosevic" + end end end end diff --git a/lib/fastlane/actions/crashlytics.rb b/lib/fastlane/actions/crashlytics.rb index 0561d59960e..0741e0b50e0 100644 --- a/lib/fastlane/actions/crashlytics.rb +++ b/lib/fastlane/actions/crashlytics.rb @@ -83,6 +83,26 @@ def self.assert_valid_ipa_path!(ipa_path) raise "No IPA file given or found, pass using `ipa_path: 'path/app.ipa'`".red end + def self.description + "Upload a new build to Crashlytics Beta" + end + + def self.available_options + [ + ['crashlytics_path', 'Path to your Crashlytics bundle', 'CRASHLYTICS_FRAMEWORK_PATH'], + ['api_token', 'Crashlytics Beta API Token', 'CRASHLYTICS_API_TOKEN'], + ['build_secret', 'Crashlytics Build Secret', 'CRASHLYTICS_BUILD_SECRET'], + ['ipa_path', 'Path to your IPA file. Optional if you use the `ipa` or `xcodebuild` action'], + ['notes_path', 'Release Notes'], + ['emails', 'Pass email address'], + ['notifications', 'Crashlytics notification option'] + ] + end + + def self.author + "pedrogimenez" + end + private_class_method :assert_params_given!, :assert_valid_params!, :assert_valid_crashlytics_path!, diff --git a/lib/fastlane/actions/deploygate.rb b/lib/fastlane/actions/deploygate.rb index f58fd3f9ea0..21ae0cba629 100644 --- a/lib/fastlane/actions/deploygate.rb +++ b/lib/fastlane/actions/deploygate.rb @@ -83,6 +83,31 @@ def self.help_message(response) Helper.log.error message.red if message end private_class_method :help_message + + def self.description + "Upload a new build to DeployGate" + end + + def self.available_options + [ + ['api_token', 'DeployGate API Token'], + ['user', 'Target username or organization name'], + ['ipa', 'Path to your IPA file. Defaults to output of xcodebuild and ipa'], + ['message', 'Text for the uploaded build'] + ] + end + + def self.output + [ + ['DEPLOYGATE_URL', 'URL of the newly uploaded build'], + ['DEPLOYGATE_REVISION', 'auto incremented revision number'], + ['DEPLOYGATE_APP_INFO', 'Contains app revision, bundle identifier, etc.'] + ] + end + + def self.author + "tnj" + end end end end diff --git a/lib/fastlane/actions/ensure_git_status_clean.rb b/lib/fastlane/actions/ensure_git_status_clean.rb index 5765f7c50f5..28d0e7b2237 100644 --- a/lib/fastlane/actions/ensure_git_status_clean.rb +++ b/lib/fastlane/actions/ensure_git_status_clean.rb @@ -16,6 +16,20 @@ def self.run(_params) raise 'Git repository is dirty! Please ensure the repo is in a clean state by commiting/stashing/discarding all changes first.'.red end end + + def self.description + "Raises an exception if there are uncommited git changes" + end + + def self.output + [ + ['GIT_REPO_WAS_CLEAN_ON_START', 'Stores the fact that the git repo was clean at some point'] + ] + end + + def self.author + "lmirosevic" + end end end end diff --git a/lib/fastlane/actions/fastlane_version.rb b/lib/fastlane/actions/fastlane_version.rb index d37dbc62f16..906c159aec8 100644 --- a/lib/fastlane/actions/fastlane_version.rb +++ b/lib/fastlane/actions/fastlane_version.rb @@ -19,6 +19,14 @@ def self.run(params) def self.step_text "Verifying required fastlane version" end + + def self.author + "KrauseFx" + end + + def self.description + "Verifies the minimum fastlane version required" + end end end end diff --git a/lib/fastlane/actions/frameit.rb b/lib/fastlane/actions/frameit.rb index 059119a5ef1..9166adba986 100644 --- a/lib/fastlane/actions/frameit.rb +++ b/lib/fastlane/actions/frameit.rb @@ -1,8 +1,5 @@ module Fastlane module Actions - module SharedValues - end - class FrameitAction < Action def self.run(params) return if Helper.test? @@ -24,6 +21,14 @@ def self.run(params) FastlaneCore::UpdateChecker.show_update_status('frameit', Frameit::VERSION) end end + + def self.description + "Adds device frames around the screenshots using frameit" + end + + def self.author + "KrauseFx" + end end end end diff --git a/lib/fastlane/actions/gcovr.rb b/lib/fastlane/actions/gcovr.rb index 443e205d744..1f51b3c61a8 100644 --- a/lib/fastlane/actions/gcovr.rb +++ b/lib/fastlane/actions/gcovr.rb @@ -101,6 +101,40 @@ def self.params_hash_to_cli_args(params) end end.compact end + + def self.description + "Runs test coverage reports for your Xcode project" + end + + def self.available_options + [ + ['object_directory', 'Specify the directory that contains the gcov data files.'], + ['output', 'Print output to this filename Keep the temporary *.gcov files generated by gcov.'], + ['keep', 'Keep the temporary *.gcov files generated by gcov.'], + ['delete', 'Delete the coverage files after they are processed.'], + ['filter', 'Keep only the data files that match this regular expression'], + ['exclude', 'Exclude data files that match this regular expression'], + ['gcov_filter', 'Keep only gcov data files that match this regular expression'], + ['gcov_exclude', 'Exclude gcov data files that match this regular expression'], + ['root', 'Defines the root directory for source files.'], + ['xml', 'Generate XML instead of the normal tabular output.'], + ['xml_pretty', 'Generate pretty XML instead of the normal dense format.'], + ['html', 'Generate HTML instead of the normal tabular output.'], + ['html_details', 'Generate HTML output for source file coverage.'], + ['html_absolute_paths', 'Set the paths in the HTML report to be absolute instead of relative'], + ['branches', 'Tabulate the branch coverage instead of the line coverage.'], + ['sort_uncovered', 'Sort entries by increasing number of uncovered lines.'], + ['sort_percentage', 'Sort entries by decreasing percentage of covered lines.'], + ['gcov_executable', 'Defines the name/path to the gcov executable].'], + ['exclude_unreachable_branches', 'Exclude from coverage branches which are marked to be excluded by LCOV/GCOV markers'], + ['use_gcov_files', 'Use preprocessed gcov files for analysis.'], + ['print_summary', 'Prints a small report to stdout with line & branch percentage coverage'] + ] + end + + def self.author + "dtrenz" + end end end end diff --git a/lib/fastlane/actions/hipchat.rb b/lib/fastlane/actions/hipchat.rb index 206b4cba506..df68fc241f7 100644 --- a/lib/fastlane/actions/hipchat.rb +++ b/lib/fastlane/actions/hipchat.rb @@ -87,6 +87,24 @@ def self.check_response_code(response, channel) raise "Unexpected #{response.code} for `#{channel}'".red end end + + def self.description + "Send a error/success message to HipChat" + end + + def self.available_options + [ + ['', 'Hipchat API Token', 'HIPCHAT_API_TOKEN'], + ['', 'Version of the Hipchat API. Must be 1 or 2', 'HIPCHAT_API_VERSION'], + ['message', 'The message to post on HipChat'], + ['channel', 'The room or @username'], + ['success', 'Is this a success message?'], + ] + end + + def self.author + "jingx23" + end end end end diff --git a/lib/fastlane/actions/hockey.rb b/lib/fastlane/actions/hockey.rb index ea4c3a1792d..7edbf912a6b 100644 --- a/lib/fastlane/actions/hockey.rb +++ b/lib/fastlane/actions/hockey.rb @@ -63,6 +63,32 @@ def self.run(params) raise 'Error when trying to upload ipa to HockeyApp'.red end end + + def self.description + "Upload a new build to HockeyApp" + end + + def self.available_options + [ + ['api_token', 'API Token for Hockey Access'], + ['ipa', 'Path to the ipa file. Optional if you use the `ipa` or `xcodebuild` action'], + ['notes', 'The changelog for this build'], + ['dsym', 'Path to the dsym file. Optional if you use the `ipa` or `xcodebuild` action'], + ['status', 'No description'], + ['notify', 'Notify testers? 1 for yes'], + ] + end + + def output + [ + ['HOCKEY_DOWNLOAD_LINK', 'The newly generated download link for this build'], + ['HOCKEY_BUILD_INFORMATION', 'contains all keys/values from the HockeyApp API, like :title, :bundle_identifier'] + ] + end + + def self.author + "KrauseFx" + end end end end diff --git a/lib/fastlane/actions/increment_build_number.rb b/lib/fastlane/actions/increment_build_number.rb index 6e04b92dc4a..15142abae02 100644 --- a/lib/fastlane/actions/increment_build_number.rb +++ b/lib/fastlane/actions/increment_build_number.rb @@ -55,6 +55,27 @@ def self.run(params) raise ex end end + + def self.description + "Increment the build number of your project" + end + + def self.available_options + [ + ['build_number', 'specify specific build number (optional, omitting it increments by one)'], + ['xcodeproj', 'optional, you must specify the path to your main Xcode project if it is not in the project root directory'] + ] + end + + def self.output + [ + ['BUILD_NUMBER', 'The new build number'] + ] + end + + def self.author + "KrauseFx" + end end end end diff --git a/lib/fastlane/actions/increment_version_number.rb b/lib/fastlane/actions/increment_version_number.rb index 75447c0304e..d6657a13b5d 100644 --- a/lib/fastlane/actions/increment_version_number.rb +++ b/lib/fastlane/actions/increment_version_number.rb @@ -93,6 +93,35 @@ def self.run(params) raise ex end end + + def self.description + "Increment the version number of your project" + end + + def self.details + [ + "This action will increment the version number. ", + "You first have to set up your Xcode project, if you haven't done it already:", + "https://developer.apple.com/library/ios/qa/qa1827/_index.html" + ].join(' ') + end + + def self.available_options + [ + ['build_number', 'specify specific build number (optional, omitting it increments by one)'], + ['xcodeproj', 'optional, you must specify the path to your main Xcode project if it is not in the project root directory'] + ] + end + + def self.output + [ + ['VERSION_NUMBER', 'The new version number'] + ] + end + + def self.author + "serluca" + end end end end \ No newline at end of file diff --git a/lib/fastlane/actions/install_carthage.rb b/lib/fastlane/actions/install_carthage.rb index 0d7dba308f3..79f4c8ce8d5 100644 --- a/lib/fastlane/actions/install_carthage.rb +++ b/lib/fastlane/actions/install_carthage.rb @@ -4,6 +4,14 @@ class CarthageAction < Action def self.run(_params) Actions.sh('carthage bootstrap') end + + def self.description + "Runs `carthage bootstrap` for your project" + end + + def self.author + "bassrock" + end end end end diff --git a/lib/fastlane/actions/ipa.rb b/lib/fastlane/actions/ipa.rb index 260d4322ca8..11bc7aa2124 100644 --- a/lib/fastlane/actions/ipa.rb +++ b/lib/fastlane/actions/ipa.rb @@ -5,19 +5,19 @@ module SharedValues DSYM_OUTPUT_PATH = :DSYM_OUTPUT_PATH end - # -w, --workspace WORKSPACE Workspace (.xcworkspace) file to use to build app (automatically detected in current directory) - # -p, --project PROJECT Project (.xcodeproj) file to use to build app (automatically detected in current directory, overridden by --workspace option, if passed) + # -w, --workspace WORKSPACE Workspace (.xcworkspace) file to use to build app (automatically detected in current directory) + # -p, --project PROJECT Project (.xcodeproj) file to use to build app (automatically detected in current directory, overridden by --workspace option, if passed) # -c, --configuration CONFIGURATION Configuration used to build - # -s, --scheme SCHEME Scheme used to build app - # --xcconfig XCCONFIG use an extra XCCONFIG file to build the app - # --xcargs XCARGS pass additional arguments to xcodebuild when building the app. Be sure to quote multiple args. - # --[no-]clean Clean project before building - # --[no-]archive Archive project after building - # -d, --destination DESTINATION Destination. Defaults to current directory - # -m, --embed PROVISION Sign .ipa file with .mobileprovision - # -i, --identity IDENTITY Identity to be used along with --embed - # --sdk SDK use SDK as the name or path of the base SDK when building the project - # --ipa IPA specify the name of the .ipa file to generate (including file extension) + # -s, --scheme SCHEME Scheme used to build app + # --xcconfig XCCONFIG use an extra XCCONFIG file to build the app + # --xcargs XCARGS pass additional arguments to xcodebuild when building the app. Be sure to quote multiple args. + # --[no-]clean Clean project before building + # --[no-]archive Archive project after building + # -d, --destination DESTINATION Destination. Defaults to current directory + # -m, --embed PROVISION Sign .ipa file with .mobileprovision + # -i, --identity IDENTITY Identity to be used along with --embed + # --sdk SDK use SDK as the name or path of the base SDK when building the project + # --ipa IPA specify the name of the .ipa file to generate (including file extension) ARGS_MAP = { workspace: '-w', @@ -122,6 +122,45 @@ def self.find_dsym_file(dir) # Finds last modified .dSYM.zip in the destination directory Dir[File.join(dir, '*.dSYM.zip')].sort { |a, b| File.mtime(b) <=> File.mtime(a) }.first end + + def self.description + "Easily build and sign your app using shenzhen" + end + + def self.details + [ + "More information on the shenzhen project page: https://github.com/nomad/shenzhen" + ].join(' ') + end + + def self.available_options + [ + ['workspace', 'Workspace (.xcworkspace) file to use to build app (automatically detected in current directory)'], + ['project', 'Project (.xcodeproj) file to use to build app (automatically detected in current directory'], + ['configuration', 'Configuration used to build'], + ['scheme', 'Scheme used to build app'], + ['clean', 'use an extra XCCONFIG file to build the app'], + ['archive', 'pass additional arguments to xcodebuild when building the app. Be sure to quote multiple args.'], + ['destination', 'Clean project before building'], + ['embed', 'Archive project after building'], + ['identity', 'Destination. Defaults to current directory'], + ['sdk', 'Sign .ipa file with .mobileprovision'], + ['ipa', 'Identity to be used along with --embed'], + ['verbose', 'use SDK as the name or path of the base SDK when building the project'], + ['xcargs', 'specify the name of the .ipa file to generate (including file extension)'] + ] + end + + def self.output + [ + ['IPA_OUTPUT_PATH', 'The path to the newly generated ipa file'], + ['DSYM_OUTPUT_PATH', 'The path to the dsym file'] + ] + end + + def self.author + "joshdholtz" + end end end end diff --git a/lib/fastlane/actions/notify.rb b/lib/fastlane/actions/notify.rb index 6ae62f1b413..529b0a4cb39 100644 --- a/lib/fastlane/actions/notify.rb +++ b/lib/fastlane/actions/notify.rb @@ -11,6 +11,10 @@ def self.run(params) def self.description "Shows a Mac OS X notification" end + + def author + "champo" + end end end end diff --git a/lib/fastlane/actions/produce.rb b/lib/fastlane/actions/produce.rb index 3fd7a9f1081..fd431afa8a3 100644 --- a/lib/fastlane/actions/produce.rb +++ b/lib/fastlane/actions/produce.rb @@ -35,6 +35,42 @@ def self.run(params) FastlaneCore::UpdateChecker.show_update_status('produce', Produce::VERSION) end end + + def self.description + "Makes sure the given app identifier is created on the Dev Portal" + end + + def details + [ + 'For more information about produce, visit its GitHub page:', + 'https://github.com/KrauseFx/produce' + ].join(' ') + end + + def self.available_options + [ + ['produce_app_identifier', 'The App Identifier of your app', 'PRODUCE_APP_IDENTIFIER'], + ['produce_app_name', 'The name of your app', 'PRODUCE_APP_NAME'], + ['produce_language', 'The app\'s default language', 'PRODUCE_LANGUAGE'], + ['produce_version', 'The initial version of your app', 'PRODUCE_VERSION'], + ['produce_sku', 'The SKU number of the app if it gets created', 'PRODUCE_SKU'], + ['produce_team_name', 'optional: the name of your team', 'PRODUCE_TEAM_NAME'], + ['produce_team_id', 'optional: the ID of your team', 'PRODUCE_TEAM_ID'], + ['produce_username', 'optional: your Apple ID', 'PRODUCE_USERNAME'], + ['skip_itc', 'Skip the creation on iTunes Connect', 'PRODUCE_SKIP_ITC'], + ['skip_devcenter', 'Skip the creation on the Apple Developer Portal', 'PRODUCE_SKIP_DEVCENTER'] + ] + end + + def self.output + [ + ['PRODUCE_APPLE_ID', 'The Apple ID of the newly created app. You probably need it for `deliver`'] + ] + end + + def self.author + "KrauseFx" + end end end end diff --git a/lib/fastlane/actions/push_to_git_remote.rb b/lib/fastlane/actions/push_to_git_remote.rb index a23895b1159..9cb1c3837b2 100644 --- a/lib/fastlane/actions/push_to_git_remote.rb +++ b/lib/fastlane/actions/push_to_git_remote.rb @@ -28,6 +28,23 @@ def self.run(params) Helper.log.info 'Sucesfully pushed to remote.' end + + def self.description + "Push local changes to the remote branch" + end + + def self.available_options + [ + ['remote', 'The remote to push to. Defaults to `origin`'], + ['branch', 'The local branch to push from. Defaults to the current branch'], + ['branch', 'The remote branch to push to. Defaults to the local branch'], + ['force', 'Force push to remote. Defaults to false'] + ] + end + + def self.author + "lmirosevic" + end end end end diff --git a/lib/fastlane/actions/register_devices.rb b/lib/fastlane/actions/register_devices.rb index c4b4ddf3ef4..df9da7abf90 100644 --- a/lib/fastlane/actions/register_devices.rb +++ b/lib/fastlane/actions/register_devices.rb @@ -58,6 +58,23 @@ def self.run(params) Helper.log.info "Device list up to date, all #{device_objs.count} devices are already registered. Total devices registed: #{existing_devices.count}.".green end end + + def self.description + "Registers new devices to the Apple Dev Portal" + end + + def self.available_options + [ + ['devices', 'A hash of devices, with the name as key and the UDID as value'], + ['device_file', 'Instead, you can proide a path containing all UDIDs'], + ['team_id', 'optional: Your team ID'], + ['username', 'optional: Your Apple ID'] + ] + end + + def self.author + "lmirosevic" + end end end end diff --git a/lib/fastlane/actions/reset_git_repo.rb b/lib/fastlane/actions/reset_git_repo.rb index 5b2fee2d48d..b73340e80c0 100644 --- a/lib/fastlane/actions/reset_git_repo.rb +++ b/lib/fastlane/actions/reset_git_repo.rb @@ -22,6 +22,29 @@ def self.run(params) 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 end end + + def self.description + "Resets git repo to a clean state by discarding uncommited changes" + end + + def self.details + [ + "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.", + "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:", + "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." + ].join(' ') + end + + def self.available_options + [ + ['files', 'Array of files the changes should be discarded from. If not given, all files will be discarded'], + ['force', 'Skip verifying of previously clean state of repo. Only recommended in combination with `files` option'] + ] + end + + def self.author + 'lmirosevic' + end end end end diff --git a/lib/fastlane/actions/resign.rb b/lib/fastlane/actions/resign.rb index 2ebb03ff136..6976c2168bc 100644 --- a/lib/fastlane/actions/resign.rb +++ b/lib/fastlane/actions/resign.rb @@ -24,6 +24,22 @@ def self.run(params) raise 'Failed to re-sign .ipa'.red end end + + def self.description + "Code sign an existing ipa file" + end + + def self.available_options + [ + ['ipa', 'Path to the ipa file to resign. Optional if you use the `ipa` or `xcodebuild` action'], + ['signing_identity', 'Code signing identity to use. e.g. "iPhone Distribution: Luka Mirosevic (0123456789)"'], + ['provisioning_profile', 'Path to your provisioning_profile. Optional if you use `sigh`'] + ] + end + + def self.author + "lmirosevic" + end end end end diff --git a/lib/fastlane/actions/slack.rb b/lib/fastlane/actions/slack.rb index 52c7e4d6b50..b6c66b98af7 100644 --- a/lib/fastlane/actions/slack.rb +++ b/lib/fastlane/actions/slack.rb @@ -1,8 +1,5 @@ module Fastlane module Actions - module SharedValues - end - class SlackAction < Action def self.git_author s = `git log --name-status HEAD^..HEAD` @@ -125,6 +122,24 @@ def self.run(params) Helper.log.info 'Successfully sent Slack notification'.green end end + + def self.description + "Send a success/error message to your Slack group" + end + + def self.available_options + [ + ['message', 'The message that should be displayed on Slack. This supports the standard Slack markup language'], + ['channel', '#channel or @username'], + ['success', 'Success or error?'], + ['payload', 'Add additional information to this post. payload must be a hash containg any key with any value'], + ['default_payloads', 'Remove some of the default payloads. More information about the available payloads GitHub'] + ] + end + + def self.author + "KrauseFx" + end end end end diff --git a/lib/fastlane/actions/team_name.rb b/lib/fastlane/actions/team_name.rb index 65a1a795787..bdfe98412de 100644 --- a/lib/fastlane/actions/team_name.rb +++ b/lib/fastlane/actions/team_name.rb @@ -14,6 +14,14 @@ def self.run(params) ENV[current.to_s] = team end end + + def self.description + "Set a team to use by its name" + end + + def self.author + "KrauseFx" + end end end end diff --git a/lib/fastlane/actions/testmunk.rb b/lib/fastlane/actions/testmunk.rb index d65f0e84456..8706983ac61 100644 --- a/lib/fastlane/actions/testmunk.rb +++ b/lib/fastlane/actions/testmunk.rb @@ -11,9 +11,6 @@ module Fastlane module Actions - module SharedValues - end - class TestmunkAction < Action def self.run(_params) raise "Please pass your Testmunk email address using `ENV['TESTMUNK_EMAIL'] = 'value'`" unless ENV['TESTMUNK_EMAIL'] @@ -36,6 +33,22 @@ def self.run(_params) raise 'Something went wrong while uploading your app to Testmunk'.red end end + + def self.description + "Run tests on real devices using Testmunk" + end + + def self.available_options + [ + ['', 'Your email address', 'TESTMUNK_EMAIL'], + ['', 'Testmunk API Key', 'TESTMUNK_API'], + ['', 'Testmunk App Name', 'TESTMUNK_APP'] + ] + end + + def self.author + "mposchen" + end end end end diff --git a/lib/fastlane/actions/typetalk.rb b/lib/fastlane/actions/typetalk.rb index ff086c889e8..10c106a9a0e 100644 --- a/lib/fastlane/actions/typetalk.rb +++ b/lib/fastlane/actions/typetalk.rb @@ -50,6 +50,24 @@ def self.check_response(response) raise "Could not sent Typetalk notification".red end end + + def self.description + "Post a message to Typetalk" + end + + def self.available_options + [ + ['message', 'The message to post'], + ['note_path', 'Path to a md file'], + ['topicId', ''], + ['success', 'Successful build?'], + ['typetalk_token', 'API token'] + ] + end + + def self.author + "dataich" + end end end end diff --git a/lib/fastlane/actions/update_project_code_signing.rb b/lib/fastlane/actions/update_project_code_signing.rb index 3b32ea5b2b5..c70ff3e4c74 100644 --- a/lib/fastlane/actions/update_project_code_signing.rb +++ b/lib/fastlane/actions/update_project_code_signing.rb @@ -19,6 +19,18 @@ def self.run(params) Helper.log.info("Successfully updated project settings to use UDID '#{udid}'".green) end + + def self.description + "Updated code signing settings from 'Automatic' to a specific profile" + end + + def self.details + "This feature is not yet 100% finished" + end + + def self.author + "KrauseFx" + end end end end diff --git a/lib/fastlane/actions/xcode_select.rb b/lib/fastlane/actions/xcode_select.rb index 03df4d0cfe3..df25c876bd9 100644 --- a/lib/fastlane/actions/xcode_select.rb +++ b/lib/fastlane/actions/xcode_select.rb @@ -25,12 +25,20 @@ def self.run(params) raise "Path to Xcode application required (e.x. \"/Applications/Xcode.app\")".red unless xcode_path.to_s.length > 0 # Verify that a path to a directory was passed in - raise "Nonexistent path provided".red unless Dir.exists? xcode_path + raise "Path '#{xcode_path}' doesn't exist".red unless Dir.exists?(xcode_path) Helper.log.info "Setting Xcode version to #{xcode_path} for all build steps" ENV["DEVELOPER_DIR"] = xcode_path + "/Contents/Developer" end + + def self.description + "Change the xcode-path to use. Useful for beta versions of Xcode" + end + + def self.author + "dtrenz" + end end end end diff --git a/lib/fastlane/actions/xcodebuild.rb b/lib/fastlane/actions/xcodebuild.rb index 71e5c33df24..eb4e5a08ccb 100644 --- a/lib/fastlane/actions/xcodebuild.rb +++ b/lib/fastlane/actions/xcodebuild.rb @@ -117,8 +117,20 @@ def self.run(params) xcpretty_args = [ "--color" ] if testing - # Test report file format - if params[:report_formats] + if params[:reports] + # New report options format + reports = params[:reports].map do |report| + unless report[:screenshots] + "--report #{report[:report]} --output #{report[:output]}" + else + "--report #{report[:report]} --output #{report[:output]} --screenshots" + end + end + + xcpretty_args.push reports.join(" ") + + elsif params[:report_formats] + # Test report file format report_formats = params[:report_formats].map do |format| "--report #{format}" end.sort().join(" ") @@ -187,6 +199,28 @@ def self.detect_workspace return workspace end + + def self.description + "Use the `xcodebuild` command to build and sign your app" + end + + def self.available_options + [ + ['archive', 'Set to true to build archive'], + ['archive_path', 'The path to archive the to. Must contain `.xcarchive`'], + ['workspace', 'The workspace to use'], + ['scheme', 'The scheme to build'], + ['build_settings', 'Hash of additional build information'] + ] + end + + def self.details + "More infomration on GitHub: https://github.com/KrauseFx/fastlane/blob/master/docs/Actions.md#xcodebuild" + end + + def self.author + "dtrenz" + end end class XcarchiveAction < Action @@ -195,6 +229,14 @@ def self.run(params) params_hash[:archive] = true XcodebuildAction.run([params_hash]) end + + def self.description + "Builds the project using `xcodebuild`" + end + + def self.author + "dtrenz" + end end class XcbuildAction < Action @@ -203,6 +245,14 @@ def self.run(params) params_hash[:build] = true XcodebuildAction.run([params_hash]) end + + def self.description + "Builds the project using `xcodebuild`" + end + + def self.author + "dtrenz" + end end class XccleanAction < Action @@ -211,6 +261,14 @@ def self.run(params) params_hash[:clean] = true XcodebuildAction.run([params_hash]) end + + def self.description + "Builds the project using `xcodebuild`" + end + + def self.author + "dtrenz" + end end class XcexportAction < Action @@ -219,6 +277,14 @@ def self.run(params) params_hash[:export_archive] = true XcodebuildAction.run([params_hash]) end + + def self.description + "Builds the project using `xcodebuild`" + end + + def self.author + "dtrenz" + end end class XctestAction < Action @@ -227,6 +293,20 @@ def self.run(params) params_hash[:test] = true XcodebuildAction.run([params_hash]) end + + def self.description + "Runs tests on the given simulator" + end + + def available_options + [ + ['destination', 'The simulator to use, e.g. "name=iPhone 5s,OS=8.1"'] + ] + end + + def self.author + "dtrenz" + end end end end diff --git a/lib/fastlane/actions/xctool.rb b/lib/fastlane/actions/xctool.rb index 8b7f6af5f4c..dce0907b3fb 100644 --- a/lib/fastlane/actions/xctool.rb +++ b/lib/fastlane/actions/xctool.rb @@ -8,6 +8,21 @@ def self.run(params) Actions.sh('xctool ' + params.join(' ')) end + + def self.description + "Run tests using xctool" + end + + def self.details + [ + "It is recommended to store the build configuration in the `.xctool-args` file.", + "More information available on GitHub: https://github.com/KrauseFx/fastlane/blob/master/docs/Actions.md#xctool" + ].join(' ') + end + + def self.author + "KrauseFx" + end end end end diff --git a/lib/fastlane/actions_list.rb b/lib/fastlane/actions_list.rb index 7269d55da66..26a9cda7e16 100644 --- a/lib/fastlane/actions_list.rb +++ b/lib/fastlane/actions_list.rb @@ -17,8 +17,6 @@ def self.print_all current << action.author.green if action.author l = (action.description || '').length - raise "Provided description for #{name} is too long. It is #{l}, must be <= 80".red if l > 80 - raise "Provided description for #{name} shouldn't end with a `.`".red if action.description.strip.end_with?'.' else Helper.log.error "Please update your action file #{name} to be a subclass of `Action` by adding ` < Action` after your class name.".red current << "Please update action file".red @@ -47,7 +45,11 @@ def self.show_details(filter) rows = [] rows << [action.description] if action.description rows << [' '] - rows << ["Created by #{action.author.green}"] if action.description + if action.details + rows << [action.details] + rows << [' '] + end + rows << ["Created by #{action.author.green}"] if action.author puts Terminal::Table.new( title: filter.green, @@ -61,7 +63,7 @@ def self.show_details(filter) if options puts Terminal::Table.new( title: filter.green, - headings: ['Key', 'Description', 'Environment Variable'], + headings: ['Key', 'Description', 'Env Var'], rows: options ) else @@ -69,7 +71,7 @@ def self.show_details(filter) end puts "\n" - output = parse_options(action.output) if action.output + output = parse_options(action.output, false) if action.output if output puts Terminal::Table.new( title: filter.green, @@ -94,18 +96,18 @@ def self.show_details(filter) end - private - # Iterates through all available actions and yields from there - def self.all_actions - all_actions = Fastlane::Actions.constants.select {|c| Class === Fastlane::Actions.const_get(c)} - all_actions.each do |symbol| - action = Fastlane::Actions.const_get(symbol) - name = symbol.to_s.gsub('Action', '').fastlane_underscore - yield action, name - end + # Iterates through all available actions and yields from there + def self.all_actions + all_actions = Fastlane::Actions.constants.select {|c| Class === Fastlane::Actions.const_get(c)} + all_actions.each do |symbol| + action = Fastlane::Actions.const_get(symbol) + name = symbol.to_s.gsub('Action', '').fastlane_underscore + yield action, name end - - def self.parse_options(options) + end + + private + def self.parse_options(options, fill_three = true) rows = [] rows << [options] if options.kind_of?String @@ -117,7 +119,7 @@ def self.parse_options(options) raise "Invalid number of elements in this row: #{current}. Must be 2 or 3".red unless ([2, 3].include?current.count) rows << current rows.last[0] = rows.last.first.yellow # color it yellow :) - rows.last << nil if rows.last.count == 2 # to have a nice border in the table + rows.last << nil if (fill_three and rows.last.count == 2) # to have a nice border in the table end end end diff --git a/lib/fastlane/version.rb b/lib/fastlane/version.rb index d57eba12f8a..9fea638a1d7 100644 --- a/lib/fastlane/version.rb +++ b/lib/fastlane/version.rb @@ -1,3 +1,3 @@ module Fastlane - VERSION = '0.6.1' + VERSION = '0.7.0' end diff --git a/spec/actions_list_spec.rb b/spec/actions_list_spec.rb index f1e84e3b90e..d06fbcffce1 100644 --- a/spec/actions_list_spec.rb +++ b/spec/actions_list_spec.rb @@ -1,8 +1,32 @@ +require 'fastlane/actions_list' + describe Fastlane do describe "Action List" do it "doesn't throw an exception" do - require 'fastlane/actions_list' Fastlane::ActionsList.run nil end + + describe "Actions provide a complete documenation" do + Fastlane::ActionsList.all_actions do |action, name| + it "Valid return values for fastlane action #{name}" do + expect(action.description.length).to be <= 80, "Provided description for '#{name}'-action is too long" + expect(action.description.length).to be > 5, "Provided description for '#{name}'-action is too short" + expect(action.description.strip.end_with?'.').to eq(false), "The description of '#{name}' shouldn't end with a `.`" + expect(action.author.length).to be > 1, "Action '#{name}' must have an author" + + if action.available_options + expect(action.available_options).to be_instance_of(Array), "'available_options' for action '#{name}' must be an array" + end + + if action.output + expect(action.output).to be_instance_of(Array), "'output' for action '#{name}' must be an array" + end + + if action.details + expect(action.details).to be_instance_of(String), "'details' for action '#{name}' must be a String" + end + end + end + end end end diff --git a/spec/actions_specs/xcode_select_spec.rb b/spec/actions_specs/xcode_select_spec.rb index 366f1b18231..9606ec2943f 100644 --- a/spec/actions_specs/xcode_select_spec.rb +++ b/spec/actions_specs/xcode_select_spec.rb @@ -26,7 +26,7 @@ Fastlane::FastFile.new.parse("lane :test do xcode_select \"#{invalid_path}\" end").runner.execute(:test) - }.to raise_error("Nonexistent path provided".red) + }.to raise_error("Path '/path/to/nonexistent/dir' doesn't exist".red) end it "sets the DEVELOPER_DIR environment variable" do diff --git a/spec/actions_specs/xcodebuild_spec.rb b/spec/actions_specs/xcodebuild_spec.rb index e9aeb1a6fad..ab7f9235a17 100644 --- a/spec/actions_specs/xcodebuild_spec.rb +++ b/spec/actions_specs/xcodebuild_spec.rb @@ -374,6 +374,41 @@ ) end + it "should support multiple reports " do + result = Fastlane::FastFile.new.parse("lane :test do + xctest( + destination: 'name=iPhone 5s,OS=8.1', + scheme: 'MyApp', + workspace: 'MyApp.xcworkspace', + reports: [{ + report: 'html', + output: './build-dir/test-report.html', + screenshots: 1 + }, + { + report: 'junit', + output: './build-dir/test-report.xml' + }], + ) + end").runner.execute(:test) + + expect(result).to eq( + "set -o pipefail && " \ + + "xcodebuild " \ + + "-destination \"name=iPhone 5s,OS=8.1\" " \ + + "-scheme \"MyApp\" " \ + + "-workspace \"MyApp.xcworkspace\" " \ + + "test " \ + + "| xcpretty --color " \ + + "--report html " \ + + "--output ./build-dir/test-report.html " \ + + "--screenshots " \ + + "--report junit " \ + + "--output ./build-dir/test-report.xml " \ + + "--test" + ) + end + it "should detect and use the workspace, when a workspace is present" do allow(Dir).to receive(:glob).with("*.xcworkspace").and_return([ "MyApp.xcworkspace" ])