diff --git a/fastlane/Fastfile b/fastlane/Fastfile index cb64744..fe3fb55 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -60,20 +60,44 @@ platform :ios do end # The shipped version lives in the Info.plist, not in MARKETING_VERSION. + # Absolute path: the lane's working directory is not guaranteed to be the repo root. def shipped_app_version - `/usr/bin/plutil -extract CFBundleShortVersionString raw MealMood/Resources/Info.plist`.strip + plist = File.expand_path("../MealMood/Resources/Info.plist", __dir__) + value = `/usr/bin/plutil -extract CFBundleShortVersionString raw "#{plist}"`.strip + UI.user_error!("Could not read the app version from #{plist}") if value.empty? + value end - desc "Show the App Store state of each version (review status, release type)" - lane :status do + # asc_api_key returns fastlane's option hash, not a Spaceship token. + def connect_api_app require 'spaceship' - # asc_api_key returns fastlane's option hash, not a Spaceship token. Spaceship::ConnectAPI.token = Spaceship::ConnectAPI::Token.create( key_id: `pass show appstore/api-key-id`.strip, issuer_id: `pass show appstore/issuer-id`.strip, key: `pass show appstore/api-key-p8`.strip ) - app = Spaceship::ConnectAPI::App.find("com.alexandrevazquez.mealmood") + Spaceship::ConnectAPI::App.find("com.alexandrevazquez.mealmood") + end + + # `deliver` does not create the App Store version record — it fails with + # "could not find an editable version for 'IOS'" when the previous version is + # already READY_FOR_SALE and nothing is open for editing. + def ensure_editable_version(version) + app = connect_api_app + editable = app.get_edit_app_store_version(platform: "IOS") + + if editable && editable.version_string != version + # ensure_version! would silently renumber it — say so before it happens. + UI.important("App Store Connect had #{editable.version_string} open for editing; renaming it to #{version}") + end + + created = app.ensure_version!(version, platform: "IOS") + UI.success(created ? "App Store version #{version} ready" : "App Store version #{version} already editable") + end + + desc "Show the App Store state of each version (review status, release type)" + lane :status do + app = connect_api_app app.get_app_store_versions(includes: "build").each do |v| UI.message("#{v.version_string} — #{v.app_store_state} — release: #{v.release_type} — build: #{v.build&.version}") end @@ -84,9 +108,11 @@ platform :ios do desc "Submit an already-uploaded build for App Store review (automatic release)" lane :submit do |options| UI.user_error!("pass build:") unless options[:build] + version = options[:version] || shipped_app_version + ensure_editable_version(version) upload_to_app_store( api_key: asc_api_key, - app_version: options[:version] || shipped_app_version, + app_version: version, build_number: options[:build], skip_binary_upload: true, skip_metadata: false,