630 lines
19 KiB
Ruby
630 lines
19 KiB
Ruby
# Customise this file, documentation can be found here:
|
|
# https://github.com/fastlane/fastlane/tree/master/docs
|
|
# All available actions: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Actions.md
|
|
# can also be listed using the `fastlane actions` command
|
|
|
|
# Change the syntax highlighting to Ruby
|
|
# All lines starting with a # are ignored when running `fastlane`
|
|
|
|
# If you want to automatically update fastlane if a new version is available:
|
|
# update_fastlane
|
|
|
|
# This is the minimum version number required.
|
|
# Update this, if you use features of a newer version
|
|
fastlane_version '2.137.0'
|
|
default_platform :ios
|
|
|
|
before_all do
|
|
setup
|
|
end
|
|
|
|
private_lane :setup do
|
|
ENV['FASTLANE_USER'] = ENV.fetch('HOMEASSISTANT_APPLE_ID', nil)
|
|
ENV['DELIVER_USERNAME'] = ENV.fetch('HOMEASSISTANT_APPLE_ID', nil)
|
|
ENV['FASTLANE_TEAM_ID'] = ENV.fetch('HOMEASSISTANT_TEAM_ID', nil)
|
|
ENV['FL_NOTARIZE_ASC_PROVIDER'] = ENV.fetch('HOMEASSISTANT_TEAM_ID', nil)
|
|
ENV['PILOT_APPLE_ID'] = ENV.fetch('HOMEASSISTANT_APPLE_ID', nil)
|
|
ENV['SIGH_USERNAME'] = ENV.fetch('HOMEASSISTANT_APPLE_ID', nil)
|
|
ENV['FL_NOTARIZE_USERNAME'] = ENV.fetch('HOMEASSISTANT_APPLE_ID', nil)
|
|
ENV['LOKALISE_API_TOKEN'] = ENV.fetch('HOMEASSISTANT_LOKALIZE_TOKEN', nil)
|
|
ENV['LOKALISE_PROJECT_ID'] = ENV.fetch('HOMEASSISTANT_LOKALIZE_PROJECT_ID', nil)
|
|
ENV['LOKALISE_PROJECT_ID_FRONTEND'] = ENV.fetch('HOMEASSISTANT_LOKALIZE_PROJECT_FRONTEND', nil)
|
|
ENV['LOKALISE_PROJECT_ID_CORE'] = ENV.fetch('HOMEASSISTANT_LOKALIZE_PROJECT_CORE', nil)
|
|
ENV['PILOT_ITC_PROVIDER'] = ENV.fetch('HOMEASSISTANT_APP_STORE_CONNECT_TEAM_ID', nil)
|
|
ENV['FASTLANE_ITC_TEAM_ID'] = ENV.fetch('HOMEASSISTANT_APP_STORE_CONNECT_TEAM_ID', nil)
|
|
ENV['SIGH_USERNAME'] = ENV.fetch('HOMEASSISTANT_APPLE_ID', nil)
|
|
ENV['SIGH_PROFILE_PATHS'] = '../Configuration/Provisioning'
|
|
|
|
app_store_connect_api_key if ENV['APP_STORE_CONNECT_API_KEY_KEY']
|
|
end
|
|
|
|
lane :lint do
|
|
sh('cd .. ; Pods/SwiftFormat/CommandLineTool/swiftformat --config .swiftformat --lint --quiet .')
|
|
sh('cd .. ; Pods/SwiftLint/swiftlint lint --config .swiftlint.yml --quiet .')
|
|
sh('cd .. ; bundle exec rubocop --config .rubocop.yml')
|
|
end
|
|
|
|
lane :autocorrect do
|
|
sh('../Pods/SwiftFormat/CommandLineTool/swiftformat ..')
|
|
sh('bundle exec rubocop -a ..')
|
|
end
|
|
|
|
lane :download_provisioning_profiles do
|
|
%w[ios catalyst macos].each do |platform|
|
|
sh(
|
|
'bundle', 'exec', 'fastlane', 'sigh', 'repair',
|
|
'-p', platform,
|
|
'-b', ENV.fetch('HOMEASSISTANT_TEAM_ID', nil),
|
|
'-u', ENV.fetch('SIGH_USERNAME', nil)
|
|
)
|
|
sh(
|
|
'bundle', 'exec', 'fastlane', 'sigh', 'download_all',
|
|
'-p', platform,
|
|
'-o', '../Configuration/Provisioning/',
|
|
'-b', ENV.fetch('HOMEASSISTANT_TEAM_ID', nil),
|
|
'-u', ENV.fetch('SIGH_USERNAME', nil)
|
|
)
|
|
end
|
|
end
|
|
|
|
lane :import_provisioning_profiles do
|
|
directory = '../Configuration/Provisioning'
|
|
|
|
Dir.children(directory).each do |file|
|
|
next if file.start_with?('.')
|
|
|
|
install_provisioning_profile(path: File.expand_path(File.join(directory, file)))
|
|
end
|
|
end
|
|
|
|
lane :update_dsyms do
|
|
directory = File.expand_path('dSYMs')
|
|
FileUtils.mkdir_p directory
|
|
|
|
download_dsyms(
|
|
after_uploaded_date: Date.today.prev_day(7).iso8601,
|
|
app_identifier: 'io.robbie.HomeAssistant',
|
|
output_directory: directory
|
|
)
|
|
|
|
FileUtils.rm_r directory
|
|
end
|
|
|
|
desc 'Update the test cases from the fcm repo'
|
|
lane :update_notification_test_cases do
|
|
bundle_directory = File.expand_path('../Tests/Shared/notification_test_cases.bundle')
|
|
zip_file = Tempfile.new(['archive', '.zip'])
|
|
|
|
FileUtils.rm_rf bundle_directory
|
|
FileUtils.mkdir_p bundle_directory
|
|
|
|
begin
|
|
archive_url = 'https://github.com/home-assistant/mobile-apps-fcm-push/archive/refs/heads/master.zip'
|
|
unzip_path = 'mobile-apps-fcm-push-master/functions/test/fixtures/legacy/*.json'
|
|
|
|
sh("curl -L #{archive_url} -o #{zip_file.path}")
|
|
sh("unzip -j #{zip_file.path} -d #{bundle_directory} '#{unzip_path}'")
|
|
ensure
|
|
zip_file.unlink
|
|
end
|
|
end
|
|
|
|
desc 'Generate proper icons for all build trains'
|
|
lane :icons do
|
|
appicon(appicon_path: 'Sources/App/Resources/Assets.xcassets', appicon_image_file: 'icons/dev.png',
|
|
appicon_name: 'AppIcon.dev.appiconset', appicon_devices: %i[ipad iphone ios_marketing macos])
|
|
appicon(appicon_path: 'Sources/App/Resources/Assets.xcassets', appicon_image_file: 'icons/beta.png',
|
|
appicon_name: 'AppIcon.beta.appiconset', appicon_devices: %i[ipad iphone ios_marketing macos])
|
|
appicon(appicon_path: 'Sources/App/Resources/Assets.xcassets', appicon_image_file: 'icons/release.png',
|
|
appicon_devices: %i[ipad iphone ios_marketing macos])
|
|
|
|
appicon(appicon_path: 'WatchApp/Assets.xcassets', appicon_image_file: 'icons/dev.png',
|
|
appicon_name: 'WatchIcon.dev.appiconset', appicon_devices: %i[watch watch_marketing])
|
|
appicon(appicon_path: 'WatchApp/Assets.xcassets', appicon_image_file: 'icons/beta.png',
|
|
appicon_name: 'WatchIcon.beta.appiconset', appicon_devices: %i[watch watch_marketing])
|
|
appicon(appicon_path: 'WatchApp/Assets.xcassets', appicon_image_file: 'icons/release.png',
|
|
appicon_name: 'WatchIcon.appiconset', appicon_devices: %i[watch watch_marketing])
|
|
end
|
|
|
|
desc 'Update switftgen input/output files'
|
|
lane :update_swiftgen_config do
|
|
# rubocop:disable Layout/LineLength
|
|
sh('cd ../ && ./Pods/SwiftGen/bin/swiftgen config generate-xcfilelists --inputs swiftgen.yml.file-list.in --outputs swiftgen.yml.file-list.out')
|
|
# rubocop:enable Layout/LineLength
|
|
end
|
|
|
|
desc 'Download latest localization files from Lokalize'
|
|
lane :update_strings do
|
|
token = ENV.fetch('LOKALISE_API_TOKEN') do
|
|
prompt(
|
|
text: 'API token',
|
|
secure_text: true
|
|
)
|
|
end
|
|
|
|
project_id = ENV.fetch('LOKALISE_PROJECT_ID') do
|
|
prompt(
|
|
text: 'Project ID',
|
|
secure_text: true
|
|
)
|
|
end
|
|
|
|
frontend_project_id = ENV.fetch('LOKALISE_PROJECT_ID_FRONTEND') do
|
|
prompt(
|
|
text: 'Frontend Project ID',
|
|
secure_text: true
|
|
)
|
|
end
|
|
|
|
core_project_id = ENV.fetch('LOKALISE_PROJECT_ID_CORE') do
|
|
prompt(
|
|
text: 'Core Project ID',
|
|
secure_text: true
|
|
)
|
|
end
|
|
|
|
resources_dir_full = File.expand_path('../Sources/App/Resources')
|
|
|
|
sh(
|
|
'lokalise2',
|
|
'--token', token,
|
|
'--project-id', project_id,
|
|
'file', 'download',
|
|
'--format', 'ios_sdk',
|
|
'--export-empty-as', 'base',
|
|
'--export-sort', 'a_z',
|
|
'--replace-breaks=false',
|
|
'--include-comments=false',
|
|
'--include-description=false',
|
|
'--unzip-to', resources_dir_full,
|
|
log: false
|
|
)
|
|
|
|
lang_frontend_to_ios = {
|
|
'bg' => 'bg',
|
|
'ca' => 'ca-ES',
|
|
'cs' => 'cs',
|
|
'cy' => 'cy-GB',
|
|
'da' => 'da',
|
|
'de' => 'de',
|
|
'el' => 'el',
|
|
'en-GB' => 'en-GB',
|
|
'en' => 'en',
|
|
'es' => 'es-ES',
|
|
'es-419' => 'es',
|
|
# es-MX is missing from the frontend, so we copy es over below
|
|
'et' => 'et',
|
|
'fi' => 'fi',
|
|
'fr' => 'fr',
|
|
'he' => 'he',
|
|
'hu' => 'hu',
|
|
'id' => 'id',
|
|
'it' => 'it',
|
|
'ja' => 'ja',
|
|
'ko' => 'ko-KR',
|
|
'ml' => 'ml',
|
|
'nb' => 'nb',
|
|
'nl' => 'nl',
|
|
'pl' => 'pl-PL',
|
|
'pt-BR' => 'pt-BR',
|
|
'ru' => 'ru',
|
|
'sl' => 'sl',
|
|
'sv' => 'sv',
|
|
'tr' => 'tr',
|
|
'uk' => 'uk',
|
|
'vi' => 'vi',
|
|
'zh-Hans' => 'zh-Hans',
|
|
'zh-Hant' => 'zh-Hant'
|
|
}
|
|
|
|
# to => from, since to is unique but from may not be
|
|
manually_copied_languages = {
|
|
'es-MX' => 'es'
|
|
}
|
|
|
|
# make sure the previous map has everything. adding a new language should error.
|
|
ios_languages = Set.new(
|
|
Dir.children(resources_dir_full)
|
|
.select { |file| File.extname(file) == '.lproj' }
|
|
.map { |file| File.basename(file, File.extname(file)) }
|
|
.reject { |lang| lang == 'Base' }
|
|
)
|
|
|
|
mapped_ios_languages = Set.new(lang_frontend_to_ios.values + manually_copied_languages.keys)
|
|
|
|
unless ios_languages == mapped_ios_languages
|
|
missing = ios_languages - mapped_ios_languages
|
|
UI.user_error!("missing language in map. missing: #{missing.to_a.join(', ')}")
|
|
end
|
|
|
|
language_mapping = lang_frontend_to_ios
|
|
.map { |key, value| { 'original_language_iso' => key, custom_language_iso: value } }
|
|
|
|
sh(
|
|
'lokalise2',
|
|
'--token', token,
|
|
'--project-id', frontend_project_id,
|
|
'file', 'download',
|
|
'--format', 'strings',
|
|
'--filter-langs', lang_frontend_to_ios.keys.join(','),
|
|
'--language-mapping', language_mapping.to_json.to_s,
|
|
'--original-filenames=false',
|
|
'--bundle-structure', '%LANG_ISO%.lproj/Frontend.%FORMAT%',
|
|
'--export-empty-as', 'base',
|
|
'--export-sort', 'a_z',
|
|
'--replace-breaks=false',
|
|
'--include-comments=false',
|
|
'--include-description=false',
|
|
'--unzip-to', resources_dir_full,
|
|
log: false
|
|
)
|
|
|
|
manually_copied_languages.each do |to, from|
|
|
FileUtils.cp(
|
|
"#{resources_dir_full}/#{from}.lproj/Frontend.strings",
|
|
"#{resources_dir_full}/#{to}.lproj/Frontend.strings"
|
|
)
|
|
end
|
|
|
|
sh(
|
|
'lokalise2',
|
|
'--token', token,
|
|
'--project-id', core_project_id,
|
|
'file', 'download',
|
|
'--format', 'strings',
|
|
'--filter-langs', lang_frontend_to_ios.keys.join(','),
|
|
'--language-mapping', language_mapping.to_json.to_s,
|
|
'--original-filenames=false',
|
|
'--bundle-structure', '%LANG_ISO%.lproj/Core.%FORMAT%',
|
|
'--export-empty-as', 'base',
|
|
'--export-sort', 'a_z',
|
|
'--replace-breaks=false',
|
|
'--include-comments=false',
|
|
'--include-description=false',
|
|
'--unzip-to', resources_dir_full,
|
|
log: false
|
|
)
|
|
|
|
manually_copied_languages.each do |to, from|
|
|
FileUtils.cp(
|
|
"#{resources_dir_full}/#{from}.lproj/Core.strings",
|
|
"#{resources_dir_full}/#{to}.lproj/Core.strings"
|
|
)
|
|
end
|
|
|
|
sh('cd ../ && ./Pods/SwiftGen/bin/swiftgen')
|
|
end
|
|
|
|
desc 'Upload localized strings to Lokalise'
|
|
lane :push_strings do
|
|
source_directories = [
|
|
'../Sources/App/Resources/en.lproj'
|
|
]
|
|
|
|
token = ENV.fetch('LOKALISE_API_TOKEN') do
|
|
prompt(
|
|
text: 'API token',
|
|
secure_text: true
|
|
)
|
|
end
|
|
|
|
project_id = ENV.fetch('LOKALISE_PROJECT_ID') do
|
|
prompt(
|
|
text: 'Project ID',
|
|
secure_text: true
|
|
)
|
|
end
|
|
|
|
source_directories.each do |directory|
|
|
puts "Enumerating #{directory}..."
|
|
Dir.each_child(directory) do |file|
|
|
next if ['Frontend.strings', 'Core.strings'].include?(file)
|
|
|
|
puts "Uploading file #{file}"
|
|
sh(
|
|
'lokalise2',
|
|
'--token', token,
|
|
'--project-id', project_id,
|
|
'file', 'upload',
|
|
'--file', "#{directory}/#{file}",
|
|
'--lang-iso', 'en',
|
|
log: false
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
desc 'Find unused localized strings'
|
|
lane :unused_strings do
|
|
files = [
|
|
'../Sources/App/Resources/en.lproj/Localizable.strings'
|
|
]
|
|
files.each do |file|
|
|
puts "Looking at #{file}"
|
|
unused_strings = File.read(file)
|
|
# grab the keys only
|
|
.scan(/"([^"]+)" = [^;]+;/)
|
|
# replace _ in the keys with nothing, which is what swiftgen does
|
|
.map { |s| [s[0], s[0].gsub('_', '')] }
|
|
# ignore any keys at the root level (aka like ok_label)
|
|
.select { |full, _key| full.include?('.') }
|
|
# find any strings that don't have matches in code
|
|
.select { |_full, key| system("git grep --ignore-case --quiet #{key} -- ../*.swift") == false }
|
|
unused_strings.each_key { |full| puts full }
|
|
puts "- Found #{unused_strings.count} unused strings"
|
|
end
|
|
end
|
|
|
|
desc 'Upload App Store Connect metadata to Lokalise'
|
|
lane :update_lokalise_metadata do
|
|
lokalise_metadata(action: 'update_lokalise', override_translation: true)
|
|
end
|
|
|
|
desc 'Download App Store Connect metadata from Lokalise and upload to App Store Connect Connect'
|
|
lane :update_asc_metadata do
|
|
lokalise_metadata(action: 'update_itunes')
|
|
end
|
|
|
|
private_lane :set_version_info do |options|
|
|
File.write(
|
|
'../Configuration/Version.xcconfig',
|
|
"MARKETING_VERSION=#{options[:version]}\nCURRENT_PROJECT_VERSION=#{options[:build]}\n"
|
|
)
|
|
end
|
|
|
|
private_lane :get_xcconfig_marketing_version do
|
|
sh('cd .. ; . Configuration/Version.xcconfig ; echo $MARKETING_VERSION').strip!
|
|
end
|
|
|
|
private_lane :get_xcconfig_build_number do
|
|
sh('cd .. ; . Configuration/Version.xcconfig; echo $CURRENT_PROJECT_VERSION').strip!
|
|
end
|
|
|
|
desc 'Set version number'
|
|
lane :set_version do |options|
|
|
version = options[:version]
|
|
|
|
unless version
|
|
if is_ci
|
|
UI.error 'no version provided'
|
|
else
|
|
version = prompt(text: 'Version number: ')
|
|
end
|
|
end
|
|
|
|
set_version_info(
|
|
version: version,
|
|
build: get_xcconfig_build_number
|
|
)
|
|
end
|
|
|
|
desc 'Setup Continous Integration'
|
|
lane :setup_ha_ci do
|
|
raise 'No github run number specified' unless ENV['GITHUB_RUN_NUMBER']
|
|
|
|
set_version_info(
|
|
version: get_xcconfig_marketing_version,
|
|
build: get_xcconfig_build_number + '.' + ENV.fetch('GITHUB_RUN_NUMBER', nil) # rubocop:disable Style/StringConcatenation
|
|
)
|
|
|
|
# we only expose these keys in ci when appropriate
|
|
ENV['FASTLANE_DONT_STORE_PASSWORD'] = '1'
|
|
ENV['FASTLANE_PASSWORD'] = ENV.fetch('HOMEASSISTANT_APP_STORE_CONNECT_PASSWORD', nil)
|
|
ENV['FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD'] = ENV.fetch('HOMEASSISTANT_APP_STORE_CONNECT_PASSWORD', nil)
|
|
|
|
keychain_name = 'HomeAssistant-Keychain'
|
|
keychain_password = SecureRandom.hex
|
|
|
|
begin
|
|
delete_keychain(name: keychain_name)
|
|
rescue StandardError
|
|
# we don't care if it didn't exist yet
|
|
end
|
|
|
|
create_keychain(
|
|
name: keychain_name,
|
|
password: keychain_password,
|
|
timeout: 3600,
|
|
unlock: true,
|
|
add_to_search_list: true
|
|
)
|
|
|
|
KeyAndValue = Struct.new(:key, :value) # rubocop:disable Lint/ConstantDefinitionInBlock
|
|
|
|
[
|
|
KeyAndValue.new(ENV.fetch('P12_KEY_IOS_APP_STORE', nil), ENV.fetch('P12_VALUE_IOS_APP_STORE', nil)),
|
|
KeyAndValue.new(ENV.fetch('P12_KEY_MAC_APP_STORE', nil), ENV.fetch('P12_VALUE_MAC_APP_STORE', nil)),
|
|
KeyAndValue.new(ENV.fetch('P12_KEY_MAC_DEVELOPER_ID', nil), ENV.fetch('P12_VALUE_MAC_DEVELOPER_ID', nil))
|
|
].each do |info|
|
|
tmp_file = '/tmp/import.p12'
|
|
File.write(tmp_file, Base64.decode64(info.value))
|
|
|
|
import_certificate(
|
|
certificate_path: tmp_file,
|
|
certificate_password: info.key,
|
|
keychain_name: keychain_name,
|
|
keychain_password: keychain_password
|
|
)
|
|
|
|
FileUtils.rm(tmp_file)
|
|
end
|
|
|
|
import_provisioning_profiles
|
|
end
|
|
|
|
desc 'Run tests'
|
|
lane :test do
|
|
run_tests(
|
|
workspace: 'HomeAssistant.xcworkspace',
|
|
scheme: 'Tests-Unit',
|
|
result_bundle: true,
|
|
skip_package_dependencies_resolution: true,
|
|
destination: 'platform=iOS Simulator,name=iPhone 16,OS=18.1'
|
|
)
|
|
end
|
|
|
|
private_lane :provisioning_profile_specifiers do |options|
|
|
# gym doesn't parse the provisioning profile specifier, so we need to do it ourselves
|
|
all_targets_result = sh([
|
|
'xcodebuild',
|
|
'2>/dev/null', # this command started outputting warnings in Xcode 12.5
|
|
'-json',
|
|
'-showBuildSettings',
|
|
'-sdk', options[:sdk],
|
|
'-project', '../HomeAssistant.xcodeproj',
|
|
'-scheme', 'App-Release',
|
|
'-list'
|
|
] + [], log: false)
|
|
all_targets = JSON.parse(all_targets_result)['project']['targets'].map { |t| "-target #{t}" }
|
|
|
|
settings_result = sh([
|
|
'xcodebuild',
|
|
'2>/dev/null', # this command started outputting warnings in Xcode 12.5
|
|
'-json',
|
|
'-showBuildSettings',
|
|
'-sdk', options[:sdk],
|
|
'-project', '../HomeAssistant.xcodeproj'
|
|
] + all_targets, log: false)
|
|
|
|
settings = JSON.parse(settings_result)
|
|
|
|
specifiers = {}
|
|
settings.each do |target_info|
|
|
specifier = target_info['buildSettings']['PROVISIONING_PROFILE_SPECIFIER']
|
|
bundle_identifier = target_info['buildSettings']['PRODUCT_BUNDLE_IDENTIFIER']
|
|
next unless specifier && bundle_identifier
|
|
|
|
specifiers[bundle_identifier] = specifier
|
|
end
|
|
|
|
specifiers
|
|
end
|
|
|
|
private_lane :upload_binary_to_apple do |options|
|
|
attempts = 0
|
|
|
|
begin
|
|
sh(
|
|
'xcrun', 'altool', '--upload-app', '--type', options[:type],
|
|
'--file', options[:path],
|
|
'--username', ENV.fetch('DELIVER_USERNAME', nil),
|
|
'--password', '@env:FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD'
|
|
)
|
|
rescue StandardError => e
|
|
puts "Failed with #{e}; retrying upload..."
|
|
|
|
# retry a few times, then give up
|
|
attempts += 1
|
|
|
|
retry if attempts <= 3
|
|
raise e
|
|
end
|
|
end
|
|
|
|
platform :ios do
|
|
private_lane :create_archive do
|
|
setup_ha_ci if is_ci
|
|
specifiers = provisioning_profile_specifiers(sdk: 'iphoneos')
|
|
ipa_path = build_ios_app(
|
|
export_method: 'app-store',
|
|
skip_package_dependencies_resolution: true,
|
|
skip_profile_detection: true,
|
|
disable_xcpretty: true,
|
|
output_directory: './build/ios',
|
|
export_options: {
|
|
signingStyle: 'manual',
|
|
provisioningProfiles: specifiers
|
|
}
|
|
)
|
|
if ENV['EMERGE_API_TOKEN']
|
|
emerge(
|
|
repo_name: ENV.fetch('EMERGE_REPO_NAME', nil),
|
|
pr_number: ENV.fetch('EMERGE_PR_NUMBER', nil),
|
|
sha: ENV.fetch('EMERGE_SHA', nil),
|
|
base_sha: ENV.fetch('EMERGE_BASE_SHA', nil)
|
|
)
|
|
end
|
|
ipa_path
|
|
end
|
|
|
|
lane :build do
|
|
ipa_path = create_archive
|
|
upload_binary_to_apple(
|
|
type: 'ios',
|
|
path: ipa_path
|
|
)
|
|
end
|
|
|
|
lane :size do
|
|
create_archive
|
|
end
|
|
end
|
|
|
|
platform :mac do
|
|
lane :build do
|
|
setup_ha_ci if is_ci
|
|
|
|
specifiers = provisioning_profile_specifiers(sdk: 'macosx')
|
|
developer_id_app_path = build_mac_app(
|
|
export_method: 'developer-id',
|
|
skip_package_dependencies_resolution: true,
|
|
skip_profile_detection: true,
|
|
skip_package_pkg: true,
|
|
disable_xcpretty: true,
|
|
output_directory: './build/macos',
|
|
export_options: {
|
|
signingStyle: 'manual',
|
|
provisioningProfiles: specifiers
|
|
}
|
|
)
|
|
app_store_pkg_path = build_mac_app(
|
|
archive_path: lane_context[SharedValues::XCODEBUILD_ARCHIVE],
|
|
export_method: 'app-store',
|
|
skip_package_dependencies_resolution: true,
|
|
skip_profile_detection: true,
|
|
skip_build_archive: true,
|
|
skip_package_pkg: false,
|
|
output_directory: './build/macos',
|
|
export_options: {
|
|
signingStyle: 'manual',
|
|
provisioningProfiles: specifiers.transform_values { |v| v.sub('Mac Dev ID', 'Mac App Store') }
|
|
}
|
|
)
|
|
|
|
notarize_attempts = 0
|
|
|
|
begin
|
|
notarize(
|
|
package: developer_id_app_path,
|
|
# not the _app_ bundle id, just an id that notarize uses for referencing
|
|
bundle_id: 'io.home-assistant.fastlane.developer-id',
|
|
verbose: true
|
|
)
|
|
rescue StandardError => e
|
|
puts "Failed with #{e}; retrying notarize in a few seconds..."
|
|
|
|
sleep 5
|
|
|
|
# retry a few times, then give up
|
|
notarize_attempts += 1
|
|
|
|
retry if notarize_attempts <= 3
|
|
raise e
|
|
end
|
|
|
|
sh(
|
|
'ditto',
|
|
'-c',
|
|
'-k',
|
|
'--sequesterRsrc',
|
|
'--keepParent',
|
|
File.expand_path(developer_id_app_path),
|
|
'../build/macos/home-assistant-mac.zip'
|
|
)
|
|
upload_binary_to_apple(
|
|
type: 'osx',
|
|
path: app_store_pkg_path
|
|
)
|
|
end
|
|
end
|