Create PR Builder in bitbucket, DangerJS and Jenkins
Tags: devops, codequality, javascript, git
Published: 2021-01-23 04:48:41

## 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](https://danger.systems/images/dangerjs-screenshot-2e2a9281.png)

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`
```typescript
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();
```   

`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`
```json
    "scripts": {
      "danger": "danger",
    },
```
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

```bash
export DANGER_BITBUCKETCLOUD_OAUTH_KEY=<OauthKey>
export DANGER_BITBUCKETCLOUD_OAUTH_SECRET=<OauthSecret>
export DANGER_BITBUCKETCLOUD_UUID={<uuid>}
```
Now you can test run dangerJS on a PR:

```bash
    yarn danger pr https://bitbucket.org/<org>/<repo>/pull-requests/<id>/
```

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)

```bash
export DANGER_FAKE_CI="YEP"
export DANGER_TEST_REPO='<org>/<repo>'
```
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:
```bash
#!/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
```
`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.

{% collapsible 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`.

{% endcollapsible %}
----------

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