- Quick start
- 1. What is CI/CD?
- 2. Fastlane:
- 3. GitLab Runner
- 4. In closing…
If you have ever worked on a project together with other people, perhaps you’ve had a situation in which you pulled some changes from a git repository and it turned out that something stopped working or the project stopped compiling. Continuous integration helps to avoid such problems. Automatic builds and test execution after each commit are also useful when you are the only person working on a given project. With continuous integration, you can notice problems faster and fix them as soon as they appear.
-
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
-
brew install ruby
-
sudo gem install bundler
-
Install the latest Xcode command line tools:
xcode-select --install
Fix Missing Headers Compiling on macOS Mojave:
open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
-
brew cask install android-sdk
-
brew install fastlane
-
npm install -g firebase-tools
- Knowledge of iOS and Android build process
- Knowledge of iOS and Android code signing process
- Basic understanding of Fastlane
- Install Fastlane following their recommended setup
- https://medium.com/@phanquanghoang/using-gitlab-ci-cd-fastlane-for-ios-project-part-1-5e7db82a3566
- https://medium.com/@phanquanghoang/https-medium-com-phanquanghoang-using-gitlab-ci-cd-fastlane-for-ios-project-part-2-f2c55bf6305e
- https://medium.com/@phanquanghoang/using-gitlab-ci-cd-fastlane-for-ios-project-part-3-f710b618da4a
- https://medium.com/@ryanisnhp/firebase-app-distribution-and-fastlane-5303c17b4395
- https://medium.com/@clementozemoya/automated-android-deployments-with-fastlane-and-firebase-app-distribution-b1d1905a4fe6
- https://medium.com/@pac_pac/how-to-auto-deploy-a-mobile-application-on-the-stores-with-gitlab-and-fastlane-608e44be3aac
- https://medium.com/coletiv-stories/ios-continuous-deployment-with-fastlane-36892ab66cb0
- https://dev.to/matt_catalfamo/how-to-build-and-manually-sign-an-ios-app-with-fastlane-2256
- https://www.thejeremywhite.com/blog/2015/10/05/xcode-gitlab-ci-setup.html
- https://about.gitlab.com/blog/2016/03/10/setting-up-gitlab-ci-for-ios-projects/
- https://docs.gitlab.com/runner/
- https://github.com/osamaq/reactnative-fastlane-appcenter
- https://shift.infinite.red/simple-react-native-android-releases-319dc5e29605
CI/CD generally refers to the combined practices of continuous integration and continuous delivery.
Testing is an essential part of the development process. Developers merge their changes back to the main branch as often as possible. The developer's changes are validated by creating a build and running some tests(Automation test). This entire process is what we call Continuous Integration (CI).
Continuous delivery(CD) is an extension of continuous integration to make sure that you can release new changes to your customers quickly in a sustainable way. This means, besides of having automated your testing, you also have automated your release process.
Fastlane is a tool for iOS and Android developers to automate tedious tasks like generating screenshots, dealing with provisioning profiles, and releasing your application.
2.1.1 Setup Fastlane:
The tool fastlane is a collection of Ruby scripts, so you must have the correct version of Ruby installed. Chances are that your OS comes with Ruby 2.0 by default, but you can confirm whether this is the case by opening Terminal and entering:
ruby -v
If it’s not installed, the easiest way to do so is via Homebrew a package manager for macOS.
/usr/bin/ruby -e \
"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Then, install Ruby using:
brew update && brew install ruby
You’ll also need Xcode Command Line Tools (CLT). To ensure that they’re installed, enter into Terminal:
xcode-select --install
Now you’re ready to install Fastlane! Enter the following command to do so:
brew install fastlane
Navigate your terminal to your ios directory or android directory and run:
fastlane init
Fastlane will automatically detect your project, and ask for any missing information.
Notes: If you get a “permission denied” error, prefix this command with
sudo
.
After some output, Fastlane will ask: "What would you like to use fastlane for?"
You should config the Fastlane file by yourself. Input 4 and tap Enter.
Back to the project folder, you’ll see a few new things:
- Gemfile: which includes the Fastlane gem as a project dependency
- Appfile: stores the app identifier, your Apple ID and any other identifying information that Fastlane needs to set up your app.
- Fastfile: manages the lanes you’ll create to invoke fastlane actions.
You'll be asked to confirm that you're ready to begin, and then for a few pieces of information. To get started quickly:
- Provide the package name for your application when asked (e.g. io.fabric.yourapp)
- Press enter when asked for the path to your json secret file
- Answer 'n' when asked if you plan on uploading info to Google Play via fastlane (we can set this up later)
That's it! Fastlane will automatically generate a configuration for you based on the information provided.
You can see the newly created ./fastlane
directory, with the following files:
- Gemfile: This will clearly define the used Fastlane version, and its dependencies, and will also speed up using fastlane.
- Appfile: which defines configuration information that is global to your app
- Fastfile: which defines the "lanes" that drive the behavior of fastlane
Fastlane requires some environment variables set up to run correctly. In particular, having your locale not set to a UTF-8 locale will cause issues with building and uploading your build. In your shell profile add the following lines:
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
# app_identifier("[[APP_IDENTIFIER]]") # The bundle identifier of your app
# apple_id("[[APPLE_ID]]") # Your Apple email address
# For more information about the Appfile, see:
# https://docs.fastlane.tools/advanced/#appfile
Remove the # at the beginning of the line to enable the options
In case your account has multiple teams, add the following lines:
itc_team_id("123456789") # App Store Connect Team ID
team_id("XXXXXXXXXX") # Developer Portal Team ID
Open Fastfile, you will see something like this:
default_platform(:ios)
platform :ios do
desc "Description of what the lane does" # 1
lane :custom_lane do # 2
# add actions here: https://docs.fastlane.tools/actions
end
end
Here’s what this code does:
- Provides a description for the lane. A lane is a workflow of sequential tasks.
- Provides the lane name and the actions(tasks) of it.
To get the most up-to-date information from the command line on your current version you can also run:
fastlane actions # list all available fastlane actions
fastlane action [action_name] # more information for a specific action
Or you can refer in available actions
For more action, check out the fastlane plugins page. If you want to create your own action, check out the local actions page.
Fastlane takes care of building your app using an action called build_app (alias for build_ios_app, or gym), just add the following to your Fastfile:
gym(scheme: "YourScheme", export_method: "ad-hoc")
Additionally you can specify more options for building your app, for example:
gym(scheme: "YourScheme", export_method: "app-store")
For example, you will have below config for build scheme FastlanePlayground and export as ad-hoc method
default_platform(:ios)
platform :ios do
desc "Archive build Ad Hoc"
lane :gymAppAdHoc do
gym(scheme: "YourScheme", export_method: "ad-hoc")
end
end
And then, in Terminal, run:
fastlane gymAppAdHoc
If everything works, you should have a FastlanePlayground.ipa
file in the current directory. If you see any codesigning error, don't worry, you will go to the next part.
Chances are that something went wrong because of code signing at the previous step. Code Signing Guide will help you setting up the right code signing approach for your project.
- You are building your app on a macOS image that doesn't have your signing certificates or provisioning profiles installed.
- You have password encrypted signing certificate downloaded to the directory on your build machine
- You have a mobile provisioning profile downloaded to a directory on your build machine
- Automatic code signing is disabled in your Xcode project
For the record, I would recommend if you have a simple iOS project that you use Fastlane match and Xcode automatic code signing. But sometimes in the real world there are restrictions and external reasons to have to do manual code signing, so we will go through the process of building and signing manually. Here is the process.
Now we will use import_certificate for codesigning. You can always manually create and manage your certificates and provisioning profiles using the Apple Developer Portal. Make sure to store the private key (.p12
) of your certificates in a safe place, as they can't be restored if you lose them.
You have to download the certificate (.cer
) and provisioning profile (.mobileprovision
) from the Apple Developer Portal. Then, you should store it in your iOS's project like here:
Then add the following to your Fastfile:
desc "install Cer And Provisioning"
lane :installCerAndProvisioning do
import_certificate(
keychain_name: "login",
certificate_path: "certs/dist.p12",
certificate_password: "yourPasswordCerts",
keychain_password: "yourPasswordCerts"
)
install_provisioning_profile(path: "certs/adhoc.mobileprovision")
install_provisioning_profile(path: "certs/provisionAppStore.mobileprovision")
end
Now that the hard part is over we can call the installCerAndProvisioning function in the build lane before we build the app. The build lane will now look like this:
desc "Archive build Ad Hoc"
lane :gymAppAdHoc do
disable_automatic_code_signing
update_project_provisioning(
profile: "certs/provisionAdhoc.mobileprovision",
code_signing_identity: "Apple Distribution: Team Name (ABCDU8RR8X)"
)
gym(scheme: SCHEME_DEV,export_method: "ad-hoc")
end
Here’s what this code does:
- Disable Automatically Code Signing, so you can use the provisioning profile
- Set provisioning profile to build ad hoc
- Build scheme "YourScheme" with method "ad-hoc"
You can read more here update_project_provisioning
After building your app, it's ready to be uploaded to a beta testing service of your choice. The beauty of Fastlane is that you can easily switch beta provider, or even upload to multiple at once, without any extra work.
Firebase App Distribution makes distributing your apps to trusted testers painless. By getting your apps onto testers' devices quickly, you can get feedback early and often. To learn more about Firebase App Distribution, go here.
Because Firebase App Distribution is not a part of Fastlane, so you need to install it as a Plugins. Run this command:
fastlane add_plugin firebase_app_distribution
Check that if in your Pluginfile like this
Next, install Firebase CLI by running this in your terminal
curl -sL firebase.tools | bash
Sign in your account to authorize Firebase by running
firebase login:ci
and you can log out anytime by running with the following command line
firebase logout
You can select Yes or No if you want to allow Firebase to collect your data. For me, I choose Yes because maybe Firebase will give us some reports about my apps
Then, your browser will open this link automatically to ask your permission
Print a new refresh token. The current CLI session will not be affected. Store the output token in a secure but accessible way in your CI system. Use this token when setup in Fastlane to upload IPA to Firebase App Distribution
Next is an important step, create a new lane in your Fastfile:
desc "upload to Beta by FireBase"
lane :uploadFirebaseDev do
firebase_app_distribution(
app: "1:664452671234:ios:5df5316d004bac5bf61234",
testers: “TESTER-EMAILS”,
groups: “TESTER-GROUP”,
release_notes: "Version Staging",
firebase_cli_token: "1//1234HjkYpldZ4CgYIARAAGBASNwF-1234whOlK0VPxN63LfLpqBG98TzhJ_1234v3e0mrE9PtCmketolYa7hhInJwj13UisBdEM",
)
end
So, what’s APP-ID here
Enter Project settings in firebase console
Scroll down and you’ll see your APP-ID here
Next is TESTER-EMAILS, back to your App Distribution and select the tab Testers & Groups
If you put tester emails in your lane already, you no need to add testers again manually in firebase console, like the image below, no need to add my testers again for each builds
There’re 3 milestones to show you who:
Invited already but not accept your invitation yet
Accepted your invitation but not install it yet
With TESTER-GROUP, please make sure that you use a correct group id (not a group name)
For example, I have a group name Worldwide Team, but in Fastfile I must input a group ID, as image below, we have worldwide-team
Next is RELEASE-NOTE, yeah, it’s like What’s new for this beta app?
2.2.6 Upload TestFlight:
- Create a new Apple ID without 2FA. Avoid using your own account, its safer for you and easier to deliver the project along to your client or someone else. Fastlane supports 2FA but you will run into issues when managing the session token (you should test it though!);
- Add the account to the project development team in Apple Developer and iTunesConnect.
Define info account without 2FA can upload build to TestFlight:
desc "Define info account without 2FA can upload build to TestFlight"
before_all do
ENV["FASTLANE_DONT_STORE_PASSWORD"] = "1"
ENV["FASTLANE_USER"] = "appleaccount@gmail.com"
ENV["FASTLANE_PASSWORD"] = "Abc12345678*"
end
Then we will archive build with method App Store. This setup will generate the .ipa file required for uploading the app to TestFlight
desc "Archive build production with method app store"
lane :buildAppProductionMethodAppStore do
disable_automatic_code_signing
update_project_provisioning(
profile: "certs/provisionAppStore.mobileprovision",
code_signing_identity: "Apple Distribution: Team Name (ABCDU8RR8X)"
)
gym(scheme: SCHEME_PRODUCTION,export_method: "app-store")
end
Now we can upload IPA to TestFlight:
desc "Upload build production to Test Flight"
lane :uploadToTestFlight do
pilot(skip_waiting_for_build_processing: true)
end
You can see more config here
2.2.7 Final setup Fastlane
Here final setup lane for all action above:
desc "Push a new build to Fabric and FireBase App Distribution"
lane :uploadIPA do
installCerAndProvisioning
gymAppAdHoc
uploadFirebaseDev
buildAppProductionMethodAppStore
uploadToTestFlight
end
Now we will call all lanes with this command:
fastlane uploadIPA
json_key_file("path/to/you/json/key/file") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
package_name("com.example.app") # e.g. com.krausefx.app
Open Fastfile, you will see something like this:
default_platform(:android)
platform :android do
desc "Description of what the lane does" # 1
lane :custom_lane do # 2
# add actions here: https://docs.fastlane.tools/actions
end
end
Here’s what this code does:
- Provides a description for the lane. A lane is a workflow of sequential tasks.
- Provides the lane name and the actions(tasks) of it.
To get the most up-to-date information from the command line on your current version you can also run:
fastlane actions # list all available fastlane actions
fastlane action [action_name] # more information for a specific action
Or you can refer in available actions
For more action, check out the fastlane plugins page. If you want to create your own action, check out the local actions page.
Navigate to JDK binary. Find the binary with:
/usr/libexec/java_home
Generate keystore. Rename the key and alias.
sudo keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
Move the key to your android/app
directory.
sudo mv my-release-key.keystore [...path to YourAppName/android/app]
Create gradle variables by adding the following to android/gradle.properties
:
MYAPP_RELEASE_STORE_FILE=my-release-key.keystore
MYAPP_RELEASE_KEY_ALIAS=my-key-alias
MYAPP_RELEASE_STORE_PASSWORD=*****
MYAPP_RELEASE_KEY_PASSWORD=*****
You can change the names.
Edit android/app/build.gradle
and add the signing config and build variant:
...
android {
...
defaultConfig { ... }
signingConfigs {
release {
if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
storeFile file(MYAPP_RELEASE_STORE_FILE)
storePassword MYAPP_RELEASE_STORE_PASSWORD
keyAlias MYAPP_RELEASE_KEY_ALIAS
keyPassword MYAPP_RELEASE_KEY_PASSWORD
}
}
}
buildTypes {
release {
...
signingConfig signingConfigs.release
}
}
}
...
Change the variable names according to the previous step. Done.
Fastlane takes care of building your app using an action called build_app (alias for gradle), just add the following to your Fastfile:
gradle(
task: "assemble",
flavor: "WorldDomination",
build_type: "Release"
)
You can pass multiple gradle tasks:
gradle(
tasks: ["assembleDebug", "bundleDebug"]
)
For example, You can use this to automatically sign and zipalign your app:
default_platform(:ios)
platform :ios do
desc "Archive build Ad Hoc"
lane :buildReleaseAPK do
gradle(
task: "assemble",
build_type: "Release",
print_command: false,
properties: {
"android.injected.signing.store.file" => "keystore.jks",
"android.injected.signing.store.password" => "store_password",
"android.injected.signing.key.alias" => "key_alias",
"android.injected.signing.key.password" => "key_password",
}
)
end
end
And then, in Terminal, run:
fastlane buildReleaseAPK
Note:
In gradle-wrapper.properties please use grade version 6.3 or above. Edit gradle-wrapper.properties file and replace distributionUrl with following value:
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
The build type has to be consistent with the build variant in the previous step. If everything works, you should have a app-develop-release.apk
file in the build outputs directory.
After building your app, it's ready to be uploaded to a beta testing service of your choice. The beauty of Fastlane is that you can easily switch beta provider, or even upload to multiple at once, without any extra work.
Firebase App Distribution makes distributing your apps to trusted testers painless. By getting your apps onto testers' devices quickly, you can get feedback early and often. To learn more about Firebase App Distribution, go here.
Because Firebase App Distribution is not a part of Fastlane, so you need to install it as a Plugins. Run this command:
fastlane add_plugin firebase_app_distribution
Check that if in your Pluginfile like this
Next, install Firebase CLI by running this in your terminal
curl -sL firebase.tools | bash
Sign in your account to authorize Firebase by running
firebase login:ci
and you can log out anytime by running with the following command line
firebase logout
You can select Yes or No if you want to allow Firebase to collect your data. For me, I choose Yes because maybe Firebase will give us some reports about my apps
Then, your browser will open this link automatically to ask your permission
Print a new refresh token. The current CLI session will not be affected. Store the output token in a secure but accessible way in your CI system. Use this token when setup in Fastlane to upload IPA to Firebase App Distribution
Next is an important step, create a new lane in your Fastfile:
desc "upload to Beta by FireBase"
lane :uploadFirebaseDev do
firebase_app_distribution(
app: "1:123452671234:android:1234e227e57f2fff61234",
testers: “TESTER-EMAILS”,
groups: “TESTER-GROUP”,
release_notes: "Version Staging",
apk_path: './app/build/outputs/apk/develop/release/app-develop-release.apk',
firebase_cli_token: "1//1234HjkYpldZ4CgYIARAAGBA1234-1234hOlK0VPxN63LfLpqBG98TzhJ_1234bv3e0mrE9PtCmketolYa7hhInJwj13UisBdEM",
)
end
So, what’s APP-ID here
Enter Project settings in firebase console
Scroll down and you’ll see your APP-ID here
Next is TESTER-EMAILS, back to your App Distribution and select the tab Testers & Groups
If you put tester emails in your lane already, you no need to add testers again manually in firebase console, like the image below, no need to add my testers again for each builds
There’re 3 milestones to show you who:
Invited already but not accept your invitation yet
Accepted your invitation but not install it yet
With TESTER-GROUP, please make sure that you use a correct group id (not a group name)
For example, I have a group name Worldwide Team, but in Fastfile I must input a group ID, as image below, we have worldwide-team
Next is RELEASE-NOTE, yeah, it’s like What’s new for this beta app?
2.3.6 Final setup Fastlane
Here final setup lane for all action above:
desc "Push a new build to Fabric and FireBase App Distribution"
lane :uploadAPK do
buildReleaseAPK
uploadFirebaseDev
end
Now we will call all lanes with this command:
fastlane uploadAPK
GitLab Runner is the open source project that is used to run your jobs and send the results back to GitLab. It is used in conjunction with GitLab CI/CD, the open-source continuous integration service included with GitLab that coordinates the jobs.
It's beyond the scope of this tutorial to go into details on best practices, workflows, and advantages/disadvantages of CI. In short, however, here's what happens when you enable it for your project:
- You make changes to your copy of the codebase and push a commit to GitLab.
- GitLab recognizes that the codebase has changed.
- GitLab triggers a build with the GitLab Runner you set up on your Mac for the project.
- The GitLab Runner runs through the build and test process you specified in
.gitlab-ci.yml
. - The GitLab Runner reports its results back to GitLab.
- GitLab shows you the results of the build.
GitLab Runner can be installed and updated on macOS.
NOTE: Note: For documentation on GitLab Runner 9 and earlier, visit this documentation.
-
Download the binary for your system:
sudo curl --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64
You can download a binary for every available version as described in Bleeding Edge - download any other tagged release.
-
Give it permissions to execute:
sudo chmod +x /usr/local/bin/gitlab-runner
The rest of commands execute as the user who will run the Runner.
-
To register a Runner under macOS:
Run the following command:
gitlab-runner register
Enter your GitLab instance URL:
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com ) https://gitlab.com
Enter the token you obtained to register the Runner, You can get your token in Gitlab Setting -> CI/CD -> Runner:
Please enter the gitlab-ci token for this runner xxx
Enter a description for the Runner, you can change this later in GitLab’s UI:
Please enter the gitlab-ci description for this runner [hostname] my-runner
Enter the tags associated with the Runner, you can change this later in GitLab’s UI:
Please enter the gitlab-ci tags for this runner (comma separated): my-tag,another-tag
Enter the Runner executor:
Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell: shell
As we can see, the registration command is specifying the
shell
executor. Let’s see what is the final configuration~/.gitlab-runner/config.toml
content:concurrent = 1 #limits how many jobs globally can be run concurrently. The most upper limit of jobs using all defined runners. 0 does not mean unlimited check_interval = 0 #defines the interval length, in seconds, between new jobs check. The default value is 3; if set to 0 or lower, the default value will be used. [session_server] session_timeout = 1800 #How long in seconds the session can stay active after the job completes (which will block the job from finishing), defaults to 1800 (30 minutes). [[runners]] name = "test-runner" #The name of the image to be run as a service url = "https://gitlab.com" #GitLab URL token = "__REDACTED__" #The Runner’s special token (not to be confused with the registration token) executor = "shell" #run build locally, default [runners.cache] [runners.cache.s3] [runners.cache.gcs]
You can see more config here
-
Install the Runner as service and start it:
cd ~ gitlab-runner install gitlab-runner start
Runner is installed and will be run after a system reboot.
You can verify this by running
$ gitlab-ci-multi-runner verify
WARNING: Running in user-mode.
WARNING: The user-mode requires you to manually start builds processing:
WARNING: $ gitlab-runner run
WARNING: Use sudo for system-mode:
WARNING: $ sudo gitlab-runner...
Veryfing runner... is alive runner=25c780b3
-
Stop the service:
gitlab-runner stop
-
Download the binary to replace the Runner's executable:
sudo curl -o /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64
You can download a binary for every available version as described in Bleeding Edge - download any other tagged release.
-
Give it permissions to execute:
sudo chmod +x /usr/local/bin/gitlab-runner
-
Start the service:
gitlab-runner start
Make sure that you read the FAQ section which describes some of the most common problems with GitLab Runner. You can see more commands here
In order to upgrade the LaunchAgent
configuration, you need to uninstall and install the service:
gitlab-runner uninstall
gitlab-runner install
gitlab-runner start
Before you create .gitlab-ci.yml
let’s first explain in brief what this is all about.
The .gitlab-ci.yml
file is where you configure what CI does with your project. It lives in the root of your repository.
On any push to your repository, GitLab will look for the .gitlab-ci.yml
file and start jobs on Runners according to the contents of the file, for that commit.
Because .gitlab-ci.yml
is in the repository and is version controlled, old versions still build successfully, forks can easily make use of CI, branches can have different pipelines and jobs, and you have a single source of truth for CI. You can read more about the reasons why we are using .gitlab-ci.yml
here.
First create a Gemfile
in the root of your project with the following content:
source "https://rubygems.org"
gem "fastlane"
Note:
.gitlab-ci.yml
is a YAML file so you have to pay extra attention to indentation. Always use spaces, not tabs.
You need to create a file named .gitlab-ci.yml
in the root directory of your repository. Below is an example of the current tutorial:
stages: #used to define stages that can be used by jobs and is defined globally
- deployiOS
- deployAndroid
variables: #Set up environment values
LC_ALL: "en_US.UTF-8"
LANG: "en_US.UTF-8"
before_script: #Override a set of commands that are executed before job.
- bundle install --path vendor/bundle
- npm i #install node_modules for RN project
deployiOS:
dependencies: []
stage: deployiOS
script: #scrip when work with current state
- cd ios/
- pod install
- fastlane uploadIPA
tags: #tag registered with gitlab-runner
- ios
only: #defines the names of branches and tags for which the job will run
- build-dev
deployAndroid:
dependencies: []
stage: deployAndroid
script: #scrip when work with current state
- npx jetify
- cd android/
- fastlane uploadAPK
tags: #tag registered with gitlab-runner
- android
only: #defines the names of branches and tags for which the job will run
- build-dev
This is the simplest possible configuration that will work for most React Native projects:
- Define job
deploy
(the names are arbitrary) with commands to be executed. - Before every job, the commands defined by
before_script
are executed. - We defined which branch will run this job by only:
build-dev
The .gitlab-ci.yml
file defines sets of jobs with constraints of how and when they should be run. The jobs are defined as top-level elements with a name (in our case deployiOS
and deployAndroid
) and always have to contain the script
keyword. Jobs are used to create jobs, which are then picked by Runners and executed within the environment of the Runner.
What is important is that each job is run independently from each other.
If you want to check whether the .gitlab-ci.yml
of your project is valid, there is a Lint tool under the page /-/ci/lint
of your project namespace. You can also find a “CI Lint” button to go to this page under CI/CD ➔ Pipelines and Pipelines ➔ Jobs in your project.
For more information and a complete .gitlab-ci.yml
syntax, please read the reference documentation on .gitlab-ci.yml
.
Once you’ve created .gitlab-ci.yml
, you should add it to your Git repository and push it to GitLab.
git add .gitlab-ci.yml
git commit -m "Add .gitlab-ci.yml"
git push origin master
Now if you go to the Pipelines page you will see that the pipeline is pending.
Note: If you have a mirrored repository where GitLab pulls from, you may need to enable pipeline triggering in your project’s Settings > Repository > Pull from a remote repository > Trigger pipelines for mirror updates.
You can also go to the Commits page and notice the little pause icon next to the commit SHA.
Clicking on it you will be directed to the jobs page for that specific commit.
Notice that there is a pending job which is named after what we wrote in .gitlab-ci.yml
. “stuck” indicates that there is no Runner configured yet for this job.
After configuring the Runner successfully, you should see the status of your last commit change from pending to either running, success or failed.
You can view all pipelines by going to the Pipelines page in your project.
Or you can view all jobs, by going to the Pipelines ➔ Jobs page.
By clicking on a job’s status, you will be able to see the log of that job. This is important to diagnose why a job failed or acted differently than you expected.
You are also able to view the status of any commit in the various pages in GitLab, such as Commits and Merge requests.
Visit the examples README to see a list of examples using GitLab CI with various languages.
Hopefully, this has been helpful and has inspired you to get builds and publishing working within your GitLab project. There is some good additional CI/CD best-practice documentation for Fastlane if you get stuck anywhere, and you could also consider using the CI_BUILD_ID
(which increments each builds) to automatically increment a version.
Thanks to Gitlab.com we have our completely free CI and we have learned something about the Fastlane tool. We also managed to create a mechanism for installing IPA straight from Gitlab, so we do not need to use any additional services and we have everything in one place. Of course, if we need something more advanced to publish our application, with the help of Fastlane we can easily add for example integration with Testflight. I encourage you to learn more about Fastlane and adapt the presented solution to your needs.
I hope this tutorial can be of great help to you during the software development process, save time for you and your team.