Want to Automate Code Reviews? Set Up Danger JS for Unsupported CIs | by Ardy Gallego Dedase | May, 2022

With Google CloudBuild as an example

You can skip this section if you are already familiar with Danger JS.

Danger JS is an open-source build tool that allows software developers to automate common code review chores. Using Danger JS, we can automatically run a set of rules against your Pull Request (PR) and leave a code review comment. It automates repetitive and trivial code review comments like “This PR is large, please consider breaking down so we can effectively review it” or “Please update the changelog file”. It helps developers to focus on reviewing the problem that the PR is trying to solve.

Automatically handle code review chores.

An example code

To better understand how it works, let’s take a common use case as an example: What if we want to leave a comment if a pull request is too big?

You can write a JS function using Danger JS to accomplish this use case:

If the number of lines changed in a pull request is more than the arbitrary bigPRThreshold value, then leave a “warning” comment in the pull request.

Setting up Danger JS

Below, I summarize the steps involved in setting up Danger JS in your CI.

  • Install Danger by runningyarn add danger —dev or npm install --save-dev danger.
  • Create a dangerfile and include it in your repository’s root folder. It can be dangerfile.ts or dangerfile.js.
  • Set up a GitHub bot and/or generate a GitHub token with sufficient access to comment, approve or reject a Pull Request.
  • Refer to this list of setup instructions that you’ll need to follow depending on the CI that you use.

For example, if you want to use Danger JS within your company’s internal CI or Google Cloud Build. Google Cloud Build is not a supported CI at the time of writing.

We have two options for that:

  • Contribute back to Danger.
  • Use Danger’s “manual mode”, which is what we will cover in the next sections.

Start by installing danger. We will use npm for our example.

npm install --save-dev danger

Import what we need from our Danger package.

import {danger, warn, markdown} from 'danger';

Create our dangerfile.ts. We will implement the following functions:

  • reviewLargePR()Same as our previous code example
  • ensurePRHasAssignee() Fail the PR if there is no assignee.

Our dangerfile.ts:

We can test our dangerfile locally by using danger-pr.js. This will not leave a comment on the pull request. It will print out the expected PR comments in the terminal. This option allows us to debug our dangerfile locally without spamming comments on a real PR.

Run the following command in your repository’s root folder, in the same folder as the dangerfile.ts:

# Your GitHub API token
export DANGER_GITHUB_API_TOKEN=<yourtoken>
node_modules/danger/distribution/commands/danger-pr.js https://github.com/danger/danger-js/pull/1192

In our example above , we are using a public PR to Danger JS’s GitHub repository. At the time of writing, this PR has around 7,000~ lines changed. This number is “large” according to our Dangerfile’s rules.

Our output will show that the PR is large:

Danger can support CIs that are not on their current supported list by using their “manual mode”.

Running Danger’s CI command

Now that our dangerfile works as expected, let’s run using danger-ci locally. This command will leave a comment on the PR that we specify.

ℹ️ Make sure that you have configured the required GitHub access when running the CI command.

Set the environment variables

We can enable manual mode by setting the required environment variables.

Set your CI’s name:

# Replace with your unsupported CI's name, e.g. CloudBuild
export DANGER_MANUAL_CI=<UNSUPPORTED_CI_NAME>

Specify your GitHub repository:

# Replace with your GitHub repository
export DANGER_MANUAL_GH_REPO=<githuborg/githubrepo>

Set your GitHub API access token in case you haven’t yet:

# Replace with your GitHub API token
export DANGER_GITHUB_API_TOKEN=<yourtoken>

Run the Danger CI command

Now that we have set the required environment variables👆, run the danger-ci command:

DANGER_MANUAL_PR_NUM=<PR Number> node_modules/danger/distribution/commands/danger-ci.js

The environment variable DANGER_MANUAL_PR_NUM is the PR number of the PR that we want Danger to review. For example, if your PR is: https://github.com/danger/danger-js/pull/1192the environment variable will be DANGER_MANUAL_PR_NUM=1192.

