-
-
Save trilliwon/d2bf3ffd53258ffe8213296bf08c823b to your computer and use it in GitHub Desktop.
Sampe Fastlane
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| default_platform :ios | |
| platform :ios do | |
| desc "Send Slack message to channels or threads" | |
| lane :send_slack_message do |options| | |
| require 'slack-ruby-client' | |
| Slack.configure do |config| | |
| config.token = ENV['SLACK_API_TOKEN'] | |
| end | |
| client = Slack::Web::Client.new | |
| slack_channel = options.fetch(:slack_channel, "group_ios_notifications") | |
| slack_thread_ts = options.fetch(:slack_thread_ts, nil) | |
| release_notes = options.fetch(:release_notes, "-") | |
| username = "Rocket" | |
| icon_url = "https://ca.slack-edge.com/T0MB3T0CC-U06GX5MDDT9-e5a25100cce1-512" | |
| # Prepare the blocks for the Slack message | |
| blocks = options.fetch(:blocks, [ | |
| { | |
| "type" => "section", | |
| "text" => { | |
| "type" => "mrkdwn", | |
| "text" => "#{release_notes}" | |
| } | |
| } | |
| ]) | |
| # Send the message to Slack | |
| client.chat_postMessage( | |
| channel: slack_channel, | |
| username: username, | |
| icon_url: icon_url, | |
| thread_ts: slack_thread_ts, | |
| blocks: blocks.to_json | |
| ) | |
| end | |
| desc "Send Text Slack message to channels or threads" | |
| lane :send_text_slack_message do |options| | |
| text = options.fetch(:text, "Rocket is here!") | |
| options[:blocks] = [ | |
| { | |
| "type" => "section", | |
| "text" => { | |
| "type" => "mrkdwn", | |
| "text" => "#{text}" | |
| } | |
| } | |
| ] | |
| send_slack_message(options) | |
| end | |
| desc "Send Firebase deploy Slack message to channels or threads" | |
| lane :send_firebase_deploy_slack_message do |options| | |
| end | |
| desc "Sign app" | |
| private_lane :sign_app do |options| | |
| # fetch appstore connect api key | |
| api_key = app_store_connect_api_key( | |
| key_id: ENV["APPSTORE_CONNECT_KEY_ID"], | |
| issuer_id: ENV["APPSTORE_CONNECT_ISSUER_ID"], | |
| key_content: ENV["APPSTORE_CONNECT_KEY_CONTENT"], | |
| duration: 1200, # optional (maximum 1200) | |
| in_house: false # optional but may be required if using match/sigh | |
| ) | |
| get_certificates( | |
| api_key: api_key, | |
| output_path: "./build/certs" | |
| ) | |
| # for Main App | |
| get_provisioning_profile( | |
| api_key: api_key, | |
| adhoc: options.fetch(:adhoc, true), | |
| app_identifier: "", # app identifier | |
| username: "", # apple id | |
| team_id: "", # apple team id | |
| output_path: "./build/profiles" | |
| ) | |
| # for Widget | |
| get_provisioning_profile( | |
| api_key: api_key, | |
| adhoc: options.fetch(:adhoc, true), | |
| app_identifier: "", # app identifier | |
| username: "", # apple id | |
| team_id: "", # apple team id | |
| output_path: "./build/profiles" | |
| ) | |
| # last line will retrun value | |
| api_key | |
| end | |
| desc "Build app" | |
| lane :build do |options| | |
| # sign_app | |
| sign_app | |
| # set build configuration | |
| # check the available build configurations or set default value | |
| scheme = options.fetch(:scheme, "APP_NAME") | |
| export_method = options.fetch(:export_method, "ad-hoc") | |
| export_options = options.fetch(:export_options, { signingStyle: "manual" }) | |
| clean = options.fetch(:clean, true) | |
| output_directory = options.fetch(:output_directory, "./build") | |
| # build | |
| gym( | |
| scheme: scheme, | |
| export_method: export_method, | |
| export_options: export_options, | |
| clean: clean, | |
| output_directory: output_directory, | |
| ) | |
| end | |
| desc "Test app" | |
| lane :test do | |
| scan( | |
| workspace: "APP_NAME.xcworkspace", # workspace name | |
| configuration: 'Debug', # build configuration | |
| devices: ["iPhone 15"], # devices | |
| scheme: "APP_NAME", # scheme name | |
| testplan: "All", # testplan name | |
| clean: true, # clean | |
| code_coverage: true, # code coverage | |
| slack_url: ENV["SLACK_WEBHOOK_URL"], # slack webhook url | |
| slack_channel: "#group_ios_notifications" # default slack channel | |
| ) | |
| end | |
| desc "Clean up all the build outputs" | |
| private_lane :clean_up do | |
| # clean up | |
| sh("pwd && ls -al") | |
| sh("rm -rf ./build") | |
| end | |
| before_all do | |
| puts "---" | |
| end | |
| desc "Deliver metadata of a new version to the iTunes connect" | |
| lane :deliver_metadata do | |
| # sign_app | |
| sign_app(adhoc: false) | |
| deliver( | |
| force: false, | |
| precheck_include_in_app_purchases: false | |
| ) | |
| # clean up | |
| clean_up | |
| end | |
| desc "Increase the build number" | |
| lane :increase_build_number do |options| | |
| api_key = options.fetch(:api_key, nil) | |
| build_num = latest_testflight_build_number( | |
| api_key: api_key | |
| ) | |
| increment_build_number( | |
| build_number: build_num + 1, | |
| xcodeproj: "./Modules/APP_NAME/APP_NAME.xcodeproj" | |
| ) | |
| end | |
| desc "firebase_app_distribution" | |
| lane :deploy_firebase do |options| | |
| begin | |
| build_number = Time.now.strftime("#{Time.now.month}%d%H%M") | |
| increment_build_number( | |
| build_number: build_number, | |
| xcodeproj: "./Modules/APP_NAME/APP_NAME.xcodeproj" | |
| ) | |
| version_number = get_version_number( | |
| xcodeproj: "./Modules/APP_NAME/APP_NAME.xcodeproj", | |
| target: "APP_NAME" | |
| ) | |
| options[:text] = "π *λΉλ μμ! Version: #{version_number}(#{build_number})*" | |
| send_text_slack_message(options) | |
| # build | |
| build( | |
| scheme: "APP_NAME", | |
| export_method: "ad-hoc", | |
| export_options: { signingStyle: "manual" }, | |
| ) | |
| options[:text] = "β λΉλ μλ£! Firebase μ λ‘λ μμ" | |
| send_text_slack_message(options) | |
| last_commit = last_git_commit | |
| author_email = last_commit[:author_email] | |
| abbreviated_commit_hash = last_commit[:abbreviated_commit_hash] | |
| branch_name = git_branch | |
| commit_author = last_commit[:author] | |
| release_notes = options.fetch(:release_notes, "New build uploaded to Firebase") | |
| firebase_app_distribution( | |
| app: ENV["GOOGLE_APP_ID"], | |
| service_credentials_file: "fastlane/service_credentials_file.json", | |
| ipa_path: "build/APP_NAME.ipa", | |
| groups: "delightroom, ios-group, po-group, design-group, upo-group, shared-tester", | |
| release_notes: "#{release_notes}\n\nBranch: #{branch_name}\nAuthor: #{commit_author}" | |
| ) | |
| upload_symbols_to_crashlytics(dsym_path: "build/APP_NAME.app.dSYM.zip") | |
| firebase_release_info = lane_context[SharedValues::FIREBASE_APP_DISTRO_RELEASE] | |
| testingUri = firebase_release_info[:testingUri] | |
| buildVersion = firebase_release_info[:buildVersion] | |
| displayVersion = firebase_release_info[:displayVersion] | |
| options[:blocks] = [ | |
| { | |
| "type" => "section", | |
| "text" => { | |
| "type" => "mrkdwn", | |
| "text" => "Successfully deployed to Firebase!" | |
| } | |
| }, | |
| { | |
| "type" => "section", | |
| "text" => { | |
| "type" => "mrkdwn", | |
| "text" => "<#{testingUri}|iOS Firebase #{displayVersion}(#{buildVersion})>" | |
| } | |
| }, | |
| { | |
| "type" => "section", | |
| "text" => { | |
| "type" => "mrkdwn", | |
| "text" => "Version: *#{displayVersion}(#{buildVersion})*" | |
| } | |
| }, | |
| { | |
| "type" => "section", | |
| "text" => { | |
| "type" => "mrkdwn", | |
| "text" => "Last Commit: \`#{abbreviated_commit_hash}\` by \`#{author_email}\`" | |
| } | |
| } | |
| ] | |
| send_slack_message(options) | |
| options[:slack_channel] = options.fetch(:share_slack_channel, "group_ios_notifications") | |
| options[:slack_thread_ts] = nil | |
| options[:blocks] = [ | |
| { | |
| "type" => "section", | |
| "text" => { | |
| "type" => "mrkdwn", | |
| "text" => "<#{testingUri}|iOS Firebase #{displayVersion}(#{buildVersion})>" | |
| } | |
| }, | |
| { | |
| "type" => "section", | |
| "text" => { | |
| "type" => "mrkdwn", | |
| "text" => "#{release_notes}" | |
| } | |
| } | |
| ] | |
| send_slack_message(options) | |
| rescue => e | |
| options[:text] = "μλ¬ λ°μ: #{e}" | |
| send_text_slack_message(options) | |
| raise | |
| end | |
| # clean up | |
| clean_up | |
| end | |
| desc "Deploy to Testflight" | |
| lane :deploy_testflight do |options| | |
| begin | |
| last_commit = last_git_commit | |
| author_email = last_commit[:author_email] | |
| branch_name = git_branch | |
| release_notes = options.fetch(:release_notes, "New features and bug fixes") | |
| groups = options.fetch(:groups, "members").strip.split(',').collect(&:strip) | |
| # sign_app | |
| api_key = sign_app(adhoc: false) | |
| increase_build_number(api_key: api_key) | |
| build_number = get_build_number( | |
| xcodeproj: "./Modules/APP_NAME/APP_NAME.xcodeproj" | |
| ) | |
| version_number = get_version_number( | |
| xcodeproj: "./Modules/APP_NAME/APP_NAME.xcodeproj", | |
| target: "APP_NAME" | |
| ) | |
| options[:text] = "π *λΉλ μμ! Version: #{version_number}(#{build_number})*" | |
| send_text_slack_message(options) | |
| build_app( | |
| scheme: "APP_NAME", | |
| export_method: "app-store", | |
| clean: true, | |
| export_options: { | |
| provisioningProfiles: { | |
| "APP_NAME" => "match AppStore APP_NAME", | |
| "APP_NAME.Widget" => "match AppStore APP_NAME.Widget" | |
| } | |
| } | |
| ) | |
| options[:text] = "β λΉλ μλ£! TestFlight μ λ‘λ μμ" | |
| send_text_slack_message(options) | |
| upload_to_testflight( | |
| beta_app_review_info: { | |
| contact_email: "", # contact email | |
| contact_first_name: "", # contact first name | |
| contact_last_name: "", # contact last name | |
| contact_phone: "", # contact phone | |
| notes: "Thanks for reviewing :)" | |
| }, | |
| api_key: api_key, | |
| distribute_external: true, | |
| groups: groups, | |
| submit_beta_review: true, | |
| changelog: "#{release_notes}\nBranch: #{branch_name}\nAuthor: #{author_email}" | |
| ) | |
| testflight_link = "<https://testflight.apple.com/v1/app/1111111111|Testflight #{version_number}(#{build_number})>" | |
| options[:text] = "β Successfully uploaded to TestFlight!\n#{testflight_link}" | |
| send_text_slack_message(options) | |
| options[:slack_channel] = options.fetch(:share_slack_channel, "group_ios_notifications") | |
| options[:slack_thread_ts] = nil | |
| options[:blocks] = [ | |
| { | |
| "type" => "section", | |
| "text" => { | |
| "type" => "mrkdwn", | |
| "text" => "#{testflight_link}" | |
| } | |
| }, | |
| { | |
| "type" => "section", | |
| "text" => { | |
| "type" => "mrkdwn", | |
| "text" => "#{release_notes}" | |
| } | |
| } | |
| ] | |
| send_slack_message(options) | |
| rescue => e | |
| options[:text] = "μλ¬ λ°μ: #{e}" | |
| send_text_slack_message(options) | |
| raise | |
| end | |
| clean_up | |
| end | |
| desc "Deploy a new version to the App Store" | |
| lane :release do |options| | |
| begin | |
| api_key = sign_app(adhoc: false) | |
| increase_build_number(api_key: api_key) | |
| build_number = get_build_number( | |
| xcodeproj: "./Modules/APP_NAME/APP_NAME.xcodeproj" | |
| ) | |
| version_number = get_version_number( | |
| xcodeproj: "./Modules/APP_NAME/APP_NAME.xcodeproj", | |
| target: "APP_NAME" | |
| ) | |
| options[:text] = "π *λΉλ μμ! Version: #{version_number}(#{build_number})*" | |
| send_text_slack_message(options) | |
| build_app( | |
| scheme: "APP_NAME", | |
| export_method: "app-store", | |
| clean: true, | |
| export_options: { | |
| provisioningProfiles: { | |
| "APP_NAME" => "match AppStore APP_NAME", | |
| "APP_NAME.Widget" => "match AppStore APP_NAME.Widget" | |
| } | |
| } | |
| ) | |
| options[:text] = "β λΉλ μλ£! AppStore μ λ‘λ μμ" | |
| send_text_slack_message(options) | |
| upload_to_app_store( # Upload to App Store | |
| force: true, | |
| submit_for_review: true, | |
| automatic_release: true, | |
| phased_release: true, | |
| skip_binary_upload: false, | |
| skip_screenshots: true, | |
| skip_metadata: false, | |
| precheck_include_in_app_purchases: false, | |
| skip_app_version_update: false, | |
| metadata_path: "./fastlane/metadata", | |
| submission_information: { | |
| add_id_info_uses_idfa: false, | |
| }, | |
| api_key: api_key | |
| ) | |
| options[:text] = "β Successfully uploaded to AppStore! *Version: #{version_number}(#{build_number})*" | |
| send_text_slack_message(options) | |
| rescue => e | |
| options[:text] = "μλ¬ λ°μ: #{e}" | |
| send_text_slack_message(options) | |
| raise | |
| end | |
| # clean up | |
| clean_up | |
| end | |
| desc "Deliver metadata" | |
| lane :upload_metadata do |options| | |
| begin | |
| api_key = sign_app(adhoc: false) | |
| upload_to_app_store( # Upload to App Store | |
| force: true, | |
| submit_for_review: false, | |
| phased_release: true, | |
| skip_binary_upload: true, | |
| skip_screenshots: true, | |
| skip_metadata: false, | |
| precheck_include_in_app_purchases: false, | |
| skip_app_version_update: true, | |
| metadata_path: "./fastlane/metadata", | |
| api_key: api_key | |
| ) | |
| rescue => e | |
| options[:text] = "μλ¬ λ°μ: #{e}" | |
| send_text_slack_message(options) | |
| raise | |
| end | |
| # clean up | |
| clean_up | |
| end | |
| desc "Deliver screenshots to the iTunes connect" | |
| lane :deliver_screenshots do | |
| # sign_app | |
| sign_app | |
| deliver( | |
| force: false, | |
| skip_binary_upload: true, | |
| skip_metadata: true, | |
| skip_screenshots: false | |
| ) | |
| # clean up | |
| clean_up | |
| end | |
| # You can define as many lanes as you want | |
| after_all do |lane| | |
| puts "Successfully deployed new App Update." | |
| end | |
| error do |lane, exception| | |
| slack( | |
| message: "Exception from `#{exception.class}`: `#{exception.message}`", | |
| slack_url: ENV["SLACK_WEBHOOK_URL"], | |
| success: false | |
| ) | |
| UI.error("Exception from `#{exception.class}`: `#{exception.message}`") | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment