From a6dcb5605cfd3af1b07fee5f0f05c9a8949b8428 Mon Sep 17 00:00:00 2001 From: alexandrev-tibco Date: Thu, 13 Aug 2026 14:36:36 +0200 Subject: [PATCH] fastlane: submit crea la version en App Store Connect si no existe El envio de la 2.0.2 fallo con "could not find an editable version for 'IOS'": deliver no crea el registro de version, y con la 2.0.1 ya en READY_FOR_SALE no habia nada editable. Con la 2.0.1 no se noto porque la version ya existia. ensure_editable_version usa app.ensure_version! de spaceship y avisa antes de renumerar un borrador ajeno. Login de Connect API extraido a connect_api_app, que ya compartia status. Ademas shipped_app_version leia un path relativo y el directorio de trabajo de la lane no es la raiz del repo, asi que devolvia vacio y ASC rechazaba el POST por versionString ausente. Ahora es absoluto respecto al Fastfile y falla ruidoso si no puede leerlo. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_012Ks8uUcMA9mjypVK7F2Pkt --- fastlane/Fastfile | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) 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,