DEV Community

Cover image for Create PR Builder in bitbucket, DangerJS and Jenkins
Piyush Kumar Baliyan for AdmitKard

Posted on • Edited on

Create PR Builder in bitbucket, DangerJS and Jenkins

AKA Making a pull request builder for bitbucket [baby-steps]

What is DangerJS?

From official website

Danger runs during your CI process, and gives teams the chance to automate common code review chores.
This happens by Danger leaving messages inside your PRs based on rules that you create with JavaScript or TypeScript.

Danger Preview from Danger website

We (at Admitkard) also recently decided to integrate DangerJS with our React + TS setup to get us messages on our Pull requests in Bitbucket.

We are using Bitbucket and there are very few articles on the web around Bitbucket+DangerJS (as Github is more popular choice). So I decided to write an article to help you through.

Let's get started.

There are four big parts of this:

  • Your repo
  • Local testing
  • Bitbucket
  • Jenkins.

Changes in Repo

Here are the step-by-step guides that we did in our (React +TS) repo. You can follow the official guide here: https://danger.systems/js/guides/getting_started.html

  1. Install DangerJS into your REPO
    yarn add danger --dev
    OR
    npm install --save-dev danger

  2. Create a dangerfile
    Create a new file dangerfile.js or dangerfile.ts
    Add following code to dangerfile

import { message, warn, fail, danger } from 'danger';
import { exec } from 'child_process';
import * as path from 'path';

// TSLint
const runTSLint = () => {
  const modifiedFiles = danger.git.modified_files
    .filter((file) => /\.ts[x]?$/.test(file))
    .join(' ');
  const tsLintExec = path.join(__dirname, 'node_modules', '.bin', 'tslint');
  const tslintCommand = `${tsLintExec} ${modifiedFiles} -t prose --project tsconfig.json`;
  const tslintOut = exec(tslintCommand, (error, stdout, stderr) => {
    if (error) {
      warn(stdout || stderr);
    }
  });
};
runTSLint();
Enter fullscreen mode Exit fullscreen mode

danger.git.modified_files is danger API for giving us modified files in the PR attached to a particular build (you can also use git API, but you will have to fiddle through finding commits in current PR).
tsLintExec is our local installation of tslint through packages
exec executes our command for tslint

tslint will fail if there are tslint errors, hence we will get error

warn will tell dangerJS to post a warning on our pull-request.

Modify package.json for dangerJS

This step is optional but it will make it easier for us to run dangerjs.
add script in your package.json

    "scripts": {
      "danger": "danger",
    },
Enter fullscreen mode Exit fullscreen mode

This is all that is needed in your repo.

To test your changes locally, you will need to setup access tokens in your bitbucket repo. So, we’ll first move to Bitbucket part


Changes in Bitbucket for DangerJS

This article is for the bitbucket cloud, but steps should be similar for the bitbucket server as well.

Get Bitbucket UUID

Get UUID of the user which DangerJS will use to post these comments (it is recommended to create a bot user for such tasks).

In bitbucket, go to your profile. Your URL will change to https://bitbucket.org/%7B<uuid>%7D/
This <uuid> is what we need.

Get Bitbucket OAuth key and secret
Now we need to set up an OAuth client for danger (so that it can post comments on your PR).

  1. Go to bitbucket settings [Profile Icon > Bitbucket Settings]
  2. Go to OAuth
  3. Add Consumer
  4. Give it a Name
  5. Give it these permissions:
    1. Repositories
      1. Read
      2. Write
    2. Pull requests
      1. Read
      2. Write

You will get a OAuth key and OAuth secret.

Thats it for now, but since we are at it. Let’s do one more change in bitbucket that we’ll need later.

Add Webhook to bitbucket

We need to add webhook so that we can trigger our jenkins jobs remotely using this webhook.

For this go to your repo

  1. Go to Settings > Webhooks
  2. Add Webhook
  3. Give it a title
  4. Give it URL https://<JENKINS_URL>/generic-webhook-trigger/invoke?token=<TOKEN>
  5. Triggers > Choose from a full list of triggers
    1. Pull Request
      1. Created
      2. Updated

