At Yoox Net-A-Porter(YNAP), we use Swift for building iOS apps. Swift is a modern, fast and type-safe programming language. In the iOS app development, getting an instant feedback on Swift code is essential and Swift being type safe language the most of the safety checks has been done by Swift compiler at compilation phase. However, there are many clean coding practices like syntax check, styling etc needs to be enforced explicitly. In this post, we will explore how we have automated most of the Swift code review process using Danger, Swiftlint and Travis CI in our iOS apps at YNAP.
Swift Code Review before Danger
The process of code reviews can be difficult especially with Swift being a new programming language. The SwiftLint is the de facto tool for linting the Swift source code by enforcing rules suitable for a specific team or project. We implemented SwiftLint on TravisCI which is our Continuous Integration(CI) Server, using some best practices as mentioned in our previous blog post. Our SwiftLint configuration has some strict rules and we used to run SwiftLint as part of Xcode build phase so that developers can see the warnings or errors in the Xcode itself while development. However, on CI we don’t want to wait until CI build reaches to running Xcode build phase script. We wanted the feedback on our code as soon as build starts so we needed a mechanism to give early feedback on whenever CI build runs. We also wanted that feedback provided by SwiftLint should be visible on pull request so that we might take instant action. That’s where Danger comes in the picture.
- Check for big Pull Requests especially if more than 500 line of code
- Check if unit tests added as part of Pull Request if application code has been changed
- Check that Pull Request has a label
- Check that Podfile or Podfile.lock updated if so ignore that big PR
These are the pretty basic checks we can easily do with Danger but the real power of danger comes in a picture with SwiftLint plugin for Danger, where all the SwiftLint rules are applied to code review process in the pull request. Danger can put comments on the pull request wherever SwiftLint warnings or errors found.
Our setup at YNAP
Now that we have covered the basics of the Danger and swiftLint plugin, Let’s talk about how we set that up on our Travis CI server. We needed the following things to setup Danger on Travis CI.
- Dedicated Bot account/Personal Access Token on GitHub
We created a dedicated bot account on GitHub which can able to put comments on Pull Requests. In order to do that, we also need to create Github Personal Access Token with write access to give the Bot an ability to comment on the pull requests. This personal access token can be configured as environmental variable DANGER_GITHUB_API_TOKEN in the Travis CI setting for an iOS project.
- Install Danger and SwiftLint Danger Plugin on Travis CI
Once we have Github access token, next thing we have updated our Travis configuration .travis.yml to install the Danger and SwiftLint Danger plugin in the before_script phase as shown below.
As macOS images of Travis CI are preconfigured with Ruby and RVM, we just need to install the Rubygems as part of the script to install Danger and swiftLint plugin for Danger.
Note: Danger can be run on any CI server as mentioned in the documentation here
- Run Danger on Travis CI
Once installed, it’s fairly easy to run Danger on Travis CI with just command danger to execute all the rules. This will run all the checks configured in the Dangerfile for our project. However, there was a tricky situation, as we are using build matrix feature of Travis CI to run multiple builds in parallel. With build matrix, Danger will execute on every parallel build resulting in putting comments multiple times on the pull requests. We need to find the way to allow Danger to comment on pull requests only once per matrix. We have achieved this by conditional build execution with Environment Variable DANGER=ALLOW in Travis CI. The configuration looks like this
- gem install fastlane --no-ri --no-rdoc --no-document
- gem install danger --no-ri --no-rdoc --no-document
- gem install danger-swiftlint --no-ri --no-rdoc --no-document
- if [ $DANGER == "ALLOW" ]; then
./Pods/SwiftLint/swiftlint lint --config .swiftlint-ci.yml;
- osx_image: xcode10
env: CI_BUILD_TARGET='nap' CI_DEVICE='iPhone X (12.0)' DANGER="ALLOW"
- osx_image: xcode10
env: CI_BUILD_TARGET='nap' CI_DEVICE='iPad Air 2 (12.0)'
As you can see that, we have set up the variable DANGER=”ALLOW” only once in the build matrix. Also, in the before_script we have conditional execution of Danger when that environmental variable is set. This way we have avoided the issue of Danger commenting multiple times.
That’s it’s! we have configured Danger to run on our Travis CI server.
Automated Code Reviews
Now let’s see how Danger is doing automated code reviews and how it helps the team to fix coding errors quickly. Whenever a developer creates a pull request, the build triggers on Travis CI and Danger runs as part of the before_script phase. As soon as Danger finished running, it puts comments on the pull requests or reports any issues on the pull requests. e.g If we forget to add unit tests then we get notified on pull requests
Danger will also notify code styling issues like whitespaces, extra lines etc.
Now that, we have a fully automated code review process for Swift. Our Github bot is reviewing all our pull requests, if there any comments reported by the bot which needs to be fixed as part of pull request. Once Danger is happy then pull request is approved.
With automated code review process, we have achieved several benefits including
- Developers no longer putting trivial comments on the pull requests and focus on much detailed and logical code review. This automated approach saved developer time in the code review process.
- There are no new warnings or issues being introduced in the Swift code which improves code quality.
- As we added a rule to check if tests are added as part of pull request, our code coverage getting much better day by day which boosted developer confidence that we are not adding any tech debt in the code and we have well-tested code.
With the combination of SwiftLint Danger plugin and Travis CI, we have achieved faster code reviews and improved our code quality in our apps. In the future, we are planning to add strict rules to make our code more robust and reliable. What are your experiences of automating iOS code reviews? Share in the comments below.