Hi guys, in this series of three articles, we will explore how to automate the builds of a React Native application and connect them with TestFlight for iOS releases and App Distribution for Android releases.
Releasing a React Native application can often be time-consuming. Each time a release is needed, you have to perform an "Archive" from Xcode and then follow the entire release process to TestFlight. A similar, though slightly different, process is required for Android, where you need to create the application's AAB and upload it to App Distribution to allow testers to perform all necessary tests.
To minimize the time spent on this process, introducing an automatic build process can be very useful and sensible.
In this first step, we will look at the necessary steps for installing Fastlane and create a general folder (for both Android and iOS) to manage the version and build number in a centralized manner, ensuring consistency across both iOS and Android.
We will use the version from package.json to manage the versioning for both iOS and Android. This way, everything will always be aligned, and it will be easy to understand which version we are using since the package.json will be our reference point.
For effective project management and releases, it is crucial that the versions of iOS and Android are aligned.
brew install fastlane
which fastlane
So, let's navigate to our React Native project and create a 'fastlane' folder at the root level of the project:
mkdir fastlane && cd fastlane
cd ..Next, we will add three necessary plugins to handle version increments, build number increments, and reading the project version from package.json:
fastlane add_plugin increment_version_name
fastlane add_plugin increment_version_code
fastlane add_plugin load_jsonNow, navigate back to the 'fastlane' folder and create a Fastfile:
cd fastlane && touch FastfileAt this point, you should have a folder called 'fastlane' at the root level of your project containing three files.
PluginFile
# Autogenerated by fastlane
#
# Ensure this file is checked in to source control!
gem 'fastlane-plugin-increment_version_name'
gem 'fastlane-plugin-increment_version_code'
gem 'fastlane-plugin-load_json'Inside the 'fastlane' folder, you should now see a few files, including an autogenerated Readme.md and the Fastfile. The Fastfile is where we will write the necessary code to execute the bump of the version and the build number.
Here's a brief overview of what each file will contain:
- Readme.md: This file is autogenerated and typically contains basic information about the Fastlane setup.
- Fastfile: This is where we'll write the code needed to increment the version and build number.
Let's start by setting up the Fastfile to handle versioning and build number increments. Open the Fastfile and add the following code:
desc 'Android: Increment versionCode and set versionName to package.json version.'
private_lane :inc_ver_and do
package = load_json(json_path: "./package.json")
increment_version_code(
gradle_file_path: "./android/app/build.gradle",
)
increment_version_name(
gradle_file_path: "./android/app/build.gradle",
version_name: package['version']
)
end
desc 'Android: Increment versionCode'
private_lane :inc_build_number_android do
increment_version_code(
gradle_file_path: "./android/app/build.gradle",
)
end
desc 'iOS: Increment build number and set the version to package.json version.'
private_lane :inc_ver_ios do
package = load_json(json_path: "./package.json")
increment_build_number(
xcodeproj: './ios/' + package['name'] + '.xcodeproj'
)
increment_version_number(
xcodeproj: './ios/' + package['name'] + '.xcodeproj',
version_number: package['version']
)
end
desc 'iOS: Increment build number'
private_lane :inc_build_number_ios do
package = load_json(json_path: "./package.json")
increment_build_number(
xcodeproj: './ios/' + package['name'] + '.xcodeproj'
)
end
desc 'Bump build numbers, and set the version to match the pacakage.json version.'
lane :bump do
package = load_json(json_path: "./package.json")
inc_ver_ios
inc_ver_and
git_commit(
path: "./",
message: "bump-version: #{package['version']}"
)
add_git_tag(
tag: package['version']
)
push_to_git_remote(
remote: "origin", # optional, default: "origin"
local_branch: "master", # optional, aliased by "branch", default is set to current branch
remote_branch: "master", # optional, default is set to local_branch
force: false, # optional, default: false
force_with_lease: false, # optional, default: false
tags: true, # optional, default: true
no_verify: true,# optional, default: false
set_upstream: true # optional, default: false
)
end
desc 'Increase build number'
lane :increaseBuildNumber do
inc_build_number_android
inc_build_number_ios
git_commit(
path: "./",
message: "bump-build-number"
)
push_to_git_remote(
remote: "origin", # optional, default: "origin"
local_branch: "master", # optional, aliased by "branch", default is set to current branch
remote_branch: "master", # optional, default is set to local_branch
force: false, # optional, default: false
force_with_lease: false, # optional, default: false
tags: true, # optional, default: true
no_verify: true,# optional, default: false
set_upstream: true # optional, default: false
)
endAs you can see, there are different scripts for performing actions for iOS and Android. Each platform handles versioning and build numbers differently, so we need to manage these aspects distinctly for each platform.
Let's define the necessary scripts and add them to the scripts section of the package.json to make them easily and quickly accessible whenever we want to use them.
Here's how to add the scripts to your package.json:
- Open your package.json file.
- Add the following scripts to the scripts section:
"bump-patch": "npm version patch --no-git-tag-version && bundle exec fastlane bump",
"bump-minor": "npm version minor --no-git-tag-version && bundle exec fastlane bump",
"bump-major": "npm version major --no-git-tag-version && bundle exec fastlane bump",These scripts allow us to bump the patch, minor, or major version by updating the package.json version, and then the version and build number of the project. As mentioned earlier, our reference point in this case remains the version in package.json.
Once this is done, the change will be committed, a tag with the new version will be added, and a push will be made to the "master" branch. These settings are easily interchangeable, and by using Fastlane's push_to_git_remote command, we can customize the Git-related part. If we simply want to push to the current branch, we just need to remove the branch definition part in this command, and by default, it will take the branch we are working on.
Keep following me to stay updated on further insights and new tools that will make coding smoother and faster. Thank you for joining me on this journey!
Happy coding!
Linkedin Profile: https://www.linkedin.com/in/davide-carizzoni/