Blog Infos
Author
Published
Topics
,
Published
Fastlane
Starting with Fastlane first…
Now Let’s Start Integration
Initiate Fastlane
source "https://rubygems.org"
gem "fastlane"
Create Fastlane Project
plugins_path = File.join(File.expand_path("..", __FILE__), 'fastlane', 'Pluginfile')
eval_gemfile(plugins_path)
Secrets management
KEYSTORE_ALIAS=<alias here>
KEYSTORE_PASSWORD=<password here>
Defining Steps in Fastfile
Load Secret
fastlane_require "dotenv"
before_all do
 Dotenv.overload ".env.secret"
end
Define Global Variables (if any)
fastlane_require "dotenv"
PACKAGE_NAME = "<package name here>"
FIREBASE_APP_ID = "<firebase app id here>"
KEYSTORE_PATH = nil
FIREBASE_KEY_PATH = nil
PLAYSTORE_KEY_PATH = nil
BUNDLE_FILE_PATH = nil
UPDATED_VERSION_CODE = nil
before_all do
Dotenv.overload ".env.secret"
KEYSTORE_PATH = Dir.pwd + "/../certificates/<keystore_name>.jks"
FIREBASE_KEY_PATH = Dir.pwd + "/../certificates/firebase-app-distribution-key.json"
PLAYSTORE_KEY_PATH = Dir.pwd + "/../certificates/playstore-app-distribution-key.json"
BUNDLE_FILE_PATH = Dir.pwd + "/../app/outputs/bundle/release/app-release.aab"
end
Increase Version Code
desc "Responsible for fetching version code from play console and incrementing version code."
lane :increment_version_code_in_project_gradle do
version_code_from_play_store_strings = google_play_track_version_codes(
package_name: PACKAGE_NAME, # PACKAGE_NAME is a global variable defined earlier
track: "production", # this can be alpha, beta etc.
json_key: PLAYSTORE_KEY_PATH,
)
version_code_from_play_store = version_code_from_play_store_strings[0].to_i
UPDATED_VERSION_CODE = version_code_from_play_store + 1
increment_version_code(
gradle_file_path: Dir.pwd + "/../app/build.gradle",
version_code: UPDATED_VERSION_CODE.to_i
)
end

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

,

From Chaos to Consistency: Managing Build and Release for 25+ Android Repos with Github Actions

Managing the build and release process for over 25 Android repositories can be a daunting task. With each repository having its own pipeline or workflow, it can become difficult to ensure consistency and quality across…
Watch Video

From Chaos to Consistency: Managing Build and Release for 25+ Android Repos with Github Actions

Shrikant Ballal
Staff Engineer
YML

From Chaos to Consistency: Managing Build and Release for 25+ Android Repos with Github Actions

Shrikant Ballal
Staff Engineer
YML

From Chaos to Consistency: Managing Build and Release for 25+ Android Repos with Github Actions

Shrikant Ballal
Staff Engineer
YML

Jobs

To use the incremented_version_code plugin, you’ve to add this plugin into Pluginfile. Add this plugin as follows:

gem 'fastlane-plugin-increment_version_code'
Run Unit Test
desc "Run unit tests."
lane :run_unit_tests do
gradle(
task: "test"
)
end

In your local machine, you can face some permission issues. In that case run

chmod +x gradlew
Assemble And Build a Bundle File
desc "Build the .aab file"
lane :build do
gradle(
task: "bundle",
build_type: "Release",
properties: {
"android.injected.signing.store.file" => KEYSTORE_PATH,
"android.injected.signing.store.password" => ENV['KEYSTORE_PASSWORD'],
"android.injected.signing.key.alias" => ENV['KEYSTORE_ALIAS'],
"android.injected.signing.key.password" => ENV['KEYSTORE_PASSWORD']
}
)
end
Distribute App to Firebase App Distribution
gem 'fastlane-plugin-firebase_app_distribution'

And create a lane in Fastfile to upload the .aab file to Firebase App Distribution:

desc "Responsible for uploading .aab to Firebase app distribution."
lane :distribute_to_firebase do
firebase_app_distribution(
app: FIREBASE_APP_ID,
release_notes: "Uploaded from CI/CD",
android_artifact_type: "AAB",
android_artifact_path: BUNDLE_FILE_PATH,
service_credentials_file: FIREBASE_KEY_PATH,
groups: "tester-team"
)
end
Upload App to Play Store for Reviewing
desc "Responsible for uploading aab to playstore"
lane :distribute_playstore do
upload_to_play_store(
track: "production",
aab: BUNDLE_FILE_PATH,
json_key: PLAYSTORE_KEY_PATH,
package_name: PACKAGE_NAME
)
end
Push Updated Code
desc "After successful execution of all task, this block is called"
after_all do
git_add(path: "*")
git_commit(
path: "*",
message: "#" + UPDATED_VERSION_CODE + " released"
)
push_to_git_remote(
local_branch: buildConfigs.key(options[:buildConfig]),
remote: "origin",
remote_branch: buildConfigs.key(options[:buildConfig]),
tags: true,
)
end

