How to implement Danger in Swift

Danger is a build tool that checks that your pull request is following certain rules.

Danger thin ice keep off sign in front of water
Photo by Erica Nilsson / Unsplash

I recently took on a project where I'm the sole iOS app developer, which means if I make Pull Requests (PR), then I'll have to be the one reviewing my own code. This is not ideal for code quality, but I figured how can I make this better for me and asked "how can I make sure I remember best practices?" The answer was to use Danger. Danger is a build tool that checks your PRs for rules that you or your team define.

What is Danger?

Danger is a build tool that checks that your pull request is following certain rules. A rule that can be implemented is "adding a changelog entry with a pull request" or a pull request can only have so many changes. It is usually run as a step in CI/CD, Continuos Integration/Continuous Deployment so that if a rule is broken, then the build can fail and the PR cannot be merged.
Danger can work locally and in CI/CD tools like GitHub actions and BitRise. It can run in different remote git servers like GitHub, BitBucket, and Gitlab and comment on the PRs.

There are multiple types of Danger, like Danger-JS, Danger-Ruby, and Danger-Swift. In this blog, we are going to cover Danger-Swift.

How to setup Danger-Swift

Setting up Danger is really only 3 steps. The docs go a bit more in depth, but ultimately to get up and going here are the 3 steps you need.

1. Install Danger locally

I suggest using Homebrew to install Danger, so if you don't have it then get Homebrew.

Run brew install danger/tap/danger-swift

It may take a while, so just be a bit patient.

2. Create your Dangerfile

In your project's root repo, add the file Dangerfile.swift. In that file include the following:

import Foundation
import Danger

let danger = Danger()

let allSourceFiles = danger.git.modifiedFiles + danger.git.createdFiles

What have you done? Well, you've imported danger and created a constant that holds all the git files. Now, if you wanted to see if a certain file has been changed, then you can use  .contains("filename.extension)" on the allSourceFiles and then output if it has been changed or not in a comment on the pull request or in your terminal if running locally. Here's an example of checking if Changelog.md has changed.

import Foundation
import Danger  

let danger = Danger()

let allSourceFiles = danger.git.modifiedFiles + danger.git.createdFiles

let changelogChanged = allSourceFiles.contains("CHANGELOG.md")

if !changelogChanged {
  warn("No CHANGELOG entry added.")
}

What else can you do? Well, you can also:

  • fail("message goes here") - will fail the build and put the message in the table
  • message("message goes here")  - will allow you to put a message in the table
  • markdown("#message goes here") - will put markdown at the bottom of the table

3. Get a GitHub api token and export it from your .zshrc file

This step is optional, but it is the only way for it to work with private repos. Grab a GitHub token and make sure permissions are set to see your repo and add export DANGER_GITHUB_API_TOKEN='token_here' to your .zshrc file. After that, you'll be able to test locally. The only thing you need is a pull request link.

Run danger-swift pr {paste pr link without brackets} and in your terminal you should see an output something smillar to below

$ danger-swift pr https://github.com/maeganwilson/ios-template/pull/2
$ Starting Danger PR on maeganwilson/ios-template#2


Danger: ✓ passed review, received no feedback.

In the next post, I'll explain how I setup GitHub actions to run Danger and made my own Danger Bot to post on my Pull Requests.


If you have any comments about this post, then make sure to let me know on Twitter, @maeganwilson_ and follow me there.