native/fastlane/Fastfile
fastlane_version "2.220.0"
require_relative "read_build_config"
require "yaml"
require "base64"
# Google API fails randomly, try to retry
# https://github.com/fastlane/fastlane/issues/21507#issuecomment-1723116829
ENV['SUPPLY_UPLOAD_MAX_RETRIES']='5'
# The following parameters have to be passed:
# path: The path of the artifact (apk or ipa) to upload (relative to home dir)
desc "Upload the artifact to BrowserStack Live"
lane :browserstack_upload_live do |options|
ensure_env_vars(
env_vars: ["BROWSERSTACK_USERNAME", "BROWSERSTACK_ACCESS_KEY"]
)
path = options[:path]
if [path].include?(nil)
raise "'nil' passed as parameter! Aborting..."
end
upload_to_browserstack_app_live(
browserstack_username: ENV["BROWSERSTACK_USERNAME"],
browserstack_access_key: ENV["BROWSERSTACK_ACCESS_KEY"],
file_path: "#{ENV['HOME']}/#{path}"
)
end
platform :android do
# The following parameters have to be passed:
# apk_path: The path of the apk to upload (relative to home dir)
desc "Upload the APK and run E2E tests on BrowserStack"
lane :browserstack_e2e_tests do |options|
ensure_env_vars(
env_vars: ["BROWSERSTACK_USERNAME", "BROWSERSTACK_ACCESS_KEY"]
)
apk_path = options[:apk_path]
if [apk_path].include?(nil)
raise "'nil' passed as parameter! Aborting..."
end
upload_to_browserstack_app_automate(
browserstack_username: ENV["BROWSERSTACK_USERNAME"],
browserstack_access_key: ENV["BROWSERSTACK_ACCESS_KEY"],
file_path: "#{ENV['HOME']}/#{apk_path}"
)
ENV["E2E_CONFIG"] = "android"
ENV["E2E_BROWSERSTACK_USER"] = ENV["BROWSERSTACK_USERNAME"]
ENV["E2E_BROWSERSTACK_KEY"] = ENV["BROWSERSTACK_ACCESS_KEY"]
ENV["E2E_BROWSERSTACK_APP"] = lane_context[SharedValues::BROWSERSTACK_APP_ID]
yarn(
command: "test:e2e",
package_path: "package.json"
)
end
# The following parameters have to be passed:
# version_code: The version code of the app
# version_name: The version name of the app
# build_config_name: The name of the build config
# aab_path: The path of the aab to upload (relative to home dir)
# production_delivery: Whether the aab should be uploaded to the production track
desc "Deliver the app to Play Store. Depending on the option `production_delivery` the update is released to the general public."
lane :playstore_upload do |options|
ensure_env_vars(
env_vars: ["GOOGLE_SERVICE_ACCOUNT_JSON"]
)
version_code = options[:version_code]
version_name = options[:version_name]
build_config_name = options[:build_config_name]
aab_path = options[:aab_path]
production_delivery = options[:production_delivery]
if [version_name, version_code, build_config_name, aab_path, production_delivery].include?(nil)
raise "'nil' passed as parameter! Aborting..."
end
build_config = read_build_config(build_config_name, 'android')
skip_images = build_config_name != "integreat"
track = production_delivery === true ? "production" : "beta"
puts("delivering #{build_config_name} v#{version_name} to track #{track}")
# https://docs.fastlane.tools/actions/supply/
upload_to_play_store(
version_code: version_code,
version_name: version_name,
package_name: build_config['applicationId'],
metadata_path: "./android/fastlane/#{build_config_name}/metadata",
track: track,
skip_upload_changelogs: false,
skip_upload_images: skip_images,
skip_upload_screenshots: skip_images,
skip_upload_metadata: false,
release_status: "completed",
aab: "#{ENV['HOME']}/#{aab_path}",
json_key_data: ENV["GOOGLE_SERVICE_ACCOUNT_JSON"]
)
end
# The following parameters have to be passed:
# build_config_name: The name of the build config
desc "Promote the most recent version in the beta track to the production track in the Play Store."
lane :playstore_promote do |options|
ensure_env_vars(
env_vars: ["GOOGLE_SERVICE_ACCOUNT_JSON"]
)
build_config_name = options[:build_config_name]
if [build_config_name].include?(nil)
raise "'nil' passed as parameter! Aborting..."
end
build_config = read_build_config(build_config_name, 'android')
application_id = build_config['applicationId']
production_version_codes = google_play_track_version_codes(
track: "production",
package_name: application_id,
json_key_data: ENV["GOOGLE_SERVICE_ACCOUNT_JSON"]
)
beta_version_codes = google_play_track_version_codes(
track: "beta",
package_name: application_id,
json_key_data: ENV["GOOGLE_SERVICE_ACCOUNT_JSON"]
)
if beta_version_codes.length == 0 || beta_version_codes[0] <= production_version_codes[0]
puts("Nothing to do, latest version already available in production track...")
next
end
puts("promoting #{build_config_name} v#{beta_version_codes[0]} to production track")
# https://docs.fastlane.tools/actions/supply/
upload_to_play_store(
version_code: beta_version_codes[0],
package_name: application_id,
track: "beta",
track_promote_to: "production",
skip_upload_changelogs: true,
skip_upload_images: true,
skip_upload_screenshots: true,
skip_upload_metadata: true,
skip_upload_apk: true,
skip_upload_aab: true,
release_status: "completed",
json_key_data: ENV["GOOGLE_SERVICE_ACCOUNT_JSON"]
)
end
end
platform :ios do
private_lane :apple_auth do |options|
ensure_env_vars(
env_vars: ["APP_STORE_CONNECT_API_KEY_ID", "APP_STORE_CONNECT_API_ISSUER_ID", "APP_STORE_CONNECT_API_KEY_CONTENT"]
)
app_store_connect_api_key(
key_id: ENV['APP_STORE_CONNECT_API_KEY_ID'],
issuer_id: ENV['APP_STORE_CONNECT_API_ISSUER_ID'],
key_content: Base64.decode64(ENV['APP_STORE_CONNECT_API_KEY_CONTENT'])
)
end
# The following parameters have to be passed:
# build_config_name: The name of the build config
# ipa_path: The path of the ipa to upload (relative to home dir)
desc "Upload the IPA and run E2E tests on BrowserStack"
lane :browserstack_e2e_tests do |options|
ensure_env_vars(
env_vars: ["BROWSERSTACK_USERNAME", "BROWSERSTACK_ACCESS_KEY"]
)
ipa_path = options[:ipa_path]
if [ipa_path].include?(nil)
raise "'nil' passed as parameter! Aborting..."
end
upload_to_browserstack_app_automate(
browserstack_username: ENV["BROWSERSTACK_USERNAME"],
browserstack_access_key: ENV["BROWSERSTACK_ACCESS_KEY"],
file_path: "#{ENV['HOME']}/#{ipa_path}"
)
ENV["E2E_CONFIG"] = "ios"
ENV["E2E_BROWSERSTACK_USER"] = ENV["BROWSERSTACK_USERNAME"]
ENV["E2E_BROWSERSTACK_KEY"] = ENV["BROWSERSTACK_ACCESS_KEY"]
ENV["E2E_BROWSERSTACK_APP"] = lane_context[SharedValues::BROWSERSTACK_APP_ID]
yarn(
command: "test:e2e",
package_path: "package.json"
)
end
# The following parameters have to be passed:
# version_name: The version name of the app
# build_config_name: The name of the build config
# ipa_path: The path of the ipa to upload (relative to home dir)
desc "Deliver the app to App Store Connect. The app is submitted for review and released automatically."
lane :appstoreconnect_upload do |options|
apple_auth()
version_name = options[:version_name]
ipa_path = options[:ipa_path]
build_config_name = options[:build_config_name]
if [version_name, ipa_path, build_config_name].include?(nil)
raise "'nil' passed as parameter! Aborting..."
end
skip_screenshots = build_config_name != "integreat"
puts("delivering #{build_config_name} v#{version_name}")
puts("skip_screenshots: #{skip_screenshots}")
# https://docs.fastlane.tools/actions/deliver/
deliver(
ipa: "#{ENV['HOME']}/#{ipa_path}",
app_version: version_name,
submit_for_review: true,
automatic_release: true,
force: true,
skip_screenshots: skip_screenshots,
skip_metadata: false,
overwrite_screenshots: true,
skip_app_version_update: false,
metadata_path: "./ios/fastlane/#{build_config_name}/metadata",
screenshots_path: "./ios/fastlane/#{build_config_name}/screenshots",
precheck_include_in_app_purchases: false, # We do not have inapp purchases
submission_information: { add_id_info_uses_idfa: false } # https://firebase.google.com/docs/analytics/configure-data-collection?platform=ios
# https://support.google.com/firebase/answer/6318039?hl=en
)
end
# The following parameters have to be passed:
# build_config_name: The name of the build config
# ipa_path: The path of the ipa to upload (relative to home dir)
desc "Deliver the app to TestFlight for testers"
lane :testflight_upload do |options|
apple_auth()
build_config_name = options[:build_config_name]
ipa_path = options[:ipa_path]
if [build_config_name, ipa_path].include?(nil)
raise "'nil' passed as parameter! Aborting..."
end
build_config = read_build_config(build_config_name, 'ios')
apple_id = build_config['appleId']
# https://docs.fastlane.tools/actions/upload_to_testflight/
upload_to_testflight(
skip_waiting_for_build_processing: true,
apple_id: apple_id,
ipa: "#{ENV['HOME']}/#{ipa_path}",
distribute_external: false
)
end
# The following parameters have to be passed:
# build_config_name: The name of the build config
desc "Promote the app from testflight to production in App Store Connect."
lane :appstoreconnect_promote do |options|
apple_auth()
build_config_name = options[:build_config_name]
if [build_config_name].include?(nil)
raise "'nil' passed as parameter! Aborting..."
end
build_config = read_build_config(build_config_name, 'ios')
bundle_identifier = build_config['bundleIdentifier']
skip_screenshots = build_config_name != "integreat"
testflight_build_number = latest_testflight_build_number(app_identifier: bundle_identifier)
testflight_version = lane_context[SharedValues::LATEST_TESTFLIGHT_VERSION]
app_store_build_number = app_store_build_number(app_identifier: bundle_identifier)
if testflight_build_number <= app_store_build_number
puts("Nothing to do, latest version already available in app store connect...")
next
end
puts("promoting #{build_config_name} v#{testflight_version} - #{testflight_build_number} to app store connect")
puts("skip_screenshots: #{skip_screenshots}")
prepare_metadata(version_name: testflight_version, build_config_name: build_config_name)
# https://docs.fastlane.tools/actions/deliver/#submit-build
deliver(
app_version: testflight_version,
build_number: testflight_build_number.to_s,
app_identifier: bundle_identifier,
submit_for_review: true,
automatic_release: true,
force: true,
skip_metadata: false,
skip_screenshots: skip_screenshots,
overwrite_screenshots: true,
skip_binary_upload: true,
metadata_path: "./ios/fastlane/#{build_config_name}/metadata",
screenshots_path: "./ios/fastlane/#{build_config_name}/screenshots",
precheck_include_in_app_purchases: false, # We do not have inapp purchases
submission_information: { add_id_info_uses_idfa: false } # https://firebase.google.com/docs/analytics/configure-data-collection?platform=ios
# https://support.google.com/firebase/answer/6318039?hl=en
)
end
# The following parameters have to be passed:
# build_config_name: The name of the build config
# version_name: The version name of the release notes to prepare
desc "Prepare metadata"
lane :prepare_metadata do |options|
build_config_name = options[:build_config_name]
version_name = options[:version_name]
if [build_config_name, version_name].include?(nil)
raise "'nil' passed as parameter! Aborting..."
end
`yarn --cwd ../../tools manage-metadata prepare-metadata #{build_config_name} appstore --override-version-name #{version_name}`
end
end