Keep your codebase cleaner — Pt. I Danger Gitlab setup

Radim Halfar
INLOOPX

--

Ever wondered how to simply achieve a cleaner codebase? I will show you our setup in which we use Danger as a great tool to improve our code reviews and simplify the merge requests.

The long way to danger

Danger wasn't our first choice to improve code reviews and general code style. I have to be honest, we initially picked Sonarqube in community edition up. We struggled with the setup though, and as soon as we got to the point when everything was working, a new version came out and we had to start from the beginning. That was a deal breaker for us as the costs grew to overcome the benefits. I accidentally came across Danger which surprised me a lot. The benefits of Danger are numerous, however, and below I will highlight the 2 most valuable ones.

  • Intuitive setup & maintenance
  • Community driven development of plugins which are easy to extend or develop on our own

Danger was initially developed only for github, but luckily gitlab support was added however the guide for gitlab is hard to follow.

Gitlab CI setup

The setup is described on the Danger web however there are couple of issues you might come across trying to set it up.

  1. The DANGER_GITLAB_API_TOKEN is the access token generated on a newly created user. Make sure you check api and if you would like to read information about authors, reviewers and further info, also check the read_user. If not, you can't read useful information from the /user api if needed. (You can definitely create new access token later, however who would like to change it again and again)
  2. The command to launch Danger is danger however you need to install danger-gitlab gem.
  3. It isn't as simple as just installing danger-gitlab on your machine. You will struggle a lot finding the right version of everything. Follow the below guide for clean and easy setup.

This setup is intended for Gitlab-CI, Gitlab v11+ community edition (I guess it will also work for EE, however I can't confirm it).

Creating an image

First of all you should know the basics of Gitlab-CI, Docker and DevOps. If these are new for you, go ahead and go through the basics.

We use our own DevOps CLI for deployment and thus I will demonstrate the setup using our CLI and Docker on Node.

First of all you need to create a project (either locally or using git) to hold your image for Danger.

In your newly created project create a Dockerfile in which you will specify all the dependencies that will be installed. I use swiftlint docker image as the base image because in the next post I will continue the setup by using various plugins. However if you don't like the base to be swiftlint image, you can pick ubuntu image from the docker hub and continue using it. It may require more dependencies to be installed, so you can compare the image with the base Dockerfile of swiftlint image to have a working setup.

Dockerfile

As you may see, there are ENV variables specified. If you specify it to the image directly, you don't need to specify it on a project basis. You might notice the git upgrade in the steps. This was a very nasty issue for us since the diff computed by Gitlab differed from the diff computed diff by git installed inside image, which was an earlier version and counted the moved files as separate deletions/additions. It's wise to check all the dependencies and their corresponding versions installed on your image and on Gitlab. If it differs, it might produce different results during the analysis. If you keep the dependencies consistent all over the systems it will (probably 😅) work as you expect.

To create the image with the above setup you may use Gitlab-CI or you may build it locally using Docker and upload the image to your registry. To be clear our devopscli is just a shortcut of “docker login & build & push”.

.gitlab-ci.yml

This setup allows you to create an image which will be deployed to your registry. To use it in your project you have to specify Dangerfile which defines rules to be applied to check the merge request. As the job will finish, you should see the image in the registry. I named the repository internal-insights/danger thus the registry name is registry.inloopx.com/internal-insights/danger. If you don't see the registry in the gitlab, you should visit registry setup page.

Registry page in your project

Project setup

The Danger image is ready. It's time to pick a proper project to test it. Open your projects root directory and create (or update) .gitlab-ci.yml file. If you are modifying the file, just add new stage to your file.

I use the image created in the previous section and specify the tag to docker to use the runner which is able to work with docker images. In the script, there is a need to specify CI_PROJECT_PATH, which is a kind of hack to force Danger to use gitlab api with the project id and not the project path because the Danger fails on finding the project if it's not specified correctly. The Danger command is extended by the option to fail on errors which basically means it fails the job if it finds any error specified by the rules in the Dangerfile. One of the last steps to make it work is defining a Dangerfile with your rules.

As you may have noticed, this Dangerfile is very simple (only to demonstrate the functionality). You can extend the file according to your needs now or stay tuned for the next post where I will dive deep into the options provided by Danger!

The final step is to add your user (the one you created during the setup described on danger.systems page) to the project members and define the DANGER_GITLAB_API_TOKEN to allow your user comment under the merge requests.

Pack your project changes into a commit and ship it to remote. Create the merge request by giving it a title and no summary, and then expect the magic.

You should end up with a failed job because of the above error discovered by Danger. To fix it simply add the summary to your merge request and rerun the job.

The basic setup for the Gitlab CI is done, however there is a plenty of room for improvements. Stay tuned for improvements on image setup, plugin integrations and custom the rules setup. I will tell you much more about rules we use and why we use them.

--

--