GitLab CI/CD
GitLab CI/CD pipelines allow you to build and upload both Android and iOS apps to TestApp.io, notifying your testers for testing and feedback.
Configuration
| Key | Description | Env Var(s) | Default |
|---|---|---|---|
| api_token | You can get it from https://portal.testapp.io/profile/tokens | TESTAPPIO_API_TOKEN | |
| app_id | You can get it from your app page at https://portal.testapp.io/apps | TESTAPPIO_APP_ID | |
| release | It can be either both or Android or iOS | TESTAPPIO_RELEASE | |
| apk | Path to the Android APK file | TESTAPPIO_ANDROID_PATH | |
| ipa | Path to the iOS IPA file | TESTAPPIO_IOS_PATH | |
| release_notes | Manually add the release notes to be displayed for the testers | TESTAPPIO_RELEASE_NOTES | |
| git_release_notes | Collect release notes from the latest git commit message to be displayed for the testers: true or false | TESTAPPIO_GIT_RELEASE_NOTES | true |
| git_commit_id | Include the last commit ID in the release notes (works with both release notes options): true or false | TESTAPPIO_GIT_COMMIT_ID | false |
| notify | Send notifications to your team members about this release: true or false | TESTAPPIO_NOTIFY | false |
Check TA-CLI for more info
iOS
Using Fastlane?TestApp.io Fastlane pluginSetup iOS Project for Fastlane
Add macOS runner
A macOS computer is required to build and package your iOS apps (IPA); however, GitLab does not provide such a runner. We will create the runner ourselves and register it to GitLab.
More info: https://docs.gitlab.com/runner/install/osx.html
Install Xcode
Make sure that xcodebuild is using Xcode rather than the command line tools:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
Verify:
xcode-select -p
Import the codesign certificate and provisioning profile to build and export the IPA file in Xcode.
Make sure that you can archive and export an IPA file from Xcode manually before setting up the pipeline.
Install GitLab runner
macOS amd64:
sudo curl --output /usr/local/bin/gitlab-runner "https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64"
macOS Apple Silicon/arm64:
sudo curl --output /usr/local/bin/gitlab-runner "https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-arm64"
Make it executable:
sudo chmod +x /usr/local/bin/gitlab-runner
Install as service:
gitlab-runner install
gitlab-runner start
Check the status
gitlab-runner status
gitlab-runner: Service is running
And finally, register the runner
gitlab-runner register
The runner is now registered. Go to your GitLab project under Settings > CI/CD > Runners to verify it appears.
The runner is ready. Let's build and package our iOS apps with this runner.
Create global variables TESTAPPIO_API_TOKEN and TESTAPPIO_APP_ID
Go to Settings > CI/CD > Variables > Add variable. Set the key field to TESTAPPIO_API_TOKEN (you can name it whatever you want — we will refer to it in the pipeline script). Put the API token in the value box. Uncheck Protect variable and check Mask variable. Then add the TESTAPPIO_APP_ID variable the same way.
Create the ExportOptions.plist file
A sample ExportOptions.plist file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>destination</key>
<string>export</string>
<key>method</key>
<string>development</string>
<key>signingStyle</key>
<string>automatic</string>
<key>stripSwiftSymbols</key>
<true/>
<key>teamID</key>
<string>YOUR_TEAM_ID</string>
<key>thinning</key>
<string><thin-for-all-variants></string>
</dict>
</plist>
Replace YOUR_TEAM_ID with your Apple Developer Team ID. The easiest way to generate the ExportOptions.plist file is to export the IPA through Xcode. Once you've successfully exported your IPA, Xcode creates an ExportOptions.plist file that you can use for the CI pipeline.
Add the following script block to your pipeline script (.gitlab-ci.yml)
tagsstages:
- build
- archive
- upload
variables:
release: "ios"
release_notes: "My release notes here..."
notify: false
ProjectName: "myproject"
SchemeName: "myschema"
build-job:
stage: build
script:
- xcodebuild clean -project $ProjectName.xcodeproj -scheme $SchemeName
- xcodebuild test -project $ProjectName.xcodeproj -scheme $SchemeName -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.5'
tags:
- ipa-macos
archive-job:
stage: archive
script:
- xcodebuild clean archive -archivePath build/$ProjectName -scheme $SchemeName
- xcodebuild -exportArchive -archivePath "build/$ProjectName.xcarchive" -exportPath "build/$ProjectName.ipa" -exportOptionsPlist "ExportOptions.plist"
artifacts:
paths:
- build/$ProjectName.ipa
tags:
- ipa-macos
upload-job:
stage: upload
before_script:
- export INSTALL_DIR=$CI_PROJECT_DIR
- curl -Ls https://github.com/testappio/cli/releases/latest/download/install | bash
script:
- $CI_PROJECT_DIR/ta-cli publish --api_token=$TESTAPPIO_API_TOKEN --app_id=$TESTAPPIO_APP_ID --release=$release --ipa=$CI_PROJECT_DIR/build/$ProjectName.ipa --release_notes=$release_notes --notify=$notify --source="Gitlab"
tags:
- linux
Things to consider
- Make sure to set the variable
ProjectNamewith the name of your Xcode project. If you're using a different scheme than the default, make sure you pass in the properSchemeNametoo (the default is the same as theProjectName). - In the
xcodebuild testcommand, the-destinationoption is set to launch an iPhone 15 image running iOS 17.5 in the Simulator. If you want to run a different device (iPad, for example), you'll need to change this. - If you're using a workspace rather than a project (e.g., because your app uses Cocoapods), change the
-project ProjectName.xcodeprojoptions to-workspace WorkspaceName.xcworkspace. Runxcodebuild --helpin the Terminal to explore more build options.
Here is the sample project we used for demonstrating the process.
Android
It's much easier for Android projects — no custom runner or codesign setup is required.
Create global variables TESTAPPIO_API_TOKEN and TESTAPPIO_APP_ID
Go to Settings > CI/CD > Variables > Add variable. Set the key field to TESTAPPIO_API_TOKEN (you can name it whatever you want — we will refer to it in the pipeline script). Put the API token in the value box. Uncheck Protect variable and check Mask variable. Then add the TESTAPPIO_APP_ID variable the same way.
Add the following code snippet to your pipeline script (.gitlab-ci.yml)
image: eclipse-temurin:17-jdk
variables:
ANDROID_COMPILE_SDK: "34"
ANDROID_BUILD_TOOLS: "34.0.0"
release: "android"
release_notes: "My release notes here..."
notify: false
# install the android sdk
before_script:
- apt-get --quiet update --yes
- apt-get --quiet install --yes wget tar unzip lib32stdc++6 lib32z1
- wget --quiet --output-document=android-sdk.zip https://dl.google.com/android/repository/commandlinetools-linux-8092744_latest.zip
- unzip -d android-sdk-linux android-sdk.zip
- mv android-sdk-linux/cmdline-tools android-sdk-linux/latest
- mkdir -p android-sdk-linux/cmdline-tools
- mv android-sdk-linux/latest android-sdk-linux/cmdline-tools/
- echo y | android-sdk-linux/cmdline-tools/latest/bin/sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}" >/dev/null
- echo y | android-sdk-linux/cmdline-tools/latest/bin/sdkmanager "platform-tools" >/dev/null
- echo y | android-sdk-linux/cmdline-tools/latest/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS}" >/dev/null
- export ANDROID_HOME=$PWD/android-sdk-linux
- export PATH=$PATH:$PWD/android-sdk-linux/platform-tools/
- chmod +x ./gradlew
# temporarily disable checking for EPIPE error and use yes to accept all licenses
- set +o pipefail
- yes | android-sdk-linux/cmdline-tools/latest/bin/sdkmanager --licenses
- set -o pipefail
stages:
- build
- upload
assembleDebug:
stage: build
script:
- ./gradlew assembleDebug
artifacts:
paths:
- app/build/outputs/
upload-job:
stage: upload
before_script:
- export INSTALL_DIR=$CI_PROJECT_DIR
- curl -Ls https://github.com/testappio/cli/releases/latest/download/install | bash
script:
- $CI_PROJECT_DIR/ta-cli publish --api_token=$TESTAPPIO_API_TOKEN --app_id=$TESTAPPIO_APP_ID --release=$release --apk=$CI_PROJECT_DIR/app/build/outputs/apk/debug/app-debug.apk --release_notes=$release_notes --notify=$notify --source="Gitlab"
Related Articles
Tip:TestApp.io mobile appshare links
Need help? Contact us — we're happy to assist!