
How GitLab and fastlane build, sign, and publish iOS applications to the App Store.
Recently we had with GitLab and . Here we will see how to build and launch an iOS app and publish it to TestFlight. Check out how cool it is , take the build, and get an update of the trial version of the application on the same iPad Pro where I developed it.
Here we will take , with which I recorded the video.
A few words about Apple Store configuration
We need an application in the App Store, distribution certificates, and a provisioning profile to tie everything together.
The most challenging part here is setting up signing rights in the App Store. I hope you can figure this out on your own. If you’re a beginner, I will point you in the right direction, but we won’t discuss the intricacies of managing Apple certificates here since they are constantly changing. This post will help you get started.
My applications
You need an application in App Store Connect to have an ID for the configuration .xcodebuild. The profile and application ID combine code builds, pricing, and availability, as well as TestFlight configuration for distributing test applications among users. Don’t make public testing; private testing is sufficient if you have a small group, simple setup, and don’t need additional permissions from Apple.
Provisioning profile
In addition to the app setup, you need distribution and development keys for iOS created in the Certificates, Identifiers & Profiles section in the Apple Developer console. All these certificates can be combined in the provisioning profile.
Users who will undergo authentication need the ability to create certificates, otherwise at the stages of you will see an error.
Other options
Besides this simple method, there are other ways to configure certificates and profiles. So, if you're working differently, you may need to restructure. The most important thing is that you will need a configuration. .xcodebuild, which will point to the necessary files, and the keychain must be accessible on the build computer for the user under whose name the runner operates. We use fastlane for code signing, and if there are issues or you want to learn more, check their documentation on code signing. .
In this example, I use the approach , but for real-world applications, perhaps .
Preparing GitLab and fastlane
Setting up the CI Runner
After gathering all this data, we proceed to configure the GitLab runner on a MacOS device. Unfortunately, building iOS applications is only feasible on MacOS. But this could change, so if you're waiting for progress in this area, keep an eye on projects like and , and our internal task .
Configuring the runner is very simple. Follow the current .
Note: The runner must use the executable shell. This is essential for building iOS on macOS to operate directly as a user, rather than through containers. If you are using shell, building and testing are done under the runner's user identity, directly on the build host. This is not as secure as using containers, so it's advisable to review the , to not miss anything.
sudo curl --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64
sudo chmod +x /usr/local/bin/gitlab-runner
cd ~
gitlab-runner install
gitlab-runner startThe Apple keychain must be set up on this host with access to the keys that Xcode needs for building. The easiest way to test this is to log in as the user who will run the build and try to perform a manual build. If the system prompts for access to the keychain, choose 'Always allow' so that CI works. It might be worth logging in and monitoring the first couple of pipelines, to ensure they no longer request keychain access. The trouble is that Apple doesn't make our job easier with the automation mode, but once you set it up, everything works fine.
fastlane init
To use fastlane in the project, run fastlane init. Just follow the , especially the section about , as we need a fast and predictable launch through the CI pipeline.
In the project directory, run these commands:
xcode-select --install
sudo gem install fastlane -NV
# Alternatively using Homebrew
# brew cask install fastlane
fastlane initfastlane will prompt for basic configuration and then create a fastlane folder in the project containing three files:
1. fastlane/Appfile
This is straightforward. Just ensure that your Apple ID and App ID are correctly specified.
app_identifier("com.vontrance.flappybird") # The bundle identifier of your app
apple_id("your-email@your-domain.com") # Your Apple email address2. fastlane/Fastfile
Fastfile defines the build steps. We use many built-in capabilities of fastlane, so this part is also clear. We create a single line that fetches the certificates, builds the app, and uploads it to TestFlight. You can break this process into different jobs if needed. All of these operations (get_certificates, get_provisioning_profile, gym and upload_to_testflight) are already included in fastlane.
Actions get_certificates and get_provisioning_profile are related to the signing approach . If you are using or something else, make adjustments.
default_platform(:ios)
platform :ios do
desc "Build the application"
lane :flappybuild do
get_certificates
get_provisioning_profile
gym
upload_to_testflight
end
end3. fastlane/Gymfile
This is an optional file, but I created it manually to change the default output directory and place the output in the current folder. This simplifies CI. If you're interested, read about gym and its parameters in .
https://docs.fastlane.tools/actions/gym/Our .gitlab-ci.yml
So, we have a CI runner for the project, and we're ready to test the pipeline. Let's see what we have in .gitlab-ci.yml:
stages:
- build
variables:
LC_ALL: "en_US.UTF-8"
LANG: "en_US.UTF-8"
GIT_STRATEGY: clone
build:
stage: build
script:
- bundle install
- bundle exec fastlane flappybuild
artifacts:
paths:
- ./FlappyBird.ipaEverything is great! , use the strategy clone with the executable shell, so we have a clean workspace for each build, and simply call flappybuild fastlane, as shown above. In the end, we obtain a build, sign it, and deploy the latest build to TestFlight.
We also get the artifact and save it with the build. Note that the format .ipa is a signed ARM executable file, which does not run in the simulator. If you want output for the simulator, just add a build target that produces it, and then include it in the artifact path.
Other environment variables
Here are a couple of environment variables on which everything depends.
FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD and FASTLANE_SESSION
Authentication for the App Store and uploading to TestFlight requires authentication for fastlane. To do this, create an application-specific password that will be used in CI. Details .
If you have two-factor authentication, create a variable FASTLANE_SESSION (instructions are there too).
FASTLANE_USER and FASTLANE_PASSWORD
To you called the profile initialization and certificates on request, you need to set the variables FASTLANE_USER and FASTLANE_PASSWORD. Details . This is not necessary if you are using a different signing method.
In conclusion
You can see how all this works .
I hope this was helpful and inspired you to work with iOS builds in a GitLab project. Here are more for fastlane, just in case. You might want to use CI_BUILD_ID (for incremental builds) to .
Another cool feature of fastlane is for the App Store, which are very easy to set up.
Share your experiences in the comments and share ideas for improving GitLab for iOS application development.
Source: habr.com
