dev-resources.site
for different kinds of informations.
Building and Deploying Flutter Apps from CI with Fastlane: How to Reuse Code Efficiently
Published at
5/27/2021
Categories
flutter
ios
fastlane
android
Author
danielgomezrico
Author
15 person written this
danielgomezrico
open
We use fastlane
for our flutter apps, for ios and android builds, it give us a common language to define the setup and reuse code for:
- Generating a changelog based on our changelog style
- Validate code style, formatting and lint
- Unit testing
- Verify that the project autogenerated code is been built fine.
- Verify that the project builds fine for each platform.
- Deploy to firebase app distribution for testing
- Deploying to each app store
There are some tricks to be able to do it:
- Create a parent
fastfile
where you have the reusable logic and one for each platformios/fastfile
andandroid/fastfile
. - Have an easy way to run tasks from the root of the project, our idea was to create a lane
sh_on_root
to run all flutter commands from each platformfastfile
. - Create a
Gemfile
for each platform and define.ruby-version
file to have a defined environment to run, helping us to avoid problems on CI server requiring some specific ruby version to run fastlane in there.
Another thing we noticed is that using --no-pub --suppress-analytics
params from flutter commands saved us some time on CI if you want to try that's a good start.
I will show an example of some usefull lanes and some workflows for them, you should think about your needs and call the lanes you need for each step but try to reuse for each platform some tasks having the parent fastfile
file.
Show me the setup
- Create the
Gemfile
for each platform android/Gemfile
ios/Gemfile
Contents:
source "https://rubygems.org"
gem 'cocoapods'
gem "fastlane"
plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
eval_gemfile(plugins_path) if File.exist?(plugins_path)
- Create the
.ruby-version
so the CI (in our case Bitrise) have a clue of which ruby version should be used ios/.ruby-version
android/.ruby-version
Contents:
2.6.5
- Create 3 fastlane files, 1 to be reused by each platform, and 1 for each platform (check that from each platform fastlane we import the parent one with
import "../../scripts/Fastfile"
)
-
fastfile
:
opt_out_usage
# Have an easy way to get the root of the project
def root_path
Dir.pwd.sub(/.*\Kfastlane/, '').sub(/.*\Kandroid/, '').sub(/.*\Kios/, '').sub(/.*\K\/\//, '')
end
# Have an easy way to run flutter tasks on the root of the project
lane :sh_on_root do |options|
command = options[:command]
sh("cd #{root_path} && #{command}")
end
# Tasks to be reused on each platform flow
lane :fetch_dependencies do
sh_on_root(command: "flutter pub get --suppress-analytics")
end
# Tasks to be reused on each platform flow
lane :build_autogenerated_code do
sh_on_root(command: "flutter pub run intl_utils:generate && flutter pub run build_runner build --delete-conflicting-outputs")
end
# Tasks to be reused on each platform flow
lane :lint do
sh_on_root(command: "flutter format --suppress-analytics --set-exit-if-changed -n lib/main.dart lib/src/ test/")
end
# Tasks to be reused on each platform flow
lane :test do |options|
sh_on_root(command: "flutter test --no-pub --coverage --suppress-analytics")
end
-
ios/fastfile
:
import "../../scripts/Fastfile"
default_platform(:ios)
platform :ios do
# Updates XCode project settings to use a different code signing based on method
private_lane :archive do |options|
method = options[:method]
profile_name = method == 'ad-hoc' ? "Distribution - Staging (adhoc)" : "Production"
update_code_signing_settings(profile_name: profile_name)
build_app(export_method: method)
end
private_lane :authenticate_apple_store do
p8_path = path_for_secret("your .p8 file path")
app_store_connect_api_key(
key_id: "your key id",
issuer_id: "your used id",
key_filepath: p8_path,
duration: 1200, # optional
in_house: false,
)
end
lane :build do |options|
# Reuse parent fastfile tasks
fetch_dependencies
build_autogenerated_code
sign_enabled = options[:sign_enabled] || false
sign_param = sign_enabled ? '' : '--no-codesign'
config_only = options[:config_only] || false
config_param = config_only ? '--config-only' : ''
sh_on_root(command: "flutter build ios --no-pub --suppress-analytics --release #{sign_param} #{config_param}")
end
lane :deploy_staging do
build(sign_enabled: true)
archive(method: "ad-hoc")
upload_symbols_to_crashlytics(dsym_path: "your.app.dSYM.zip")
firebase_app_distribution(
app: "yours app id from firebase",
ipa_path: "your.ipa",
groups: "developers, staging",
release_notes: changelog
)
end
lane :deploy_staging_testflight do
build(sign_enabled: true)
archive(method: "app-store")
authenticate_apple_store
# Reuse parent fastfile tasks
test
upload_to_testflight(
ipa: "your.ipa",
reject_build_waiting_for_review: true,
skip_waiting_for_build_processing: false,
distribute_external: true,
notify_external_testers: true,
groups: "Your testers"
)
end
lane :deploy_production do
# All certificates and .p8 file should be fine on runnning machine
build(sign_enabled: true, config_only: true)
archive(method: "app-store")
authenticate_apple_store
# Reuse parent fastfile tasks
test
deliver(
ipa: "your.ipa",
skip_metadata: true,
skip_screenshots: true,
submit_for_review: false,
force: false,
automatic_release: false,
submission_information: {
add_id_info_serves_ads: false,
add_id_info_uses_idfa: false,
export_compliance_uses_encryption: false,
},
precheck_include_in_app_purchases: false,
)
end
end
-
android/fastfile
import "../../scripts/Fastfile"
default_platform(:android)
platform :android do
private_lane :build_apk do
# Reuse parent fastfile tasks
fetch_dependencies
build_autogenerated_code
sh_on_root(command: "flutter build apk --release")
end
lane :build do
# Reuse parent fastfile tasks
fetch_dependencies
build_autogenerated_code
sh_on_root(command: "flutter build appbundle --no-pub --release --suppress-analytics")
end
lane :deploy_staging do
build_apk
# Reuse parent fastfile tasks
test
firebase_app_distribution(
app: "your app id",
groups: "your testers",
android_artifact_type: "APK",
android_artifact_path: "#{root_path}/build/app/outputs/flutter-apk/app-release.apk",
firebase_cli_path: "/usr/local/bin/firebase"
)
end
lane :deploy_production do
build
# Reuse parent fastfile tasks
test
supply(
track: 'beta',
aab: "../build/app/outputs/bundle/release/app-release.aab",
json_key: path_for_secret("your play store.json"),
skip_upload_apk: true, # Upload the aab instead of apk
skip_upload_metadata: true,
skip_upload_changelogs: true,
skip_upload_images: true,
skip_upload_screenshots: true
)
end
end
fastlane Article's
30 articles in total
From days to minutes: Build and publish React Native apps using Fastlane and Github Actions
read article
[Boost]
read article
The Ultimate Guide to Automating Android APK Builds and Firebase Distribution with Fastlane 🚀
read article
From Manual to Automatic: The Magic of CI/CD Pipelines! 🤯
read article
Protegendo credenciais em automatização de builds no Fastlane com Variáveis de Ambiente
read article
GUI for fastlane?
read article
Steps to Add and Upload testflight Using Fastlane
read article
Simplifying Flutter Deployment with FastLane
read article
🚀 Added new YouTube series on "Flutter CI/CD with GitLab and Fastlane" !
read article
Automate publishing your android app to Google Play Store with Fastlane and Github Actions
read article
GitHub Actions CI/CD for Flutter Fastlane (iOS) with possible mistakes
read article
Criando uma conta e configurando um projeto no CodeMagic
read article
Automatically add new devices to the Apple Developer Portal (GitHub Actions & Fastlane)
read article
Fastlane: æ·±å…¥æµ…å‡ºä¸€çœ‹ä½ å°±æ‡‚
read article
Fastlane: iOS 和 Android 的自动化构建工具
read article
Fastlane with React Native — Part-1
read article
Deploy iOS Application to AppCenter via Github Actions (Manual Code SignIn)
read article
Single point versioning with Fastlane for React Native
read article
Unable to use Fastlane on macOS Monterey 12.1
read article
Automating Flutter App Versioning Using Fastlane Plugin
read article
How To Automate App Releases using Fastlane and SemVer for Hybrid Applications
read article
Building and Deploying Flutter Apps from CI with Fastlane: How to Reuse Code Efficiently
currently reading
How to run Fastlane and GitLab with AppStore Connect API
read article
Automating mobile application deployments using Fastlane and CI/CD tools
read article
React Native e2e tests and Automatic Deploys (Detox + Fastlane + CircleCI)
read article
Deploy React Native app on Playstore with Fastlane and Github Actions ( 1 / 2 )
read article
Deploy React Native app on Playstore with Fastlane and Github Actions ( 2 / 2 )
read article
CI/CD in iOS Development
read article
Como configurar Fastlane para Firebase App Distribution (Android e iOS)
read article
Flutter + Fastlane + Github Actions
read article
Featured ones: