Bitbucket + Bitrise: Configuring Continuous Integration for an iOS app
By configuring a CI tool with your app, you open up a world of possibilities for your development and maintenance efforts. Read on to get started!
Join the DZone community and get the full member experience.
Join For FreeWhen iOS applications start growing, at some point it becomes essential to have a quick develop-release-test feedback loop. You can create this loop by doing everything manually, but it can be much quicker and more advanced if you use Continuous Integration (CI) tools.
With a CI tool, you can build up a history of releases and quickly see which build contained what. You can run tests for every build automatically and catch some inevitable bugs. You can have consistency in your release notes. And you can streamline your release cycles, which automates your checklists.
Sound interesting? Let’s try to build this feedback loop using Bitbucket Webhooks, Bitrise, and fastlane.
Deployment Flow
The flow we are going to use for our Continuous Integration is going to look like this:
- Create and merge a Pull Request in Bitbucket.
- Bitbucket performs a “Webhook” HTTP request to Bitrise.
- Bitrise starts building the process and launches fastlane.
- fastlane builds the app and sends it to App Store Connect.
- App Store Connect processes the build, and it becomes available in TestFlight.
Bitbucket Webhooks and Git Branching Model
Each deployment starts from us creating a Pull Request.
Let’s say your team is using a master git branch for code in the releasable state. It also makes new releases by merging this master branch to the release branch.
The following section describes how to create a Webhook manually. However, if you use Bitrise, it can create a Webhook for you automatically, so, feel free to skip to the Bitrise section.
Manual Webhook Configuration
Next, let’s configure Bitbucket Webhooks so that whenever someone pushes to the release branch or merges a Pull Request to the release branch, the Webhook is triggered.
To do that, go to your Bitbucket repository and click “Settings” in the side menu. Then click “Webhooks” in the “Workflows” section and then click “Add webhook.”
Fill out Title, URL (see below), set Status to Active, and select “Choose from a full list of triggers” for Triggers. The triggers we are going to use are:
- Repository: Push
- Pull Request: Created, Updated
To get the URL for our Webhook:
- Head over to Bitrise, create a new app.
- Open the Dashboard -> Your app -> Code tab.
- Scroll to the Incoming Webhooks section and click Setup Manually.
- Select “Bitbucket Webhooks” and copy the Webhook URL
Bitrise and Automatic Webhook Configuration
Bitrise is a platform for Continuous Integration. You can configure different deployment “workflows” in it and have the Bitrise servers build and publish your application. Here are the steps to create a new deployment workflow for our CI setup.
- First sign up in Bitrise, go to the Dashboard, and click “Add New App.”
- Select “Private” if you want your config and logs to stay private.
- Select Bitbucket and connect it to your account.
- Click “Auto-add SSH key” or configure SSH access manually.
- Enter `release` as the branch name in the “Choose branch” step.
- In the Project build configuration, select “fastlane” and check that Fastlane lane is set to `ios release.`
- Select the stack that you normally use to build your app or just the latest available Xcode/macOS and click Confirm.
- In the last step, “Webhook setup,” click “Register Webhook for me.”
The last step creates a Webhook in Bitbucket, so you don’t have to do anything manually. You can head over to the Bitbucket repository and check the Webhook configuration in Settings -> Webhooks.
In our setup, we are going to use fastlane to build and publish the app to App Store Connect.
Fastlane Configuration
Fastlane is a set of tools for automating development and release processes.
Follow this guide to install fastlane: Setup – fastlane docs.
In short, you need to install Xcode development tools:
xcode-select --install
and then install fastlane via RubyGems
sudo gem install fastlane -NV
or via brew:
brew cask install fastlane
Then open the working directory of your app in the Terminal and initialize fastlane.
cd /path/to/your/app
fastlane init
Select “3. Automate App Store distribution”
Then follow the configuration requests. Fastlane can create and configure the new App Id for you and create a sample deployment “lane.” A lane is just a collection of steps, required to complete some scenario.
Once the configuration is finished, open the Fastfile which has been created and configure the first deployment script. Fastlane has large set of tools for automating various processes like code signing, uploading of screenshots, running tests ,and so on. However, we are going to start with a simple setup:
default_platform(:ios)
platform :ios do
desc "Push a new release build to the App Store"
lane :release do
build_app(scheme: "CITest")
upload_to_app_store(force: true, skip_metadata: true, skip_screenshots: true)
end
end
The “release” lane will:
- perform a build of your project —
build_app(scheme: “CITest”)
. - Upload the resulting ipa file to App Store Connect —
upload_to_app_store
. In this guide, we are skipping the fastlane metadata upload.
You can test your setup by opening your project directory in the Terminal and running a fastlane release:
cd /path/to/your/app/directory
fastlane release
Code Signing
If you see problems with code signing, start here: Troubleshooting – fastlane docs. You can use fastlane match to manage code signing, but be careful: if you already have generated Certificates and Provisioning Profiles, match can break things. However, if it’s a completely new setup or you don’t care much about the existing profiles, match is going to speed things up considerably.
We’ll use fastlane match in our example:
cd /path/to/your/app/directory
fastlane match development
fastlane match adhoc
fastlane match appstore
Then open Xcode, turn off Automatic code signing, and select the provisioning profiles that match has generated.
After that, we can add match to our Fastfile:
default_platform(:ios)
platform :ios do
desc "Push a new release build to the App Store"
lane :release do
match(type: "appstore", readonly: true)
build_app(scheme: "CITest")
upload_to_app_store(force: true, skip_metadata: true, skip_screenshots: true)
end
end
Finishing the Bitrise Setup
Bitrise is building the project on its servers which don’t have any of your passwords and credentials required to code sign and upload your app to App Store Connect. Therefore, we’ll have to share some of those; precisely these two:
- Login/password for App Store Connect user.
- Password to decrypt your match repository (if you use match).
The App Store Connect user doesn’t have to be the one you use to control your apps. You can create a new user in App Store Connect, which only has access to the app you automate and has at least a Developer role.
Once you set your new App Store Connect user, head over to Bitrise and open Workflow Editor tab and then Secrets. Add two new secrets:
ITUNES_CONNECT_USER
and ITUNES_CONNECT_PASSWORD
with App Store credentials for this new user. Plus, put the same password into the FASTLANE_PASSWORD
secret.
If you use match, add one more secret called MATCH_PASSWORD
with the password you used to encrypt the match repository.
Conclusion
That should be it. Try to create a new Pull Request and merge it and see if Bitrise triggers the new build. If everything goes well, you will see the new build in TestFlight and will be able to select it for your new iOS app version.
There is much more that you can do with automated deployments, such as:
- Testing using a fastlane scan.
- Automated build number incrementation.
- dSYM uploads to Crashlytics_Raygun_etc.
However, start with simple things first. I hope this guide helps you!
Published at DZone with permission of Ivan Parfenchuk. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments