Deploy Flutter (iOS) Apps to Testers using Firebase App Distribution with Semaphore

  • An existing Flutter project; you can use our starter app or create one by running flutter create my_app
  • A Firebase account; you can create one here
  • An Apple Developer Account ($99 / year) for the developer certificates and provisioning profiles

Creating a Firebase Project

Authentication with Firebase CLI

npm install -g firebase-tools
firebase login ✔ Success! Logged in as joshua*****@gmail.com

Setting up App Distribution

gem install bundler
brew install fastlane
sudo gem install fastlane

Setting up fastlane with your Flutter iOS project

cd ios && fastlane init && cd -
  1. Select manual setup:
What would you like to use fastlane for? 
1. 📸 Automate screenshots
2. 👩‍✈️ Automate beta distribution to TestFlight
3. 🚀 Automate App Store distribution
4. 🛠 Manual setup - manually setup your project to automate your tasks
>>> 4

Adding the Firebase App Distribution Plugin to Fastlane

fastlane add_plugin firebase_app_distribution
sudo fastlane add_plugin firebase_app_distribution

Setting up Fastfile with Firebase

default_platform(:ios) # Credentials (for later) 
git_authorization = "<GIT_AUTHORIZATION>"
firebase_app_id = "<YOUR_FIREBASE_APP_ID>"
firebase_cli_token = "<YOUR_CLI_TOKEN>"
# Team
team_id = "<YOUR_TEAM_ID>"
platform :ios do
desc "Deploy iOS to Firebase"
lane :deploy do
# add actions here: https://docs.fastlane.tools/actions
end
end
# Keychains 
keychain_user = "temp"
keychain_pass = "temp"
def delete_temp_keychain(name)
delete_keychain(
name: name
) if File.exist? File.expand_path("~/Library/Keychains/#{name}-db") end
def create_temp_keychain(name, password)
create_keychain(
name: name,
password: password,
unlock: false,
timeout: 0
)
end
def ensure_temp_keychain(name, password)
delete_temp_keychain(name)
create_temp_keychain(name, password)
end
platform :ios do   
lane :deploy do
ensure_temp_keychain(keychain_user, keychain_pass)
gym(
scheme: "Runner",
archive_path: "./build/Runner.xcarchive",
export_method: "ad-hoc",
output_directory: "./build/Runner",
)
firebase_app_distribution(
app: firebase_app_id,
firebase_cli_token: firebase_cli_token,
release_notes: "Bug fixes and performance improvements",
groups: "internal",
)
delete_temp_keychain(keychain_user)
end
end
firebase login:ci
✔ Success! Use this token to login on a CI server: 1//0etIq08H_oIB5CgYIARAAGA4SNwF-L9IrgmGb2iadCGcAmqhzK_NH8F8zQBkbPrMS2qtWhMqUmpbVbYK4YzC_83-eHb8NgylEMUg

Setting up fastlane match

fastlane match init
fastlane match supports multiple storage modes, please select the one you want to use: 
1. git
2. google_cloud
3. s3 >>> 1
fastlane match adhoc -a <YOUR_BUNDLE_IDENTIFIER> ... All required keys, certificates and provisioning profiles are installed 🙌
git_authorization = "joshuadeguzman:<YOUR_ACCESS_TOKEN>"
platform :ios do 
lane :deploy do
ensure_temp_keychain(keychain_user, keychain_pass)
# Add this
match(
type: "adhoc",
git_basic_authorization: git_authorization,
)
... (truncated) end
end

Deploying to Firebase using fastlane locally

flutter packages & clean
flutter build ios --no-codesign
cd ios && fastlane deploy && cd -

Setting up a Semaphore project for your app

Setting up blocks to integrate and build your apps

checkout 
cache restore flutter-packages-$SEMAPHORE_GIT_BRANCH-$(checksum pubspec.yaml),flutter-packages-$(checksum pubspec.yaml),flutter-packages
flutter pub get cache store flutter-packages-$SEMAPHORE_GIT_BRANCH-$(checksum pubspec.yaml),flutter-packages-$(checksum pubspec.yaml),flutter-packages /root/.pub-cache
flutter format --set-exit-if-changed .
flutter analyze .
checkout 
cache restore flutter-packages-$SEMAPHORE_GIT_BRANCH-$(checksum pubspec.yaml),flutter-packages-$(checksum pubspec.yaml),flutter-packages
flutter pub get
flutter test test
checkout 
cache restore flutter-packages-$SEMAPHORE_GIT_BRANCH-$(checksum pubspec.yaml),flutter-packages-$(checksum pubspec.yaml),flutter-packages
flutter pub get
checkout 
cache restore flutter-packages-$SEMAPHORE_GIT_BRANCH-$(checksum pubspec.yaml),flutter-packages-$(checksum pubspec.yaml),flutter-packages
flutter pub get
cache store flutter-packages-$SEMAPHORE_GIT_BRANCH-$(checksum pubspec.yaml),flutter-packages-$(checksum pubspec.yaml),flutter-packages /root/.pub-cache
checkout 
cache restore flutter-packages-$SEMAPHORE_GIT_BRANCH-$(checksum pubspec.yaml),flutter-packages-$(checksum pubspec.yaml),flutter-packages sh bump_version.sh
flutter build ios --no-codesign
cd ios
bundle install
cache store
bundle exec fastlane deploy
git fetch --all 
git merge origin/set-up-semaphore
git push origin master

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store