default_platform(:ios) APP_IDENTIFIER = "sh.paseo" platform :ios do desc "Submit the latest TestFlight build to App Store Review" lane :submit_review do api_key = app_store_connect_api_key( key_id: ENV.fetch("ASC_KEY_ID"), issuer_id: ENV.fetch("ASC_ISSUER_ID"), key_filepath: ENV.fetch("ASC_KEY_P8"), ) build_number = latest_testflight_build_number( api_key: api_key, app_identifier: APP_IDENTIFIER, ) require "spaceship" Spaceship::ConnectAPI.token = Spaceship::ConnectAPI::Token.create( key_id: ENV.fetch("ASC_KEY_ID"), issuer_id: ENV.fetch("ASC_ISSUER_ID"), filepath: ENV.fetch("ASC_KEY_P8"), ) app = Spaceship::ConnectAPI::App.find(APP_IDENTIFIER) UI.user_error!("Could not find app #{APP_IDENTIFIER} on App Store Connect") if app.nil? valid_build = nil deadline = Time.now + (30 * 60) loop do builds = Spaceship::ConnectAPI::Build.all( app_id: app.id, build_number: build_number.to_s, ) build = builds.find { |b| b.pre_release_version&.platform == "IOS" } state = build&.processing_state UI.message("Build #{build_number} processing state: #{state || 'unknown'}") if state == "VALID" valid_build = build break end if state == "INVALID" || state == "FAILED" UI.user_error!("Build #{build_number} failed App Store processing (state: #{state}).") end if Time.now > deadline UI.user_error!("Timed out waiting for build #{build_number} to finish processing on App Store Connect.") end sleep(30) end app_version = valid_build.pre_release_version.version UI.message("Submitting build #{build_number} as App Store version #{app_version} for review") # Ensure an editable App Store version exists for this marketing version. # deliver requires a "Prepare for Submission" version on App Store Connect # and won't auto-create one when skip_metadata + skip_screenshots are set. app.ensure_version!(app_version, platform: Spaceship::ConnectAPI::Platform::IOS) # Apple requires a non-empty "What's New" on every new App Store version # before it can be submitted for review. With skip_metadata: true, deliver # never sets this, so we populate it directly per-locale. edit_version = app.get_edit_app_store_version(platform: Spaceship::ConnectAPI::Platform::IOS) release_notes = "Bug fixes and improvements." edit_version.get_app_store_version_localizations.each do |localization| if localization.whats_new.to_s.strip.empty? UI.message("Setting whatsNew on #{localization.locale}") localization.update(attributes: { whatsNew: release_notes }) end end deliver( api_key: api_key, app_identifier: APP_IDENTIFIER, app_version: app_version, build_number: build_number.to_s, submit_for_review: true, automatic_release: true, force: true, skip_binary_upload: true, skip_screenshots: true, skip_metadata: true, precheck_include_in_app_purchases: false, submission_information: { add_id_info_uses_idfa: false, export_compliance_uses_encryption: false, }, ) end end