Streamlined Android App Deployment: A Guide to Using Fastlane for the App Store in year 2024

Raja Osama
3 min readOct 3, 2024

--

Envision yourself zooming along the development expressway in your sleek React Native vehicle, code streaming behind you, commit after commit adding to the thrill. Then, you’re faced with a decision: Google Play Store or internal distribution? Have no fear, for Fastlane arrives just in time, like a superhero, to rescue your day.

Fastlane is more than a mere tool; it’s the trusty sidekick you didn’t know you needed. It takes care of the tedious tasks — code signing, beta testing, and the alchemy of app store submissions — all while you relax with your digital cup of joe. 🎉

So strap in, dear developer! It’s time to fire up those engines, bump up those build numbers, and launch your app as if tomorrow is a myth. Embrace Fastlane, the champion of automated deployments, because who has time for manual processes? 🚀📱

“Fastlane: Your React Native Sidekick for Epic Deployments!”

This file contains the configuration for Fastlane, your superhero sidekick in the world of Android development. Let’s dive into the details:

  1. Install Fastlane with a Ruby Twist: First, make sure you’ve got Ruby on your system (it’s like the secret sauce). Then, sprinkle some Fastlane magic with this command:
sudo gem install fastlane -NV

2. Obtain the Service Account JSON:

  1. Create a Service Account:
    -
    Go to the Google Cloud Console: Google Cloud Console
    - Navigate to your project (or create a new one if needed).
    - In the left sidebar, click on “IAM & Admin” > “Service accounts.”
    - Click the “+ CREATE SERVICE ACCOUNT” button.
    - Fill in the details (name, description), and choose the role “Project” > “Editor” (or a more specific role if you prefer).
    - Click “Create.”

2. Generate a JSON Key File:
-
Locate the newly created service account in the list.
- Click the three dots (⋮) next to it and select “Create key.”
- Choose the JSON format and click “Create.”
- Save the downloaded JSON file securely. This is your service account key.

3. Uploading Service Account JSON to GitHub secrets
Simply upload the service account JSON file you’ve downloaded to your GitHub repository secrets. This will enable you to upload the app without any manual interactions.

3. Fastlane Init: The Hero’s Call: Now, brace yourself! Execute this command to summon Fastlane into your project:

fastlane init

🚀 Fastlane swoops in, asking questions like a curious parrot. Answer wisely! Specify Android, or both.

# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
# https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
# https://docs.fastlane.tools/plugins/available-plugins
#
# Uncomment the line if you want fastlane to automatically update itself
# update_fastlanedefault_platform(:ios)
platform :ios do
desc "Push a new beta build to TestFlight"
lane :beta do
// Writing for Beta
end
end

4. Fetching Version Code: Let’s talk about the elephant in the room — the build number and version name directly fetched from your Android app. Imagine how good it would be to have a function that does that for you. Here’s one that fetches the version code:

  def get_max_version_code(track)
google_play_track_version_codes(
package_name: "com.you.app",
track: track,
json_key_data: "#{ENV['ANDROID_JSON_DATA']}"
).max
end

5. Fetching Version Name: Now, let’s get the version name from the app store directly:

  def get_released_track_version_code_and_name()
version_codes = google_play_track_release_names(track: 'production', package_name: 'com.your.app', json_key_data:"#{ENV['ANDROID_JSON_DATA']}")
latest_release_name = version_codes.last
match = latest_release_name.match(/(\d+) \(([\d\.]+)\)/)
release_code = match[1].to_i
release_name = match[2]
return release_code, release_name
end

6. Getting the Last Version Code: Retrieve the last version code from both internal and production tracks:

 def get_last_version_code()
internal_version_code = get_max_version_code("internal")
production_version_code = get_max_version_code("production")
return [internal_version_code, production_version_code].max
end

7. Beta Deployment: In your Fastlane beta lane, use the last version code to increment and handle release names:

 lane :beta do
version_code = get_last_version_code()
raise "Failed to get last version code" unless version_code

increment_version_code(
gradle_file_path: "./app/build.gradle", # replace with your actual path
version_code: version_code + 1
)

release = get_released_track_version_code_and_name()
raise "Failed to get released track version code and name" unless release && release.length >= 2

release_code = release[0].to_i
release_name = release[1]

if version_code >= release_code
version_segments = Gem::Version.new(release_name).segments
raise "Failed to parse release name" unless version_segments && version_segments.length > 0

version_segments[-1] += 1
release_name = version_segments.join('.')
end
end

8. Clean Bundle Release: Create a clean bundle release:

    gradle(task: "clean bundleRelease")

9. Upload to Play Store: Finally, let’s upload the app to the Play Store directly:

json_key_data = ENV['ANDROID_JSON_DATA']
raise "ANDROID_JSON_DATA environment variable is not set" unless json_key_data

upload_to_play_store(json_key_data: json_key_data,
track: 'internal',
version_name: release_name)
rescue => e
puts "An error occurred: #{e.message}"

Next Step : Crafting a pipeline to be able to run Fastlane action to deploy your applicaiton

--

--

Raja Osama

👋 Hi, I'm Raja Osama, a polyglot rockstar software engineer who loves to create fascinating applications using JavaScript-based tech stack. 💻