Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add Bitbucket Data Center support #227

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
- main

env:
IMAGE_NAME: ghcr.io/renovatebot/renovate-approve-bot-bitbucket-cloud
IMAGE_NAME: ghcr.io/renovatebot/renovate-approve-bot-bitbucket
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maxbrunet @viceice do you have any concerns about this breaking change? Ideas on how to unbreak it for users, or alert them?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no way to unbreak.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we probably should publish both images for a while

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should bundle other breaking changes for v2?

And the code getting larger, TypeScript (#58) starts making more sense

FYI I do not use Bitbucket anymore, so I will not be able to help testing this


concurrency:
group: ${{ github.workflow }}-${{ github.event.number || github.ref }}
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
FROM docker.io/library/node:14.19.1-alpine@sha256:8845b4f88f64f8c56a39236648ba22946e806a6153c10911f77b70e5a2edb4ca

LABEL \
org.opencontainers.image.source="https://github.com/renovatebot/renovate-approve-bot-bitbucket-cloud" \
org.opencontainers.image.url="https://github.com/renovatebot/renovate-approve-bot-bitbucket-cloud" \
org.opencontainers.image.source="https://github.com/renovatebot/renovate-approve-bot-bitbucket" \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

repo rename should be a separate PR/ step with a major version bump.

should probably be done before this PR.

org.opencontainers.image.url="https://github.com/renovatebot/renovate-approve-bot-bitbucket" \
org.opencontainers.image.licenses="ISC"

WORKDIR /opt/app
Expand Down
47 changes: 39 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# renovate-approve-bot - Bitbucket Cloud Edition
# renovate-approve-bot - Bitbucket Edition

A job to approve Pull Requests from [Renovate Bot](https://github.com/renovatebot/renovate) on Bitbucket Cloud. This enables you to require Pull Request approvals on your repository while also utilising Renovate's "automerge" feature.
A job to approve Pull Requests from [Renovate Bot](https://github.com/renovatebot/renovate) on Bitbucket Cloud and Data Center (and Server). This enables you to require Pull Request approvals on your repository while also utilising Renovate's "automerge" feature.

For Github, see [renovatebot/renovate-approve-bot](https://github.com/renovatebot/renovate-approve-bot).

[![build](https://github.com/renovatebot/renovate-approve-bot-bitbucket-cloud/actions/workflows/build.yml/badge.svg)](https://github.com/renovatebot/renovate-approve-bot-bitbucket-cloud/actions/workflows/build.yml)
[![build](https://github.com/renovatebot/renovate-approve-bot-bitbucket/actions/workflows/build.yml/badge.svg)](https://github.com/renovatebot/renovate-approve-bot-bitbucket/actions/workflows/build.yml)

## How it works

Expand All @@ -14,7 +14,7 @@ On each run, the bot will:
2. Filter out PRs where "automerge" is disabled
3. Approve the "automerge" PRs

## Usage
## Bitbucket Cloud usage

1. Create a Bitbucket Cloud account for the renovate-approve-bot and add it to your team (Recommended)
2. [Create an App password](https://support.atlassian.com/bitbucket-cloud/docs/app-passwords/) with `pullrequest:write` scope
Expand All @@ -33,7 +33,7 @@ On each run, the bot will:
--env BITBUCKET_USERNAME \
--env BITBUCKET_PASSWORD \
--env RENOVATE_BOT_USER \
ghcr.io/renovatebot/renovate-approve-bot-bitbucket-cloud:latest
ghcr.io/renovatebot/renovate-approve-bot-bitbucket:latest
```

- From source:
Expand All @@ -43,7 +43,7 @@ On each run, the bot will:
node ./index.js
```

## Bitbucket Pipelines example
### Bitbucket Pipelines example

Example to run renovate-approve-bot in a custom Bitbucket Pipeline on a schedule:

Expand All @@ -56,15 +56,46 @@ Example to run renovate-approve-bot in a custom Bitbucket Pipeline on a schedule
renovate-approve-bot:
- step:
name: Renovate Approve Bot
image: ghcr.io/renovatebot/renovate-approve-bot-bitbucket-cloud:latest
image: ghcr.io/renovatebot/renovate-approve-bot-bitbucket:latest
script:
- export RENOVATE_BOT_USER=your-renovate-bot-user
- node /opt/app/index.js
```

3. Create a [schedule](https://support.atlassian.com/bitbucket-cloud/docs/pipeline-triggers/#On-schedule) for the custom pipeline (e.g. Hourly)

## Bitbucket Data Center and Server usage

1. Create an account for the renovate-approve-bot in your Bitbucket Data Center or Server instance
2. Create a [HTTP access token](https://confluence.atlassian.com/bitbucketserver/http-access-tokens-939515499.html) (formerly known as personal access token) for the renovate-approve-bot account
3. Grant read access on your repositories to the renovate-approve-bot account
4. Optionally, add the renovate-approve-bot account to the default reviewers if you require approval from default reviewers
5. Set the environment variables:
- `BITBUCKET_URL`: URL of your Bitbucket Data Center or Server instance
- `BITBUCKET_USERNAME`: Bitbucket username associated with the account used for renovate-approve-bot
- `BITBUCKET_PASSWORD`: HTTP access token of the renovate-approve-bot account
- `RENOVATE_BOT_USER`: Bitbucket username of your Renovate Bot
6. Run the bot (on a schedule similarly to Renovate Bot, e.g. as a [Cron](https://en.wikipedia.org/wiki/Cron) job):

- With Docker:

```shell
docker run --rm \
--env BITBUCKET_URL \
--env BITBUCKET_USERNAME \
--env BITBUCKET_PASSWORD \
--env RENOVATE_BOT_USER \
ghcr.io/renovatebot/renovate-approve-bot-bitbucket:latest
```

- From source:

```shell
npm install --production
node ./index.js
```

## Security / Disclosure

If you discover any important bug with `renovate-approve-bot-bitbucket-cloud` that may pose a security problem, please disclose it confidentially to [email protected] first, so that it can be assessed and hopefully fixed prior to being exploited.
If you discover any important bug with `renovate-approve-bot-bitbucket` that may pose a security problem, please disclose it confidentially to [email protected] first, so that it can be assessed and hopefully fixed prior to being exploited.
Please do not raise GitHub issues for security-related doubts or problems.
72 changes: 72 additions & 0 deletions adapter/bitbucket-cloud.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const got = require('got');

const MANUAL_MERGE_MESSAGE = 'merge this manually';

class BitbucketCloudAdapter {
constructor(options) {
this.options = options;
this.log = options.log;
this.defaultRequestOptions = {
prefixUrl: 'https://api.bitbucket.org',
// If we use username/password options, they will be URL encoded
// https://github.com/sindresorhus/got/issues/1169
// https://github.com/nodejs/node/issues/31439
headers: {
Authorization: `Basic ${Buffer.from(
`${options.BITBUCKET_USERNAME}:${options.BITBUCKET_PASSWORD}`
).toString('base64')}`,
},
responseType: 'json',
};
}

isAutomerging(pr) {
try {
return !pr.description.includes(MANUAL_MERGE_MESSAGE);
} catch (error) {
this.log.error(error);
return false;
}
}

getPullRequests() {
const prEndpoint = `/2.0/pullrequests/${this.options.RENOVATE_BOT_USER}`;
this.log.info(
'Requesting %s%s...',
this.defaultRequestOptions.prefixUrl,
prEndpoint
);

return got.paginate('', {
...this.defaultRequestOptions,
pathname: prEndpoint,
pagination: {
transform: (response) =>
response.body.values
.filter((pr) => this.isAutomerging(pr))
.map((pr) => pr.links.self.href),
paginate: (response) => {
if ('next' in response.body && response.body.next !== '') {
this.options.log.info('Requesting %s...', response.body.next);
return {
url: new URL(response.body.next),
};
}
this.options.log.info('All pull-requests gathered.');
return false;
},
},
});
}

approvePullRequest(prHref) {
return got('', {
...this.defaultRequestOptions,
prefixUrl: `${prHref}/approve`,
method: 'POST',
throwHttpErrors: false,
});
}
}

module.exports = BitbucketCloudAdapter;
Loading