Here you created multiple lanes in Fastfile. To execute a lane, just run the following command.

bundle exec fastlane <lane name>

As you’ve created multiple lanes, you’ve to run this command for each lane. It’s another hassle. You can call all these lanes from another lane to execute only the lane from the terminal, and it will do all tasks one after another.

desc "Responsible for testing, building and uploading bundle to firebase app distribution and playstore by calling other private lanes."
lane build_and_distribute:
increment_version_code_in_project_gradle()
run_unit_tests()
build()
distribute_to_firebase()
distribute_playstore()
end
fastlane_require "dotenv"
PACKAGE_NAME = "<package name here>"
FIREBASE_APP_ID = "<firebase app id here>"
KEYSTORE_PATH = nil
FIREBASE_KEY_PATH = nil
PLAYSTORE_KEY_PATH = nil
BUNDLE_FILE_PATH = nil
UPDATED_VERSION_CODE = nil
before_all do
Dotenv.overload ".env.secret"
KEYSTORE_PATH = Dir.pwd + "/../certificates/<keystore_name>.jks"
FIREBASE_KEY_PATH = Dir.pwd + "/../certificates/firebase-app-distribution-key.json"
PLAYSTORE_KEY_PATH = Dir.pwd + "/../certificates/playstore-app-distribution-key.json"
BUNDLE_FILE_PATH = Dir.pwd + "/../app/outputs/bundle/release/app-release.aab"
end
lane :build_and_distribute do
increment_version_code_in_project_gradle()
run_unit_tests()
build()
distribute_to_firebase()
distribute_playstore()
end
desc "Responsible for fetching version code from play console and incrementing version code."
private_lane :increment_version_code_in_project_gradle do
version_code_from_play_store_strings = google_play_track_version_codes(
package_name: PACKAGE_NAME, # PACKAGE_NAME is a global variable defined earlier
track: production, # this can be alpha, beta etc.
json_key: PLAYSTORE_KEY_PATH,
)
version_code_from_play_store = version_code_from_play_store_strings[0].to_i
incremented_version_code = version_code_from_play_store + 1
increment_version_code(
gradle_file_path: Dir.pwd + "/../app/build.gradle",
version_code: incremented_version_code.to_i
)
end
desc "Run unit tests."
private_lane :run_unit_tests do
gradle(
task: "test"
)
end
desc "Build the .aab file"
private_lane :build do
gradle(
task: "bundle",
build_type: "Release",
properties: {
"android.injected.signing.store.file" => KEYSTORE_PATH,
"android.injected.signing.store.password" => ENV['KEYSTORE_PASSWORD'],
"android.injected.signing.key.alias" => ENV['KEYSTORE_ALIAS'],
"android.injected.signing.key.password" => ENV['KEYSTORE_PASSWORD']
}
)
end
desc "Responsible for uploading .aab to Firebase app distribution."
private_lane :distribute_to_firebase do
firebase_app_distribution(
app: FIREBASE_APP_ID,
release_notes: "Uploaded from CI/CD",
android_artifact_type: "AAB",
android_artifact_path: BUNDLE_FILE_PATH,
service_credentials_file: FIREBASE_KEY_PATH,
groups: "tester-team"
)
end
desc "Responsible for uploading aab to playstore"
private_lane :distribute_playstore do
upload_to_play_store(
track: production,
aab: BUNDLE_FILE_PATH,
json_key: PLAYSTORE_KEY_PATH,
package_name: PACKAGE_NAME
)
end
desc "After successful execution of all task, this block is called"
after_all do
git_add(path: "*")
git_commit(
path: "*",
message: "#" + UPDATED_VERSION_CODE + " released"
)
push_to_git_remote(
local_branch: buildConfigs.key(options[:buildConfig]),
remote: "origin",
remote_branch: buildConfigs.key(options[:buildConfig]),
tags: true,
)
end
view raw Fastfile hosted with ❤ by GitHub
gem 'fastlane-plugin-firebase_app_distribution'
gem 'fastlane-plugin-increment_version_code'
That’s it…
bundle exec fastlane build_and_distribute

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
Life is hard. We are engulfed in tasks that take time, are boring, and…
READ MORE
blog
As a developer working on various Kotlin Multiplatform projects, whether for your job or…
READ MORE
blog
There are a lot of blogs and videos on why we need CI/CD. From…
READ MORE
blog
To release an Android app to the public, every Android Developer needs to build…
READ MORE

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Menu