BlueWallet/ios/fastlane/Fastfile
2024-03-03 09:40:34 -04:00

313 lines
10 KiB
Ruby

def app_identifiers
["io.bluewallet.bluewallet", "io.bluewallet.bluewallet.watch", "io.bluewallet.bluewallet.watch.extension", "io.bluewallet.bluewallet.Stickers", "io.bluewallet.bluewallet.MarketWidget"]
end
platform :ios do
before_all do |lane, options|
UI.message("Setting up for all lanes...")
UI.message("Discarding all untracked changes before running any lane...")
sh("git clean -fd")
sh("git checkout -- .")
end
desc "Register new devices from a file"
lane :register_devices_from_txt do
UI.message("Registering new devices from file...")
csv_path = "../../devices.txt" # Update this with the actual path to your file
# Registering devices using the devices_file parameter
register_devices(
devices_file: csv_path
)
UI.message("Devices registered successfully.")
app_identifiers.each do |app_identifier|
match(
type: "development",
app_identifier: app_identifier,
readonly: false, # This will regenerate the provisioning profile if needed
force_for_new_devices: true # This forces match to add new devices to the profile
)
end
UI.message("Development provisioning profiles updated.")
end
desc "Create a temporary keychain"
lane :create_temp_keychain do
UI.message("Creating a temporary keychain...")
create_keychain(
name: "temp_keychain",
password: ENV["KEYCHAIN_PASSWORD"],
default_keychain: true,
unlock: true,
timeout: 3600,
lock_when_sleeps: true
)
UI.message("Temporary keychain created successfully.")
end
desc "Synchronize certificates and provisioning profiles"
lane :setup_provisioning_profiles do |options|
UI.message("Setting up provisioning profiles...")
target_to_app_identifier = {
'BlueWallet' => 'io.bluewallet.bluewallet',
'BlueWalletWatch' => 'io.bluewallet.bluewallet.watch',
'BlueWalletWatchExtension' => 'io.bluewallet.bluewallet.watch.extension',
'Stickers' => 'io.bluewallet.bluewallet.Stickers',
'MarketWidget' => 'io.bluewallet.bluewallet.MarketWidget'
}
platform = options[:platform] || "ios" # Default to iOS if not specified
target_to_app_identifier.each do |target, app_identifier|
match(
git_basic_authorization: ENV["MATCH_GIT_BASIC_AUTHORIZATION"],
git_url: ENV["GIT_URL"],
type: "appstore",
platform: platform,
app_identifier: app_identifier,
team_id: ENV["ITC_TEAM_ID"],
team_name: ENV["ITC_TEAM_NAME"],
readonly: true,
keychain_name: "temp_keychain",
keychain_password: ENV["KEYCHAIN_PASSWORD"]
)
end
end
desc "Fetch development certificates and provisioning profiles for Mac Catalyst"
lane :fetch_dev_profiles_catalyst do
match(
type: "development",
platform: "catalyst",
app_identifier: app_identifiers,
readonly: true
)
end
desc "Fetch App Store certificates and provisioning profiles for Mac Catalyst"
lane :fetch_appstore_profiles_catalyst do
match(
type: "appstore",
platform: "catalyst",
app_identifier: app_identifiers,
readonly: true
)
end
desc "Clear derived data"
lane :clear_derived_data_lane do
UI.message("Clearing derived data...")
clear_derived_data
end
desc "Increment build number"
lane :increment_build_number_lane do
UI.message("Incrementing build number to current timestamp...")
# Set the new build number
increment_build_number(
xcodeproj: "BlueWallet.xcodeproj",
build_number: ENV["NEW_BUILD_NUMBER"]
)
UI.message("Build number set to: #{ENV['NEW_BUILD_NUMBER']}")
end
desc "Install CocoaPods dependencies"
lane :install_pods do
UI.message("Installing CocoaPods dependencies...")
cocoapods
end
desc "Build the application"
lane :build_app_lane do
UI.message("Building the application...")
build_app(
scheme: "BlueWallet",
workspace: "BlueWallet.xcworkspace",
export_method: "app-store",
include_bitcode: true,
configuration: "Release",
skip_profile_detection: true,
include_symbols: true,
export_team_id: ENV["ITC_TEAM_ID"],
export_options: {
signingStyle: "manual",
provisioningProfiles: {
'io.bluewallet.bluewallet' => 'match AppStore io.bluewallet.bluewallet',
'io.bluewallet.bluewallet.watch' => 'match AppStore io.bluewallet.bluewallet.watch',
'io.bluewallet.bluewallet.watch.extension' => 'match AppStore io.bluewallet.bluewallet.watch.extension',
'io.bluewallet.bluewallet.Stickers' => 'match AppStore io.bluewallet.bluewallet.Stickers',
'io.bluewallet.bluewallet.MarketWidget' => 'match AppStore io.bluewallet.bluewallet.MarketWidget'
}
},
xcargs: "GCC_PREPROCESSOR_DEFINITIONS='$(inherited) VERBOSE_LOGGING=1'",
output_directory: "./build", # Directory where the IPA file will be stored
output_name: "BlueWallet.#{ENV['PROJECT_VERSION']}(#{ENV['NEW_BUILD_NUMBER']}).ipa",
buildlog_path: "./build_logs"
)
end
desc "Upload to TestFlight without Processing Wait"
lane :upload_to_testflight_lane do
attempts = 0
max_attempts = 3
begin
UI.message("Uploading to TestFlight without processing wait...")
changelog = ENV["LATEST_COMMIT_MESSAGE"]
upload_to_testflight(
api_key_path: "appstore_api_key.json",
ipa: "./build/BlueWallet.#{ENV['PROJECT_VERSION']}(#{ENV['NEW_BUILD_NUMBER']}).ipa",
skip_waiting_for_build_processing: true, # Do not wait for processing
changelog: changelog
)
rescue => exception
attempts += 1
if attempts <= max_attempts
wait_time = 180 # 3 minutes in seconds
UI.message("Attempt ##{attempts} failed with error: #{exception.message}. Waiting #{wait_time} seconds before trying again...")
sleep(wait_time)
retry
else
UI.error("Failed after #{max_attempts} attempts. Error: #{exception.message}")
raise exception
end
end
end
desc "Deploy to TestFlight"
lane :deploy do |options|
UI.message("Starting build process...")
# Update the WWDR certificate
update_wwdr_certificate
setup_app_store_connect_api_key
setup_provisioning_profiles
clear_derived_data_lane
increment_build_number_lane
unless File.directory?("Pods")
install_pods
end
build_app_lane
upload_to_testflight_lane
# Clean up and delete the temporary keychain
delete_keychain(name: "temp_keychain")
# Mark deployment as completed for the current commit
last_commit = last_git_commit
already_built_flag = ".already_built_#{last_commit[:sha]}"
File.write(already_built_flag, Time.now.to_s)
end
desc "Build and distribute the Mac Catalyst app for BlueWallet-NoLDK (Universal)"
lane :build_and_distribute_catalyst_universal do |options|
# Conditionally fetch the right provisioning profiles
if options[:type] == "development"
fetch_dev_profiles_catalyst
else
fetch_appstore_profiles_catalyst
end
# Build the Mac Catalyst app (Universal Build for Apple Silicon and Intel)
build_app(
scheme: "BlueWallet-NoLDK",
configuration: "Release",
catalyst_platform: "macos",
export_method: options[:type] || "app-store", # Default to app-store if not specified
xcargs: "ARCHS='arm64 x86_64' VALID_ARCHS='arm64 x86_64'",
export_options: {
provisioningProfiles: {
"io.bluewallet.bluewallet" => "Provisioning Profile Name for Catalyst",
# Include other identifiers as necessary
},
signingStyle: "manual",
}
)
# Optionally, upload the build to TestFlight or App Store Connect for app-store type
if options[:type] != "development"
upload_to_testflight(skip_waiting_for_build_processing: true)
end
end
desc "Update 'What's New' section in App Store Connect for all localizations"
lane :update_release_notes do
# Path to the release notes file
# Make sure to edit it to remove any mention of non-Apple products
release_notes_path = "../../release-notes.txt"
# Ensure the release notes file exists
unless File.exist?(release_notes_path)
UI.error("Release notes file does not exist at path: #{release_notes_path}")
next # Skip the rest of the lane if file not found
end
# Read release notes from file
release_notes_text = File.read(release_notes_path)
# Log the content of release notes
UI.message("Release Notes Content:\n#{release_notes_text}")
# Define version number
app_version = get_version_number # Make sure this gets the correct version number
UI.message("Version being updated: #{app_version}")
# Hash mapping language codes to release notes text
localized_release_notes = {
'en-US' => release_notes_text, # English (U.S.) - Primary
'ar-SA' => release_notes_text, # Arabic
'zh-Hans' => release_notes_text, # Chinese (Simplified)
'da' => release_notes_text, # Danish
'nl-NL' => release_notes_text, # Dutch
'fi' => release_notes_text, # Finnish
'fr-FR' => release_notes_text, # French
'de-DE' => release_notes_text, # German
'he' => release_notes_text, # Hebrew
'hu' => release_notes_text, # Hungarian
'it' => release_notes_text, # Italian
'pt-BR' => release_notes_text, # Portuguese (Brazil)
'pt-PT' => release_notes_text, # Portuguese (Portugal)
'ro' => release_notes_text, # Romanian
'ru' => release_notes_text, # Russian
'es-MX' => release_notes_text, # Spanish (Mexico)
'es-ES' => release_notes_text, # Spanish (Spain)
'sv' => release_notes_text, # Swedish
}
# Log which version and what content is being set
localized_release_notes.each do |locale, notes|
UI.message("Setting release notes for #{locale}:\n#{notes}\n")
end
# Update release notes in App Store Connect for all localizations
deliver(
app_identifier: app_identifiers.first, # Use the first app identifier
app_version: app_version, # Use the fetched app version
skip_metadata: true, # We are updating metadata
skip_screenshots: true,
skip_binary_upload: true,
force: true, # Skip HTML report verification
release_notes: localized_release_notes,
submit_for_review: false, # Change this to true if you want to automatically submit the version for review
automatic_release: false # Change to true if you want the version to be released automatically once approved
)
end
end