The Developer Needs to Upload a Build for This Distribution Fastlane
App developers always strive to improve the product they are working on. So information technology is definite that either(mostly) you will be adding new features to existing products or (luckily) you will be setting up a whole new projection. Either mode, onboarding new developers or bootstrapping an entirely new projection is a pretty challenging task. If not executed advisedly, technical debt arises and headaches for developers, managers, sales people, and well-nigh chiefly, clients.
Git-menstruum: A quick overview
Git flow is reasonably used in Active as well every bit conventional Waterfall-based projects as well.
Before we start our thought process nigh implementing Continous Integration and Continous Delivery, information technology is crucial to decide your own git branching model. It should resemble your development workflow to make use of CI/CD tools.
Git branching model
This article is focused on mobile applications. Therefore, nosotros volition utilise the following git branching model for which serves the purpose as an example.
Git flow is essentially a merge base solution. It does non rebase the branch. As well, keeping tag proper name format vX.Y.Z-beta-N
helps to generate a changelog using automated utilities.
Neither Github-period nor Git-period in its purest class can aid u.s.a. adopt a resilient development workflow. The modern tendency of Github usually seems to be having at least two branches, develop
and primary
where develop
branch is always nether active development and principal
are belongings the latest tagged releases at whatever given fourth dimension.
Git-flow(with GitHub-period tweaks) will help us come to a concrete solution for CI and CD. Of course, depending on your team sizes, yous may have a different menses, but that flow should too be resembling the above-mentioned Git Branching Model.
Implementing Continous Integration & Commitment
By definition, an automatic process or practice employed by software developers collaborating on a single software project of integrating lawmaking changes on the shared repository. This automation process may be composed of steps similar testing lawmaking, packaging, and delivering and deployment to production.
During product development, developers have frequently been requested to requite a new IPA file or APK file to the QA squad or the customer for checking and testing the features. Extending your workflow with CI/CD for unit-testing, distributing your binary tin can significantly reduce your off-development burden.
Advantages of CI/CD
CI/CD combined with git-catamenia gives many benefits such every bit the following:
- Saves programmer time by sending automated builds to testing teams
- Removes probability of inconsistency in builds(mainly caused due to local caching) by the guaranteed pristine build
- Takes team engagement to the next level by encouraging open up communication and free information flow
- Reduces programmer dependency by promoting knowledge sharing amid team members
- Improves programmer confidence when merging code
- Helps eliminate a class of bugs that might occur due to transmission treatment
At that place could exist de-merits of employing CI in a small team or individual developer adding overheads. However, for developers working on multiple projects with many people, CI is a wise investment with very high returns in terms of time and money.
Fastlane
Fastlane is recommended to implement CI/CD. Historically it became a function of Cloth in 2015, after acquired by Google in 2017. Withal, depending on the squad skills, you lot may implement the solution on some scripting languages like Shell Script
, Cherry-red
, Python
etc. The community of Fastlane is vibrant, and you will notice a lot of open up-source plugins for your concern use case.
Nosotros have chosen Fastlane tools for implementing our CI/CD Solutions. It does require some knowledge of Reddish however, you don't need to be an adept to piece of work with it since information technology is implemented using Ruddy-similar to widely used iOS dependency manager CocoaPods. (+ane to Gradle
for its built-in dependency management function for Android)
Manufactures on how to get started with Fastlane can exist establish here. There is reasonably practiced documentation for both iOS and Android. Nevertheless, we had difficulties finding some details related to Android Fastlane actions though we could search on forums like StackOverflow
.
Modeling Git Branching Model to Fastlane
Ordinarily, each major branches in our Git Branching Model correspond to an environment equally shown in the table below:
Environs | Alias/Tag | Branch | Description |
---|---|---|---|
Development | alpha | develop | All the features for side by side or distant releases are ordinarily developed in this environment |
Staging | beta | release/ or hotfix/ | Pre-release surround |
Product | prod | master | Build made on primary always uses this environment |
More complex flows may accept boosted layers of environment separation. For example, we can categorize our environment in the post-obit equally a lane
(a.k.a Ruby function):
# Fastfile ALIAS_MAP = { 'alpha' => 'Develop', 'beta' => 'Staging', 'prod'=> 'Product' } ... desc 'Build alpha IPA' lane :blastoff do |options| build_app # This volition be replaced with custom `build_deploy` private lane later end desc 'Build beta IPA' lane :beta do |options| build_app # This will be replaced with custom `build_deploy` private lane subsequently end desc 'Build production ipa' lane :prod do |options| build_app # This will be replaced with custom `build_deploy` private lane afterward stop ...
Listing ane
ℹ️We may utilise lane options
parameters to pass command line arguments from CI YAML file.
Y'all tin can put some configuration of build_app
action into Gymfile
per lane
basis every bit shown below:
# Gymfile for_platform :ios do include_bitcode true include_symbols true for_lane :alpha do scheme '<YOUR_DEV_SCHEME>' export_method 'evolution' # or 'enterprise' for in-business firm testing cease for_lane :beta do scheme '<YOUR_STAGING_SCHEME>' export_method 'advertisement-hoc' finish for_lane :prod exercise scheme '<YOUR_PRODUCTION_SCHEME>' export_method 'app-shop' # or 'enterprise' for release cease end
Listing 2
For available configuration options for Gymfile
follow the link here.
After putting above lawmaking from Listing 2 in a Gymfile
, you don't need to pass relavant settings similar scheme
and export_method
into build_app
action like below:
# You don't need to gear up parameters marked with 👈 # since it is handled in Gym file build_app( scheme: "Release", # 👈 export_options: { # 👈 method: "app-store" # 👈 } )
Listing three
ℹ️Note: We will use xcconfig to set bundle id
and provisioning contour
unlike Listing three
Firebase App Distribution
To distribute the congenital IPA binary to Firebase, Reading this document on how to setup Firebase App Distribution is highly recommended.
In Listing 1, we used build_app
action to trigger the build. We can motility that activeness into a private_lane
called build_deploy
and salve duplicate code into these three principal lanes. (Cheque List 7 at the end for farther clarification)
desc 'Build and deploy ipa' private_lane :build_deploy practice |options| #1. Bank check if any new commits since concluding release is_releasable = analyze_commits(match: "*#{options[:environment]}*") unless is_releasable UI.of import "No changes since last one hence skipping build" next terminate #ii. Increment build number increment_build_number( build_number: lane_context[SharedValues::RELEASE_NEXT_VERSION] # set a specific number ) #3. If y'all can use `match`, you use `friction match`. setup_provisioning_profiles #iv. Build deploy build_app deploy_app options cease
List 4
Pace ane. Check if whatsoever new commits since the final release
analyze_commits
is a third-party action for semantic release only quite helpful if y'all follow conventional commits. Information technology lets us cheque if in that location has been any alter since the last release. If there is then we go further otherwise stop with a bulletin-"No changes since the final one hence skipping build". This will help united states of america save some build minutes on the CI motorcar.
Step 2. Increment build number
We tin can keep the Marketing Version and Internal Build Version split. For example, if the Xcode project has AGV tooling enabled, we can use increment_build_number
, which will automatically change the build number in the target.
Step 3. Setup Provisioning Profiles
Nosotros can use the Fastlane match
command hither. In case if we don't have access, nosotros may need to install it manually using import_certificate
first and and so performing FastlaneCore::ProvisioningProfile.install
.
Step 4. Build and deploy
We use build_app
action every bit nosotros used in Listing 1. After the IPA file is gear up we have to send it to Firebase App Distribution using deploy_app
a private lane.
Deploying
We deploy to Firebase for blastoff
and beta
only. For prod
upload either we manually upload to App Store Connect or automate information technology using upload_to_testflight
action. We will limit our word to upload prod
IPA as an asset on Github Release only.
The deploy_app
lane is also self-explanatory as shown in the listing beneath. We tin separate the process in 5 steps:
private_lane :deploy_app exercise |options| environment = options[:environment] next if environment == 'prod' # Since `prod` is uploaded to testflight and app store #1. Generate Alter Log notes = conventional_changelog(title: "Modify Log", format: "plain") #2. Get Google App ID gsp_path = "SupportingFiles/GoogleService/#{ALIAS_MAP[surround]}-Info.plist" google_app_id = get_info_plist_value(path: gsp_path, key: 'GOOGLE_APP_ID') #3. Upload to firebase firebase_app_distribution( app: google_app_id, # groups: tester_group, release_notes: notes, firebase_cli_path: FIREBASE_CLI_PATH ) #four. Upload dSYM files to crashlytics upload_symbols_to_crashlytics(gsp_path: gsp_path) clean_build_artifacts end
List 5
Step 1. Generating Alter Log:
Nosotros are using the semantic-version
plug-in of Fastlane to generate these logs. conventional_changelog
has to exist used in conjunction with analyze_commits
(which we have used in build_deploy
lane to bank check is_releasable
). analyze_commits
takes match
argument-a regex for matching with the previous git-tag like v1.0.ane-beta-5
. This helps to generate logs for only between the last tag and electric current v1.0.1-beta-6
.
Step two. Get Google App ID
Nosotros need google_app_id
from the relevant GoogleService-Info.plist. This Plist is generated on Firebase. Our sample code project is a multi-configuration single target Xcode project. Three GoogleService plists are renamed and moved to GoogleService
folder:
- GoogleService/Develop-Info.plist
- GoogleService/Staging-Info.plist
- GoogleService/Product-Info.plist
We get gsp_path
outset and from that we get google_app_id
.
Stride 3. Upload to firebase
To use this plugin we have to install firebase CLI as well. On CircleCI inside setup
control nosotros have installed npm package for firebase-cli
. firebase_app_distribution
is nothing only a wrapper to use the CLI to upload to Firebase. We need to requite firebase_cli_path
so that the appropriate binary is used.
Step 4. Upload dSYM files to crashlytics
Finally we upload dSYM
files to Firebase. This volition help Firebase brand crash reports de-symbolized and readable.
Note: When bitcode is enabled in an Xcode project, App Store recompiles the code and provides us with dSYM files. These files need to exist downloaded and uploaded to Firebase Crashlytics for crash report de-symbolization. Therefore, for the product version only we need to perform this stride. checkout download_dsym
action for Fastlane.
Github Release
release_on_github
is a individual lane and helps us automatically tag the commit, add release notes and attach IPA file for production, which tin can be later uploaded to App Store Connect.
Since Firebase doesn't accept APIs to download the IPA file except from installing information technology on device only-in case where you may want to requite beta
releases to the client using other distribution like deploygate
-You may desire to go on the IPA as a pre-release in Github release history.
Uploading IPA as an nugget
desc "Release on github" private_lane :release_on_github practice |options| environs = options[:environment] #1. Generate Change Log notes = conventional_changelog(title: "Change Log") #ii. Get Version and Build Number version_number = get_version_number build_number = get_build_number #three. Set Github Release is_prerelease = environment == 'beta' ? true : false proper name = "[#{ALIAS_MAP[surroundings]}] v#{version_number} Build: #{build_number}}" set_github_release( repository_name: "#{ENV['CIRCLE_PROJECT_USERNAME']}/#{ENV['CIRCLE_PROJECT_REPONAME']}", name: name, commitish: ENV['CIRCLE_SHA1'], clarification: notes, tag_name: "5#{version_number}-#{options[:surround]}-#{build_number}", is_prerelease: is_prerelease, upload_assets: [lane_context[SharedValues::IPA_OUTPUT_PATH]] ) end
Listing 6
Step 1. Generate Change Log
conventional_changelog
generates by default mark-downwards way notes. This is handy when preparing motorcar-release notes.
Step 2. Get Version and Build Number
We use these to set up the title of the release. AGV tooling should be enabled in the XCode project to utilise get_version_number
and get_build_number
.
Pace 3. Set Github Release
We cheque if its beta so marks it as Pre-Release. Based on the environment we format the proper name/ title for the release notes. Set the tag name in a format like v1.0.ane-beta-1234
and upload the congenital IPA file every bit an nugget to the release.
Notation: Y'all will need to set up your personal token or ci bot token to GITHUB_API_TOKEN
in the environs. This token should have permission to create a tag.
Revising Main Lanes in List 1
We will skip the alpha
releases on Github because they are quite frequent in releases and stored on the Firebase. Hence, y'all can salvage some infinite on Github by not tagging them and causing it hard to navigate release history on Github.
# Fastfile ALIAS_MAP = { 'alpha' => 'Develop', 'beta' => 'Staging', 'prod'=> 'Production' } ... desc 'Build alpha IPA' lane :alpha do |options| build_deploy options # Not releasing to Github since Firebase App Distribution end desc 'Build beta ipa' lane :beta do |options| build_deploy options release_on_github options end desc 'Build product ipa' lane :prod do |options| build_deploy options release_on_github options stop ...
Listing 7
Matching up CircleCI configuration with Fastlane
CircleCI uses YAML
files which should exist simple. When a pull request is merged or lawmaking is pushed to some branch, it may trigger a CircleCI workflow given a properly ready config.yml
which in turn fires a specific lane on Fastlane.
Please advisedly note that nosotros have three environment arguments called alpha
, beta
and prod
which you can refer in Table 2 in the alias column. Have a look at snippet of yaml file beneath:
--- jobs: deploy: executor: name: default parameters: build_type: type: enum enum: ["alpha", "beta", "prod"] # Corresponds to lanes default: blastoff steps: - attach_workspace: at: /Users/distiller/project - run: name: Build ipa control: package exec fastlane ios << parameters.build_type >> - store_artifacts: path: output when: on_success
Following is also snippet of the same yaml file. Hither setup
installs required dependency similar rubygems, npm modules, cocoapod, firebase cli, carthage etc.
--- workflows: principal: jobs: - setup - test: requires: - setup - deploy: proper name: build_deploy_alpha build_type: alpha requires: - setup filters: branches: merely: - develop # RegEx - deploy: name: build_deploy_beta build_type: beta requires: - setup filters: branches: but: - /release\/.*/ # RegEx - /hotfix\/.*/ # RegEx - deploy: proper name: build_deploy_prod build_type: prod requires: - setup filters: branches: only: - principal # RegEx
Pay special attention to the filters of the each workflow besides. They are containing Regular Expressions similar develop
, /release\/.*/
, /hotfix\/.*/
,master
.
These filters make sure that CI build is triggered simply for those branches which match to a higher place regex.alpha
builds are triggered when code is pushed to develop
, beta
for release/*
and prod
for principal
.
Push On Co-operative | Lane executed | Surround |
---|---|---|
develop | bundle exec fastlane ios alpha | Evolution |
release/* & hotfix/* | bundle exec fastlane ios beta | Staging |
master | bundle exec fastlane ios prod | Production |
The only purpose of showing the above snippet is to prove you how the git branching model is practical to the CircleCI YAML file configuration and the Fastlane configuration file. Yous can learn more near CircleCI Yaml hither.
Decision
Effective development workflow and CI-CD implementation can assist reduce tons of developer hours. Similarly, the QA squad will be able to link the bugs and issues to a particular build and can have a more than productive conversation with developers. Especially, ramping upwardly time for the new developer also reduces significantly.
Resources
Sample Code Fastlane Tools Docs Firebase App Distribution Git Branching Model past Vincent Driessen AGV tooling enabled
Commodity Photo past Rasa Kasparaviciene
Source: https://engineering.monstar-lab.com/en/post/2021/09/15/How-to-setup-CICD-for-iOS-App-Development-with-Fastlane-CircleCI-and-Firebase-App-Distribution/
0 Response to "The Developer Needs to Upload a Build for This Distribution Fastlane"
Post a Comment