forked from eatvio/eatvio_app
The beta lane took the build number from pubspec (FLUTTER_BUILD_NUMBER). Re-running CI on the same commit re-submitted an already-taken build number and failed with 409 ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE (run 2045: build 157 was already on TestFlight). Now the lane queries the latest TestFlight build for the current marketing version (falling back to the pubspec value when nothing was uploaded yet) and uploads latest + 1, so retries can never collide.
135 lines
4.2 KiB
Ruby
135 lines
4.2 KiB
Ruby
# This file contains the fastlane.tools configuration
|
|
# You can find the documentation at https://docs.fastlane.tools
|
|
#
|
|
# For a list of all available actions, check out
|
|
#
|
|
# https://docs.fastlane.tools/actions
|
|
#
|
|
# For a list of all available plugins, check out
|
|
#
|
|
# https://docs.fastlane.tools/plugins/available-plugins
|
|
#
|
|
|
|
# Uncomment the line if you want fastlane to automatically update itself
|
|
# update_fastlane
|
|
|
|
default_platform(:ios)
|
|
|
|
platform :ios do
|
|
desc "Push a new beta build to TestFlight"
|
|
lane :beta do
|
|
UI.message "Current working directory: #{Dir.pwd}"
|
|
UI.message "Checking API key file..."
|
|
|
|
possible_paths = [
|
|
"../AuthKey.p8",
|
|
"./AuthKey.p8",
|
|
"../../AuthKey.p8",
|
|
File.expand_path("../AuthKey.p8"),
|
|
File.expand_path("./AuthKey.p8")
|
|
]
|
|
|
|
auth_key_path = nil
|
|
possible_paths.each do |path|
|
|
if File.exist?(path)
|
|
UI.message "Found AuthKey.p8 at: #{path}"
|
|
auth_key_path = File.expand_path(path)
|
|
break
|
|
end
|
|
end
|
|
|
|
if auth_key_path.nil?
|
|
UI.user_error!("API key file not found. Tried paths: #{possible_paths.join(', ')}")
|
|
end
|
|
|
|
UI.message "Using auth_key_path: #{auth_key_path}"
|
|
|
|
# Authenticate to App Store Connect early:
|
|
# needed here by latest_testflight_build_number, not only by upload_to_testflight.
|
|
app_store_connect_api_key(
|
|
key_id: "325JS9JCZH",
|
|
issuer_id: "dfa27d1d-2bb8-4d4d-847e-0b32f9b880b3",
|
|
key_filepath: auth_key_path,
|
|
duration: 1200,
|
|
in_house: false
|
|
)
|
|
|
|
# Configure Flutter for release mode
|
|
UI.message "Configuring Flutter for release mode..."
|
|
sh("cd .. && flutter build ios --config-only --release")
|
|
|
|
# Read version and build number from Flutter Generated.xcconfig.
|
|
# They are only a floor: the actual build number is derived from TestFlight below,
|
|
# so repeated CI runs on the same commit can never hit
|
|
# ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE ("bundle version must be higher").
|
|
generated_xcconfig_path = File.join("..", "Flutter", "Generated.xcconfig")
|
|
flutter_build_name = nil
|
|
flutter_build_number = nil
|
|
|
|
if File.exist?(generated_xcconfig_path)
|
|
File.foreach(generated_xcconfig_path) do |line|
|
|
if (m = line.match(/FLUTTER_BUILD_NAME=(.*)/))
|
|
flutter_build_name = m[1].strip
|
|
elsif (m = line.match(/FLUTTER_BUILD_NUMBER=(.*)/))
|
|
flutter_build_number = m[1].strip
|
|
end
|
|
end
|
|
end
|
|
|
|
if flutter_build_name.nil? || flutter_build_number.nil?
|
|
UI.user_error!("Could not find FLUTTER_BUILD_NAME/FLUTTER_BUILD_NUMBER in #{generated_xcconfig_path}")
|
|
end
|
|
|
|
UI.message "Flutter version from pubspec: #{flutter_build_name} (#{flutter_build_number})"
|
|
|
|
asc_latest_build_number = latest_testflight_build_number(
|
|
app_identifier: "com.eatvioapp.app",
|
|
version: flutter_build_name,
|
|
initial_build_number: flutter_build_number.to_i
|
|
)
|
|
|
|
new_build_number = [flutter_build_number.to_i, asc_latest_build_number].max + 1
|
|
UI.message "Latest TestFlight build number: #{asc_latest_build_number} -> uploading build #{new_build_number}"
|
|
|
|
match(type: "appstore", readonly: true)
|
|
|
|
# Set build number explicitly instead of incrementing
|
|
increment_build_number(
|
|
xcodeproj: "Runner.xcodeproj",
|
|
build_number: new_build_number
|
|
)
|
|
|
|
update_code_signing_settings(
|
|
use_automatic_signing: false,
|
|
path: "Runner.xcodeproj",
|
|
team_id: "VL68C36HYS",
|
|
targets: ["Runner"],
|
|
code_sign_identity: "Apple Distribution",
|
|
profile_name: "match AppStore com.eatvioapp.app 1781098260"
|
|
)
|
|
|
|
build_app(
|
|
workspace: "Runner.xcworkspace",
|
|
scheme: "Runner",
|
|
export_method: "app-store",
|
|
# codesigning_identity: "Apple Distribution",
|
|
export_team_id: "VL68C36HYS"
|
|
)
|
|
|
|
begin
|
|
upload_to_testflight(
|
|
skip_waiting_for_build_processing: true,
|
|
skip_submission: true,
|
|
distribute_external: false,
|
|
notify_external_testers: false,
|
|
changelog: "TestFlight build #{new_build_number}",
|
|
verbose: true
|
|
)
|
|
rescue => ex
|
|
UI.error "Upload to TestFlight failed: #{ex.message}"
|
|
UI.error "Full error: #{ex.backtrace.join("\n")}"
|
|
raise ex
|
|
end
|
|
end
|
|
end
|