require "shellwords" default_platform(:ios) IOS_KEY_PATH = File.expand_path("../ios/AuthKey_84F695CDQ3.p8") IOS_OUTPUT_DIR = File.expand_path("../build/ios") ANDROID_PROJECT_DIR = File.expand_path("../android") PLAY_JSON_KEY_PATH = File.expand_path("../android/play-service-account.json") platform :ios do desc "Build a signed, App Store-ready .ipa" lane :release do Dir.chdir(File.expand_path("../ios/App")) do Bundler.with_clean_env do sh("pod install --repo-update") end end build_app( workspace: "ios/App/App.xcworkspace", scheme: "App", export_method: "app-store", output_directory: IOS_OUTPUT_DIR, output_name: "Donetick.ipa", export_options: { signingStyle: "manual", provisioningProfiles: { "com.donetick.app" => "Donetick App Store(fastline)", "com.donetick.app.widget" => "Donetick Widget App Store(fastline)", }, }, ) UI.success("Signed .ipa at #{IOS_OUTPUT_DIR}/Donetick.ipa") end desc "Upload the built .ipa to TestFlight" lane :upload do UI.user_error!("Missing #{IOS_KEY_PATH} — run scripts/pull-secrets.sh first") unless File.exist?(IOS_KEY_PATH) UI.user_error!("ASC_ISSUER_ID is not set (App Store Connect API key issuer id)") if ENV["ASC_ISSUER_ID"].to_s.empty? ipa_path = File.join(IOS_OUTPUT_DIR, "Donetick.ipa") UI.user_error!("Missing #{ipa_path} — run `fastlane ios release` first") unless File.exist?(ipa_path) api_key = app_store_connect_api_key( key_id: ENV["ASC_KEY_ID"] || "84F695CDQ3", issuer_id: ENV["ASC_ISSUER_ID"], key_filepath: IOS_KEY_PATH, duration: 1200, in_house: false, ) upload_to_testflight( api_key: api_key, ipa: ipa_path, skip_waiting_for_build_processing: true, skip_submission: true, ) UI.success("Uploaded to TestFlight") end end platform :android do desc "Build a signed release .aab" lane :release do keystore_properties = File.join(ANDROID_PROJECT_DIR, "keystore.properties") UI.user_error!("Missing #{keystore_properties} — run scripts/pull-secrets.sh first") unless File.exist?(keystore_properties) gradle( task: "bundle", build_type: "Release", project_dir: "#{ANDROID_PROJECT_DIR}/", ) aab_path = lane_context[SharedValues::GRADLE_AAB_OUTPUT_PATH] UI.success("Signed .aab at #{aab_path}") end desc "Build a signed release .apk (for sideloading/testing)" lane :apk do keystore_properties = File.join(ANDROID_PROJECT_DIR, "keystore.properties") UI.user_error!("Missing #{keystore_properties} — run scripts/pull-secrets.sh first") unless File.exist?(keystore_properties) gradle( task: "assemble", build_type: "Release", project_dir: "#{ANDROID_PROJECT_DIR}/", ) apk_path = lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] UI.success("Signed .apk at #{apk_path}") end desc "Upload the built .aab to the Play Store (internal testing track by default)" lane :upload do |options| UI.user_error!("Missing #{PLAY_JSON_KEY_PATH} — run scripts/pull-secrets.sh first") unless File.exist?(PLAY_JSON_KEY_PATH) aab_path = File.join(ANDROID_PROJECT_DIR, "app/build/outputs/bundle/release/app-release.aab") UI.user_error!("Missing #{aab_path} — run `fastlane android release` first") unless File.exist?(aab_path) upload_to_play_store( json_key: PLAY_JSON_KEY_PATH, package_name: "com.donetick.app", aab: aab_path, track: options[:track] || "internal", skip_upload_metadata: true, skip_upload_images: true, skip_upload_screenshots: true, ) UI.success("Uploaded to Play Store (#{options[:track] || 'internal'} track)") end end