That's it for bitbucket.
Now let’s test this on our local repo.


Testing DangerJS on local terminal

First, we need to configure some env variables for dangerJS. These variables basically are the bitbucket credentials that we need to provide to dangerJS.

Setting Environment Variables for DangerJS for Bitbucket

export DANGER_BITBUCKETCLOUD_OAUTH_KEY=<OauthKey>
export DANGER_BITBUCKETCLOUD_OAUTH_SECRET=<OauthSecret>
export DANGER_BITBUCKETCLOUD_UUID={<uuid>}
Enter fullscreen mode Exit fullscreen mode

Now you can test run dangerJS on a PR:

    yarn danger pr https://bitbucket.org/<org>/<repo>/pull-requests/<id>/
Enter fullscreen mode Exit fullscreen mode

You will see dangerJS output in your terminal with warnings.

To actually test how this will behave when it will integrated in your CI pipeline, an additional step will need to be done. (This step is optional)

export DANGER_FAKE_CI="YEP"
export DANGER_TEST_REPO='<org>/<repo>'
Enter fullscreen mode Exit fullscreen mode

Now run DANGER_TEST_PR='<PRid>' npm run danger ci
Danger will run and this will actually post comment on your PR


With local testing done, now its time to integrate it with Jenkins.

Integration of Jenkins with DangerJS and bitbucket

Installing required plugins

  1. Install https://plugins.jenkins.io/generic-webhook-trigger

Now making a Jenkins job for our Pull Request Builder

  1. Create a new Freestyle project in Jenkins
  2. Go to Source Code Management and choose git as SCM
  3. Add repo URL and credentials (SSH or username password)
  4. Now move to Build Triggers, and choose Generic Webhook Trigger
  5. Under Post content parameters, Add a parameter
    1. Parameter
      1. Variable: branchName
      2. Expression: $.pullrequest.source.branch.name JSONPath
    2. Parameter
      1. Variable: pullRequestId
      2. Expression $.pullrequest.id JSONPath
  6. Token: <Token> (this token has to be same as we configured in our webhook
  7. Cause: Reason for trigger (you can use Env variables and the Post Content Parameters that we configured above)
  8. Now to go Bindings
    1. Add your bitbucket credentials bitbucketDangerJSOauthKey and bitbucketDangerJSOauthSecret to jenkins credential store
    2. Also add bitbucketUserUUID to jenkins as well
  9. Go to Build

Under build add this:

#!/bin/bash
export ghprbGhRepository="<org>/<repo>"
export ghprbPullId=$pullRequestId
export DANGER_BITBUCKETCLOUD_UUID=$bitbucketUserUUID
export DANGER_BITBUCKETCLOUD_OAUTH_KEY=$bitbucketDangerJSOauthKey
export DANGER_BITBUCKETCLOUD_OAUTH_SECRET=$bitbucketDangerJSOauthSecret
npm install
npm run danger ci
Enter fullscreen mode Exit fullscreen mode

ghprbGhRepository is your repo URL
ghprbPullId is our PR id that we extracted from webhook
rest are Variables that we did in our repo.

Note Jenkins might give you error Skipping Danger due to this run not executing on a PR.. This is due to missing variables.

Why the variables are named like so even for Bitbucket?
Now ghprbGhRepository and ghprbPullId, sounds like they will be required for github-pull-request-builder only, but this is not the case.

Take a look here: https://github.com/danger/danger-js/blob/master/source/ci_source/providers/Jenkins.ts

You can see under isPR, it checks for these variables (for bitbucket as well). I am going to raise a PR with dangerJS to get these variables fixed to something generic like DANGER_PR_REPO and DANGER_PR_ID.

With this, your PR will trigger Jenkins jobs and post comments on your PR if anything fails in TSLint.
You can easily extend DangerJS to post other comments as well and can control your Jenkins pipeline output.

Final Words

DangerJS provides an easy way to make it easy for the reviewer and the developer to get notified of issues in their code that can be configured with build tools.
In words of Danger

⚠️ Stop saying "you forgot to …" in code review

Top comments (0)