An example

ℹ️ Note that we have the option to write a shell script that runs all the commands in this example, instead of running the commands one at a time.

Let’s take a public GitHub Pull Request that I’ve set up as an example.

Let’s set up our environment variables:

# Replace with your unsupported CI's name, e.g. CloudBuild
export DANGER_MANUAL_CI=MyCI
# Replace with your GitHub repository
export DANGER_MANUAL_GH_REPO=ardydedase/danger-example
# Replace with your GitHub API token
export DANGER_GITHUB_API_TOKEN=<yourtoken>

Then run the danger-ci command with the PR number, which is 1 in this example:

DANGER_MANUAL_PR_NUM=1 node_modules/danger/distribution/commands/danger-ci.js

In our example, the PR fails because there is no assigned user to the PR.

The PR comment on GitHub will be:

☝️ I’m using my personal GitHub token for this demo, so it’s my username that appears on the PR. Ideally, we should set up a GitHub bot.

We will perform the same steps in our unsupported CI: set the environment variables and run the danger-ci command. We will cover this in the next section. 👇

After testing our dangerfile in Step 3, we are now ready to configure Danger with our unsupported CI.

We will use Google CloudBuild as our CI in our example because:

  • At the time of writing, Google CloudBuild is not yet a supported CI in Danger JS.
  • It has a Local Cloud Builder CLI tool we can use to test our build configuration YAML locally.

Google Cloud Prerequisites

We will need our CloudBuild CLI tool installed to test our Danger build with Google Cloud locally. Please refer to the docs linked below:

CloudBuild configuration file

Let’s create our config file:

ℹ️ Replace the GITHUB_API_TOKEN with your token.

When we run cloud-build-local, dryrun is enabled by default unless we specify otherwise. This gives us the option to check our build’s syntax, saving us time to test. Let’s start by running the cloud-build-local command below to make sure that our config file has no syntax error:

cloud-build-local --config=./cloudbuild-local.yaml .

If the above command is successful, the output will be:

Let’s now set the dryrun flag to false to run the danger build locally:

cloud-build-local --config=./cloudbuild-local.yaml --dryrun=false .

👆 The above command will a few minutes to complete. Downloading the node docker image will take the most time.

A successful build will show a similar output below:

And it should leave a PR comment as well:

Now that our local configuration works as expected, we can use the same configuration in our production Cloud Build setup.

Configuration for Production environment

Our production setup is almost the same, except that we are retrieving the PR number from CloudBuild. Instead of hard-coding, we will assign $_PR_NUMBER to DANGER_MANUAL_PR_NUM.

Our Danger CI command will be:

DANGER_MANUAL_PR_NUM=$_PR_NUMBER node_modules/danger/distribution/commands/danger-ci.js

We should also store our GitHub API token in Google Cloud’s Secrets Manager or any “secrets” manager that you are using.

If we are using Google Secrets manager, we will need to update our build configuration to use it:

availableSecrets:
secretManager:
- versionName: projects/$PROJECT_ID/secrets/<my-github-token>/versions/1
env: DANGER_GITHUB_API_TOKEN

Replace <my-github-token> with your secret name.

Our build config using the Pull Request number $_PR_NUMBER and secret from Secrets Manager:

Setup CloudBuild Trigger

The last step is to configure our CloudBuild trigger to make sure that it works as expected.

In Google Cloud Console, by creating a new Trigger in CloudBuild:

While creating your trigger, make sure that you select “Pull request” as the Event. This gives our config file access to $_PR_NUMBER . If we don’t do this, $_PR_NUMBER will return an empty string.

Choose Repository as the Location for our config file. Specify the path to our build configuration file.

You can leave the rest of the input fields as they are.

That’s all we need. You now have a nice Google CloudBuild setup with automated code reviews powered by Danger JS!

ℹ️ Even though we write our Dangerfile using TypeScript or JavaScript, Danger JS can work with any codebase regardless of the programming language.

You can find the GitHub repository here for your reference:

Leave a Comment