diff --git a/deliver/README.md b/deliver/README.md index e8e3b1341ba..a1c7a30804e 100644 --- a/deliver/README.md +++ b/deliver/README.md @@ -62,6 +62,7 @@ Get in contact with the developer on Twitter: [@FastlaneTools](https://twitter.c - Easily implement a real Continuous Deployment process using [fastlane](https://fastlane.tools) - Store the configuration in git to easily deploy from **any** Mac, including your Continuous Integration server - Get a HTML preview of the fetched metadata before uploading the app metadata and screenshots to iTC +- Automatically uses [precheck](https://github.com/fastlane/fastlane/tree/master/precheck) to ensure your app has the highest chances of passing app review the first time To upload builds to TestFlight check out [pilot](https://github.com/fastlane/fastlane/tree/master/pilot). diff --git a/deliver/lib/deliver/options.rb b/deliver/lib/deliver/options.rb index f9bf54aa752..75321eddd39 100644 --- a/deliver/lib/deliver/options.rb +++ b/deliver/lib/deliver/options.rb @@ -181,10 +181,10 @@ def self.available_options description: "Clear all previously uploaded screenshots before uploading the new ones", is_string: false, default_value: false), - FastlaneCore::ConfigItem.new(key: :only_submit_on_precheck_success, + FastlaneCore::ConfigItem.new(key: :run_precheck_before_submit, short_option: "-x", - env_name: "DELIVER_ONLY_SUBMIT_ON_PRECHECK_SUCCESS", - description: "Only submit for review once precheck has passed", + env_name: "DELIVER_RUN_PRECHECK_BEFORE_SUBMIT", + description: "Run precheck before submitting to app review", is_string: false, default_value: true), FastlaneCore::ConfigItem.new(key: :precheck_default_rule_level, diff --git a/deliver/lib/deliver/runner.rb b/deliver/lib/deliver/runner.rb index e23bf428a9e..3fba83ed8cb 100644 --- a/deliver/lib/deliver/runner.rb +++ b/deliver/lib/deliver/runner.rb @@ -12,6 +12,7 @@ def initialize(options, skip_auto_detection = {}) end def login + UI.message("Running precheck before submitting to review, if you'd like to disable this check you can set run_precheck_before_submit to false") unless options[:run_precheck_before_submit] == false UI.message("Login to iTunes Connect (#{options[:username]})") Spaceship::Tunes.login(options[:username]) Spaceship::Tunes.select_team @@ -36,7 +37,7 @@ def run # Make sure we pass precheck before uploading def precheck_app - return true unless options[:only_submit_on_precheck_success] + return true unless options[:run_precheck_before_submit] if options[:submit_for_review] UI.message("Making sure we pass precheck ๐Ÿ‘ฎโ€โ™€๏ธ ๐Ÿ‘ฎ before we submit ๐Ÿ›ซ") diff --git a/fastlane/lib/fastlane/actions/precheck.rb b/fastlane/lib/fastlane/actions/precheck.rb index 39ffa516833..465434f6948 100644 --- a/fastlane/lib/fastlane/actions/precheck.rb +++ b/fastlane/lib/fastlane/actions/precheck.rb @@ -38,7 +38,7 @@ def self.is_supported?(platform) def self.example_code [ 'precheck( - apple_things(level: :skip), # Set to skip to not run the `apple_things` rule + negative_apple_sentiment(level: :skip), # Set to skip to not run the `negative_apple_sentiment` rule curse_words(level: :warn) # Set to warn to only warn on curse word check failures )' ] diff --git a/precheck/README.md b/precheck/README.md index 0d59ef40f25..3c2fadc6d9f 100644 --- a/precheck/README.md +++ b/precheck/README.md @@ -34,12 +34,12 @@ Precheck [![Twitter: @FastlaneTools](https://img.shields.io/badge/contact-@FastlaneTools-blue.svg?style=flat)](https://twitter.com/FastlaneTools) [![License](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://github.com/fastlane/fastlane/blob/master/LICENSE) -###### Pass App Store precheck, the first time +###### Check your app using a community driven set of App Store review rules to avoid being rejected Apple rejects builds for many avoidable metadata issues like including swear words ๐Ÿ˜ฎ, other companiesโ€™ trademarks, or even mentioning an iOS bug ๐Ÿ›. _fastlane precheck_ takes a lot of the guess work out by scanning your appโ€™s details in iTunes Connect for avoidable problems. fastlane precheck helps you get your app through app review without rejections so you can ship faster ๐Ÿš€ -Get in contact with the developer on Twitter: [@FastlaneTools](https://twitter.com/FastlaneTools) +Get in contact with the developers on Twitter: [@FastlaneTools](https://twitter.com/FastlaneTools) ------- @@ -59,16 +59,17 @@ Get in contact with the developer on Twitter: [@FastlaneTools](https://twitter.c # Features -- Many scanning rules: - - ๏ฃฟ product bug ๐Ÿ› mentions - - swear word checker ๐Ÿ™…โ€โ™‚๏ธ - - mentioning other platforms ๐Ÿค– - - url reachability checker ๐Ÿ˜ต - - placeholder/test words/mentioning future features ๐Ÿ“ - - Copyright date checking - - customizable word list checking ๐Ÿ™ˆ -- You can use our pre-selected list of what we would use, or you can customize which rules to check for, so you run the rules you care most about. -- Customizable: you can decide if you want to warn ๐Ÿ“ข about potential problems and continue or have fastlane show an error ๐Ÿ™… and stop after all scans are done. + +| | precheck Features | +|----------|-----------------| +|๐Ÿ›| ๏ฃฟ product bug mentions| +|๐Ÿ™…โ€โ™‚๏ธ|Swear word checker| +|๐Ÿค–|Mentioning other platforms| +|๐Ÿ˜ต|URL reachability checker| +|๐Ÿ“|Placeholder/test words/mentioning future features| +|๐Ÿ“…|Copyright date checking| +|๐Ÿ™ˆ|Customizable word list checking| +|๐Ÿ“ข|You can decide if you want to warn about potential problems and continue or have _fastlane_ show an error and stop after all scans are done.| ##### [Do you like fastlane? Be the first to know about updates and new fastlane tools](https://tinyletter.com/fastlane-tools) @@ -77,13 +78,15 @@ Get in contact with the developer on Twitter: [@FastlaneTools](https://twitter.c sudo gem install fastlane # Usage -Run fastlane precheck to check the app metadata from iTunes Connect +Run _fastlane precheck_ to check the app metadata from iTunes Connect fastlane precheck To get a list of available options run fastlane precheck --help + + # Example @@ -92,15 +95,23 @@ Since you might want to manually trigger _precheck_ but don't want to specify al Run `fastlane precheck init` to create a new configuration file. Example: ```ruby -apple_things(level: :skip) # indicates that your metadata will not be checked by this rule -curse_words(level: :warn) # when triggered, this rule will warn you of a potential problem -unreachable_urls(level: :error) # show error and prevent any further commands from running after fastlane precheck finishes -custom_text(data: ["fabric"], level: :warn) # pass in whatever words you want to check for +# indicates that your metadata will not be checked by this rule +negative_apple_sentiment(level: :skip) + +# when triggered, this rule will warn you of a potential problem +curse_words(level: :warn) + +# show error and prevent any further commands from running after fastlane precheck finishes +unreachable_urls(level: :error) + +# pass in whatever words you want to check for +custom_text(data: ["chrome", "webos"], + level: :warn) ``` -### Use with [`fastlane`](https://github.com/fastlane/fastlane/tree/master/fastlane) +### Use with [_fastlane_](https://github.com/fastlane/fastlane/tree/master/fastlane) -_precheck_ is totally integrated with [`deliver`](https://github.com/fastlane/fastlane/tree/master/deliver) another [`fastlane`](https://github.com/fastlane/fastlane/tree/master/fastlane) tool. +_precheck_ is fully integrated with [_deliver_](https://github.com/fastlane/fastlane/tree/master/deliver) another [_fastlane_](https://github.com/fastlane/fastlane/tree/master/fastlane) tool. Update your `Fastfile` to contain the following code: @@ -108,7 +119,8 @@ Update your `Fastfile` to contain the following code: lane :production do ... # by default deliver will call precheck and warn you of any problems - # if you want precheck to halt submitting to app review, you can pass precheck_default_rule_level: :error + # if you want precheck to halt submitting to app review, you can pass + # precheck_default_rule_level: :error deliver(precheck_default_rule_level: :error) ... end @@ -122,7 +134,7 @@ end # How does it work? -`precheck` will access the `iTunes Connect` to download your app's metadata. It uses [spaceship](https://spaceship.airforce) to communicate with Apple's web services. +`precheck` will access `iTunes Connect` to download your app's metadata. It uses [spaceship](https://spaceship.airforce) to communicate with Apple's web services. # Tips diff --git a/precheck/assets/precheck.gif b/precheck/assets/precheck.gif index f46bdaec02e..5a3b2057739 100644 Binary files a/precheck/assets/precheck.gif and b/precheck/assets/precheck.gif differ diff --git a/precheck/assets/precheckScreenshot.png b/precheck/assets/precheckScreenshot.png deleted file mode 100644 index af5acddf06d..00000000000 Binary files a/precheck/assets/precheckScreenshot.png and /dev/null differ diff --git a/precheck/lib/assets/PrecheckfileTemplate b/precheck/lib/assets/PrecheckfileTemplate index b100910f3ad..0b574a739c0 100644 --- a/precheck/lib/assets/PrecheckfileTemplate +++ b/precheck/lib/assets/PrecheckfileTemplate @@ -17,7 +17,7 @@ # when triggered, this rule will cause an error to be displayed and it will prevent any further fastlane commands from running after precheck finishes # Examples: -# apple_things(level: :skip) +# negative_apple_sentiment(level: :skip) # curse_words(level: :warn) # future_functionality(level: :error) # other_platforms(level: :error) diff --git a/precheck/lib/precheck/item_to_check.rb b/precheck/lib/precheck/item_to_check.rb index d10e0d20745..faf1ec65858 100644 --- a/precheck/lib/precheck/item_to_check.rb +++ b/precheck/lib/precheck/item_to_check.rb @@ -5,10 +5,12 @@ module Precheck class ItemToCheck attr_accessor :item_name attr_accessor :friendly_name + attr_accessor :is_optional - def initialize(item_name, friendly_name) + def initialize(item_name, friendly_name, is_optional = false) @item_name = item_name @friendly_name = friendly_name + @is_optional = is_optional end def item_data @@ -29,9 +31,9 @@ def to_s class TextItemToCheck < ItemToCheck attr_accessor :text - def initialize(text, item_name, friendly_name) + def initialize(text, item_name, friendly_name, is_optional = false) @text = text - super(item_name, friendly_name) + super(item_name, friendly_name, is_optional) end def item_data @@ -44,9 +46,9 @@ def item_data class URLItemToCheck < ItemToCheck attr_accessor :url - def initialize(url, item_name, friendly_name) + def initialize(url, item_name, friendly_name, is_optional = false) @url = url - super(item_name, friendly_name) + super(item_name, friendly_name, is_optional) end def item_data diff --git a/precheck/lib/precheck/options.rb b/precheck/lib/precheck/options.rb index 081d88c865d..1fe0bcb44d0 100644 --- a/precheck/lib/precheck/options.rb +++ b/precheck/lib/precheck/options.rb @@ -6,7 +6,7 @@ module Precheck class Options def self.rules [ - AppleThingsRule, + NegativeAppleSentimentRule, PlaceholderWordsRule, OtherPlatformsRule, FutureFunctionalityRule, diff --git a/precheck/lib/precheck/rule.rb b/precheck/lib/precheck/rule.rb index 2e347438048..71aa116730f 100644 --- a/precheck/lib/precheck/rule.rb +++ b/precheck/lib/precheck/rule.rb @@ -140,6 +140,12 @@ def item_field_supported?(item_name: nil) end def perform_check(item: nil) + if item.item_data.to_s == "" && item.is_optional + # item is optional, and empty, so that's totally fine + check_result = RuleReturn.new(validation_state: Precheck::VALIDATION_STATES[:passed]) + return RuleCheckResult.new(item, check_result, self) + end + check_result = self.rule_block.call(item.item_data) return RuleCheckResult.new(item, check_result, self) end diff --git a/precheck/lib/precheck/rule_processor.rb b/precheck/lib/precheck/rule_processor.rb index 170c572fd05..a6d662544cf 100644 --- a/precheck/lib/precheck/rule_processor.rb +++ b/precheck/lib/precheck/rule_processor.rb @@ -119,18 +119,20 @@ def self.generate_url_items_to_check(app: nil, app_version: nil) friendly_name_postfix: "support URL") items += collect_urls_from_hash(hash: app_version.marketing_url, item_name: :marketing_url, - friendly_name_postfix: "marketing URL") + friendly_name_postfix: "marketing URL", + is_optional: true) items += collect_urls_from_hash(hash: app.details.privacy_url, item_name: :privacy_url, - friendly_name_postfix: "privacy URL") + friendly_name_postfix: "privacy URL", + is_optional: true) return items end - def self.collect_urls_from_hash(hash: nil, item_name: nil, friendly_name_postfix: nil) + def self.collect_urls_from_hash(hash: nil, item_name: nil, friendly_name_postfix: nil, is_optional: false) items = [] hash.each do |key, value| - items << URLItemToCheck.new(value, item_name, "#{friendly_name_postfix}: (#{key})") + items << URLItemToCheck.new(value, item_name, "#{friendly_name_postfix}: (#{key})", is_optional) end return items end @@ -167,15 +169,16 @@ def self.generate_text_items_to_check(app: nil, app_version: nil) items += collect_text_items_from_language_item(hash: app.details.subtitle, item_name: :app_subtitle, - friendly_name_postfix: "app name subtitle") + friendly_name_postfix: "app name subtitle", + is_optional: true) return items end # # a few attributes are LanguageItem this method creates a TextItemToCheck for each pair - def self.collect_text_items_from_language_item(hash: nil, item_name: nil, friendly_name_postfix: nil) + def self.collect_text_items_from_language_item(hash: nil, item_name: nil, friendly_name_postfix: nil, is_optional: false) items = [] hash.each do |key, value| - items << TextItemToCheck.new(value, item_name, "#{friendly_name_postfix}: (#{key})") + items << TextItemToCheck.new(value, item_name, "#{friendly_name_postfix}: (#{key})", is_optional) end return items end diff --git a/precheck/lib/precheck/rules/apple_things_rule.rb b/precheck/lib/precheck/rules/negative_apple_sentiment_rule.rb similarity index 82% rename from precheck/lib/precheck/rules/apple_things_rule.rb rename to precheck/lib/precheck/rules/negative_apple_sentiment_rule.rb index f62d3a0d80e..bd6c9af9e45 100644 --- a/precheck/lib/precheck/rules/apple_things_rule.rb +++ b/precheck/lib/precheck/rules/negative_apple_sentiment_rule.rb @@ -2,13 +2,13 @@ require 'precheck/rules/abstract_text_match_rule' module Precheck - class AppleThingsRule < AbstractTextMatchRule + class NegativeAppleSentimentRule < AbstractTextMatchRule def self.key - :apple_things + :negative_apple_sentiment end def self.env_name - "RULE_APPLE_THINGS" + "RULE_NEGATIVE_APPLE_SENTIMENT" end def self.friendly_name