diff --git a/bin/deliver b/bin/deliver index 6fb3a94..5f8252f 100755 --- a/bin/deliver +++ b/bin/deliver @@ -28,7 +28,21 @@ class FastlaneApplication c.syntax = 'deliver' c.description = 'Run a deploy process using the Deliverfile in the current folder' c.action do |args, options| - path = (Deliver::Helper.fastlane_enabled?? './fastlane' : '.') + run_deliver(options) + end + end + + command :upload_metadata do |c| + c.syntax = 'deliver upload_metadata' + c.description = "Uploads new app metadata only. No binary will be uploaded" + c.action do |args, options| + ENV["DELIVER_SKIP_BINARY"] = "1" + run_deliver(options) + end + end + + def run_deliver(options) + path = (Deliver::Helper.fastlane_enabled?? './fastlane' : '.') Dir.chdir(path) do # switch the context if File.exists?(deliver_path) # Everything looks alright, use the given Deliverfile @@ -41,7 +55,6 @@ class FastlaneApplication end end end - end end command :init do |c| diff --git a/lib/deliver/deliver_process.rb b/lib/deliver/deliver_process.rb index 6a097c0..8d27411 100644 --- a/lib/deliver/deliver_process.rb +++ b/lib/deliver/deliver_process.rb @@ -26,33 +26,36 @@ def initialize(deploy_information = nil) def run begin - run_unit_tests - fetch_information_from_ipa_file - - verify_ipa_file - - Helper.log.info("Got all information needed to deploy a new update ('#{@app_version}') for app '#{@app_identifier}'") + unless metadata_only? + run_unit_tests + fetch_app_key_information + fetch_information_from_ipa_file + @app_version ||= get_latest_version + verify_ipa_file + else + fetch_app_key_information + @app_identifier ||= ask("App Identifier (e.g. com.krausefx.app): ") + @app_version ||= get_latest_version || ask("Which version number should be updated? ") + end create_app - verify_app_on_itunesconnect - - unless is_beta_build? - # App Metdata will not be updated for beta builds - load_metadata_from_config_json_folder # the json file generated from the quick start # deprecated - load_metadata_folder # this is the new way of defining app metadata - set_app_metadata - set_screenshots + Helper.log.info("Got all information needed to deploy a new update ('#{@app_version}') for app '#{@app_identifier}'") - verify_pdf_file + verify_app_on_itunesconnect unless metadata_only? - additional_itc_information # e.g. copyright, age rating + if ready_for_sale? + raise "Cannot update metadata of apps 'Ready for Sale'. You can dupe: http://www.openradar.appspot.com/18263306".red + end - trigger_metadata_upload + if is_beta_build? + Helper.log.info "Beta builds don't upload new metadata to iTunesConnet".yellow + else + upload_metadata end # Always upload a new ipa (except if none was given) - trigger_ipa_upload + trigger_ipa_upload unless metadata_only? call_success_block rescue => ex @@ -60,6 +63,53 @@ def run end end + def upload_metadata + load_metadata_from_config_json_folder # the json file generated from the quick start # deprecated + load_metadata_folder # this is the new way of defining app metadata + set_app_metadata + set_screenshots + + verify_pdf_file + + additional_itc_information # e.g. copyright, age rating + + trigger_metadata_upload + end + + ##################################################### + # @!group What kind of release + ##################################################### + + # Deployment = Submission of the binary + def skip_deployment? + @deploy_information[Deliverer::ValKey::SKIP_DEPLOY] + end + + # Release = App Store and not TestFlight + def is_release_build? + is_beta_build? == false + end + + # TestFlight Buil + def is_beta_build? + @deploy_information[Deliverer::ValKey::IS_BETA_IPA] + end + + # Only upload metadata and no binary + def metadata_only? + ENV["DELIVER_SKIP_BINARY"] + end + + # Is the app already ready for sale? + # if so, we can't update the app metadata: http://www.openradar.appspot.com/18263306 + def ready_for_sale? + return false if Helper.is_test? + return @ready if @checked_for_ready + + @checked_for_ready = true + @ready = (app.get_app_status == App::AppStatus::READY_FOR_SALE) + end + ##################################################### # @!group All the methods ##################################################### @@ -75,10 +125,24 @@ def run_unit_tests end end - def fetch_information_from_ipa_file + # Tries to fetch app version and app identifier from Deliverfile + def fetch_app_key_information @app_version = @deploy_information[Deliverer::ValKey::APP_VERSION] @app_identifier = @deploy_information[Deliverer::ValKey::APP_IDENTIFIER] + fetch_app_identifier_from_app_file + end + + # returns the latest app version from iTunes Connect + def get_latest_version + return nil if Helper.is_test? + data = itc.get_app_information(Deliver::App.new(app_identifier: @app_identifier)) + return (data['version']['value'] rescue nil) + rescue + return nil + end + + def fetch_information_from_ipa_file used_ipa_file = ENV["IPA_OUTPUT_PATH"]# if (ENV["IPA_OUTPUT_PATH"] and File.exists?(ENV["IPA_OUTPUT_PATH"])) if is_release_build? @@ -125,7 +189,7 @@ def fetch_information_from_ipa_file end def fetch_app_identifier_from_app_file - @app_identifier = (CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier) rescue nil) + @app_identifier ||= (CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier) rescue nil) end def verify_ipa_file @@ -216,17 +280,22 @@ def set_app_metadata @app.metadata.update_price_tier(@deploy_information[Deliverer::ValKey::PRICE_TIER]) if @deploy_information[Deliverer::ValKey::PRICE_TIER] end + def screenshots_path + return @screens_path if @screens_path - def set_screenshots - screens_path = @deploy_information[Deliverer::ValKey::SCREENSHOTS_PATH] - + @screens_path = @deploy_information[Deliverer::ValKey::SCREENSHOTS_PATH] if (ENV["DELIVER_SCREENSHOTS_PATH"] || '').length > 0 - Helper.log.warn "Overwriting screenshots path from config (#{screens_path}) with (#{ENV["DELIVER_SCREENSHOTS_PATH"]})".yellow - screens_path = ENV["DELIVER_SCREENSHOTS_PATH"] + Helper.log.warn "Overwriting screenshots path from config (#{@screens_path}) with (#{ENV["DELIVER_SCREENSHOTS_PATH"]})".yellow + @screens_path = ENV["DELIVER_SCREENSHOTS_PATH"] end - screens_path ||= "./screenshots/" # default value - + @screens_path ||= "./screenshots/" # default value + + return @screens_path + end + + def set_screenshots + screens_path = screenshots_path if screens_path # Not using Snapfile. Not a good user. if not @app.metadata.set_all_screenshots_from_path(screens_path, use_framed_screenshots?) @@ -249,7 +318,7 @@ def set_screenshots # This will only be true if there is a Framefile, as this makes the screenshots valid # since the resolution is only correct when using a background + title using frameit 2.0 def use_framed_screenshots? - return Dir["../**/Framefile.json"].count > 0 + return Dir[screenshots_path + "**/Framefile.json"].count > 0 end def verify_pdf_file @@ -283,9 +352,12 @@ def trigger_metadata_upload raise "Error uploading app metadata".red unless result == true end + def itc + @itc ||= ItunesConnect.new + end + def additional_itc_information # e.g. rating or copyright - itc = ItunesConnect.new itc.set_copyright!(@app, @deploy_information[Deliverer::ValKey::COPYRIGHT]) if @deploy_information[Deliverer::ValKey::COPYRIGHT] itc.set_app_review_information!(@app, @deploy_information[Deliverer::ValKey::APP_REVIEW_INFORMATION]) if @deploy_information[Deliverer::ValKey::APP_REVIEW_INFORMATION] itc.set_release_after_approval!(@app, @deploy_information[Deliverer::ValKey::AUTOMATIC_RELEASE]) if @deploy_information[Deliverer::ValKey::AUTOMATIC_RELEASE] != nil @@ -369,17 +441,5 @@ def verify_app_version(app_version) end return app_version end - - def skip_deployment? - @deploy_information[Deliverer::ValKey::SKIP_DEPLOY] - end - - def is_release_build? - is_beta_build? == false - end - - def is_beta_build? - @deploy_information[Deliverer::ValKey::IS_BETA_IPA] - end end end diff --git a/lib/deliver/itunes_connect/itunes_connect.rb b/lib/deliver/itunes_connect/itunes_connect.rb index 9406224..9932261 100644 --- a/lib/deliver/itunes_connect/itunes_connect.rb +++ b/lib/deliver/itunes_connect/itunes_connect.rb @@ -8,4 +8,5 @@ require 'deliver/itunes_connect/itunes_connect_apple_watch_app_icon' require 'deliver/itunes_connect/itunes_connect_app_rating' require 'deliver/itunes_connect/itunes_connect_additional' -require 'deliver/itunes_connect/itunes_connect_screenshot_fetcher' \ No newline at end of file +require 'deliver/itunes_connect/itunes_connect_screenshot_fetcher' +require 'deliver/itunes_connect/itunes_connect_information' \ No newline at end of file diff --git a/lib/deliver/itunes_connect/itunes_connect_information.rb b/lib/deliver/itunes_connect/itunes_connect_information.rb new file mode 100644 index 0000000..6e8bf00 --- /dev/null +++ b/lib/deliver/itunes_connect/itunes_connect_information.rb @@ -0,0 +1,34 @@ +require 'open-uri' + +module Deliver + # For all the information reading (e.g. version number) + class ItunesConnect < FastlaneCore::ItunesConnect + ALL_INFORMATION_URL = "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/apps/version/" + + # This method will download information for a given app + # @param app (Deliver::App) the app you want this information from + # @raise [ItunesConnectGeneralError] General error while executing + # this action + # @raise [ItunesConnectLoginError] Login data is wrong + def get_app_information(app) + begin + verify_app(app) + + url = ALL_INFORMATION_URL + app.apple_id.to_s + + # Turn off/on the async mode of jQuery + evaluate_script("jQuery.ajaxSetup({async:false});") + response = evaluate_script("$.get('#{url}').responseText") + evaluate_script("jQuery.ajaxSetup({async:true});") + + raise "Could not fetch data for app" unless response + + data = JSON.parse(response) + + return data['data'] + rescue Exception => ex + error_occured(ex) + end + end + end +end \ No newline at end of file diff --git a/lib/deliver/itunes_connect/itunes_connect_screenshot_fetcher.rb b/lib/deliver/itunes_connect/itunes_connect_screenshot_fetcher.rb index 9cc2545..b2f562b 100644 --- a/lib/deliver/itunes_connect/itunes_connect_screenshot_fetcher.rb +++ b/lib/deliver/itunes_connect/itunes_connect_screenshot_fetcher.rb @@ -3,8 +3,6 @@ module Deliver # For all the information reading (e.g. version number) class ItunesConnect < FastlaneCore::ItunesConnect - ALL_INFORMATION_URL = "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/apps/version/" - # This method will download all existing app screenshots # @param app (Deliver::App) the app you want this information from # @param folder_path (String) the path to store the screenshots in