Using a CI/CD service to build and deploy your project

Rodrigo Cavalcante
7 min readJun 1, 2017

A few months ago I started reading about CI/CD but I never had an opportunity to used it on a project since last month where I started a new personal project with my friend.

But what is CI/CD?

CI or Continuous Integration is the ability to keep integrating code in your application, this means to push new features and/or fixes to your repo every day/week or any other period you want to.

continuous integration (CI) is the practice of merging all developer working copies to a shared mainline several times a day (wikipedia)

CD or Continuous Delivery is the ability to continuous release new versions of your software safely and quickly.

Continuous delivery (CD) is a software engineering approach in which teams produce software in short cycles, ensuring that the software can be reliably released at any time (wikipedia)

Continuous Delivery is the ability to get changes of all types — including new features, configuration changes, bug fixes and experiments — into production, or into the hands of users, safely and quickly in a sustainable way. (continousdelivery.com)

To achieve this we will use a versioning system like git (gitlab, github, bitbucket) that developers can push their work into a release branch and them our CI service will pull this code, build, test and deploy our app to beta users.

We started to look for CIs on google and found some interesting services like Travis, Buddybuild, Bitrise, CircleCI and Jenkins.

Travis is free for open source project has a nice UI, but this is a private project and Travis don’t have free plans for private repos.

Buddybuild is our favorite, We’ve used it before and it works for free on private projects. The negative side is the long waiting time on building queue for free users, but we can live with that.

We did not try Bitrise, CircleCI or Jenkins.

For this project, we decided to use Gitlab that supports private repos and Buddybuild.

Setting up your branches

We have two branches that will be used to generate apps to our users. We have a developer branch that will generate a beta app and a master branch that will generate an app to AppStore. You can have how many branches you want e.g. a preproduction branch or an alpha testers branch.

With that in mind, we need to create and protect theses branches so no one can push some code to it and eventually break the app.

First, we need to create a new branch you can go to your repo and select branches and them new branch.

Create a new branch

To protect a branch you need to select settings go to repository scroll down to Protected Branches. Select a branch and select the roles that will be able to merge and to push. After that, your branch will get a protected tag on it.

protected branch

Protecting a branch means that no one can push code directly to it, only via Pull Request (PR) or Merge Request (MR), which means that on this project we are going to develop a new feature/fix in another branch, once it’s finished we push it to Gitlab and them create an MR to merge this new feature/fix into developer.

Building our app

We choose Buddybuild as CI service because it:

  • has an easy integration with Gitlab.
  • is free for private repo even though we have to wait a long time for builds (sometimes the waiting time is about one hour).

When you create your account on Buddybuild you can choose to link it with gitlab, github or bitbucket. Choose your git service and it will automatically scan for apps. It has a nice and easy flow to setting up your project and once it is done you’ll see your branches.

branches list on buddybuild

If you select More -> App Settings you can configure your branches settings and more.

First, we want to disable push on any branch that is not developer or master because we are only going to build MR/PR not pushes. If you want to build pushes fell free to enable this option.

Disable pushes on branches

There’s a lot of configurations that you can setup on Buddybuild. I recommend you to read the docs if you want to learn more about it.

Now every time you create a new MR/PR Buddybuild will be triggered and will build your app. It will clone your repo, run tests and custom scripts if everything is ok the build will be successful.

Every time a build triggers gitlab is notified and you’ll see that there’s a pipeline running.

Testing your app

Testing everything on your app it’s very important when using a CI/CD service because you need to make sure everything is working as expected. We need to tell Buddybuild that our project has a test target and that it should run our tests on every build. To do that just enable tests on branches.

You can also select devices on settings.

Enable tests on branches

It generate a coverage report by files like the image below but to do this you need to enable Gather coverage data on your project scheme (Xcode).

Test coverage generate by buddybuild

Scripting

Running custom scripts are available on Buddybuild in three phases during the building process.

  • after it clones your repo.
  • before starts building.
  • after the build is finished.

To run a custom script after the cloning process is finished you need to create a file at your repo root directory and name it buddybuild_postclone.sh.

We are using swiftlint on this project which is a tool to enforce Swift style and conventions. So we want to break the build if the developer does not follow a certain rule to do that we can create a custom post clone script.

It will install swiftlint if needed and scan our project folder.

Buddybuild coverage report is not good enough, it shows classes but not the lines missing.

So we decided to use codecov which is a coverage service that shows your tests, classes that are being tested, missing functions and more. It is free for one private repo per account.

To use it in a private repo you need to setup an environment variable. It’s very easy to do on buddybuild you just need to go to settings -> Environment Variables and create a new variable with your codecov token. I called mine CODECOV_TOKEN

Finally, you can create a post build script by creating a buddybuild_postbuild.sh file at the same directory of your .xcodeproj file.

Don’t forget to replace 'scheme' by your scheme.

If you want to run a pre building script just create a script file next to your .xcodeproj named buddybuild_prebuild.sh. For example, you can use this script to add a key to your plist file.

Building and deploying

We set up Buddybuild to build our app every time we push code to developer via MR now let’s deliver our app to beta testers.

At Deployments, you can enter your iTunes connect account and Buddybuild will add new devices UUID for you. If you don’t, you need to add every new device manually.

You also can create beta groups to deploy your app via email and select how this deploy will be done like each build, scheduled or manually which branch and scheme that will be deployed.

Deploy group

You can create different groups for each branch. For example an alpha group with developer and a beta group with master.

Badges

Buddybuild and Codecov have badges that you can add to your readme file so your developers can visually see its status.

Codecov and Buddybuild Badges

To add them and create a cool readme file you can go to settings, look for badges and copy and paste the markup code. It’s something like:

[![codecov](https://codecov.io/gl/xxxxxxxx/ios/branch/developer/graph/badge.svg?token=xxxxxxxx)](https://codecov.io/gl/xxxxxxxxxx/ios)[![BuddyBuild](https://dashboard.buddybuild.com/api/statusImage?appID=xxxxxxxx&branch=developer&build=latest)](https://dashboard.buddybuild.com/apps/xxxxxxxxxxx/build/latest?branch=developer)

If you have any question just let me know in comments. See ya!

--

--