Skip to content

klarna/bec

BEC

Keep your BitBucket Settings under version control

Build Status License Developed at Klarna

The behaviour of a BitBucket repository can be customized in a multitude of ways. Configuring default reviewers, branch restrictions, hooks and merge strategies can be a tedious, repetitive and error prone procedure if it is performed via the GUI, especially with a large number of repositories.

Wouldn't it be nice if it was possible to store the BitBucket settings under version control and maintain them in the same way we maintain code? This is the idea behind BEC, a tool which has been developed internally at Klarna. The tool allows you to write your BitBucket repository settings in yml format and to check and apply them via a command line interface.

BEC comes with extensive documentation and sample repository configuration files. It also supports Mustache templates, allowing you to apply variations of your configuration to multiple repositories.

Here's a short presentation explaining what BEC is about.

Requirements

BEC requires BitBucket Server 5.5 or superior.

Quickstart

To build bec, you need Erlang/OTP 21+ and rebar3 installed on your machine.

git clone git@github.com:klarna-incubator/bec.git
cd bec
rebar3 escriptize

You will get an executable escript in:

_build/default/bin/

Ensure the location of the script is added to your PATH:

export PATH=/path/to/_build/default/bin:$PATH

Then you can run BEC:

$ bec
Usage: bec [-h] [-c [<config>]] [-r [<repo_config>]]
           [-e [<enforce>]] [-k [<keep>]]
           [-v [<verbosity>]]

  -h, --help         Show this help message
  -c, --config       The BitBucket Config File [default: bitbucket.config]
  -r, --repo_config  The Repo Config to check or configure [default: undefined]
  -e, --enforce      Enforce values when they do not match expectations [default: false]
  -k, --keep         Keep going after the first error (always true when enforce == true) [default: false]
  -v, --verbosity    Verbosity Level [default: 1]

Build with Docker

docker run --rm --name erlangbuilder -v ${PWD}:/bec  -w=/bec  erlang rebar3 escriptize

Sample BitBucket Configuration

BEC supports both Basic Authentication (via username/password) and Token-Based Authentication (preferred). If both a token and a username/password pair are provided, the token will take precedence.

Set BitBucket url and credentials in bitbucket.config:

{bitbucket_url, "https://my.bitbucket.server"}.
{bitbucket_username, "first.last"}.
{bitbucket_password, "password"}.
{bitbucket_token, "someToken"}.

Values can also be provided using OS environment variables, for example

{bitbucket_password, {env, "BITBUCKET_PASSWORD"}}.

Please follow this guide if you want to generate the token to authenticate.

Sample Repo Configuration

You can find a sample configuration file for a custom BitBucket repo in sample_repo_configuration.yml.

Repo Configuration Templates

It is a common need to apply very similar configuration to multiple repositories. Repo configuration templates are supported for this use case.

A repo configuration template file is similar to a repo configuration, but has a .ymlt extension, and will be rendered as a Mustache template. The parameters for the template are defined in a .ymlv file (as Yaml).

For example common_repo.ymlt may look like this:

---
project: {{project}}
repo: {{repo}}

pr-restrictions:
  required-all-approvers : true
  required-all-tasks-complete : true
  required-approvers : 2
  {{#has_ci}}required-successful-builds : 1
  {{/has_ci}}
  # Please note that Mustache throws away all white space after
  # section opening and closing tags, this is the reason for not
  # putting both of them on a single line. The closing tag has to
  # be indented as much as the next line of Yaml needs to be.

{{#has_ci}}
hooks:
  - key: "com.nerdwin15.stash-stash-webhook-jenkins:jenkinsPostReceiveHook"
    enabled: true
    settings:
      branchOptions:
      branchOptionsBranches:
      cloneType: custom
      gitRepoUrl: ssh://git@my.bitbucket.server/{{project}}/{{repo}}.git
      ignoreCerts: false
      ignoreCommitters:
      jenkinsBase: https://jenkins.hipster.company.io/
      omitBranchName: false
      omitHashCode: false
      omitTriggerBuildButton: false
{{/has_ci}}

The corresponding common_repo.ymlv specifies the values for the project, repo and has_ci variables:

---
- project: MYTEAM
  repo: my_repo
  has_ci: true

- project: MYTEAM
  repo: best_cat_pics
  has_ci: false

Please note that previous versions of the BitBucket Erlang client only supported the repo parameter in the .ymlt file, and the .ymlv file had a simplified syntax:

---
repo:
  - my_repo
  - best_cat_pics

Handling secrets

Repo configurations may contain secrets, like authentication tokens for web hooks. It is possible to inject the secrets at runtime from OS environment variables by using the !env YAML tag:

- auth_token: !env TOKEN

This tag will fetch the value of the TOKEN OS environment variable.

In case a field is not entirely a secret, but contains a secret, repo configuration templates can be used:

# example.ymlv
- auth_token: !env TOKEN
# example.ymlt
hooks:
  - key: de.aeffle.stash.plugin.stash-http-get-post-receive-hook:http-get-post-receive-hook
    settings:
      url: https://jenkins.hipster.company.io/buildByToken/build?job=fancyci&token={{ auth_token }}

Known Limitations

  • Basic HTTP Authentication is the only authentication mechanism currently supported
  • The BitBucket Paged API is not supported, yet

Running tests against Bitbucket

The full test suite (including PropEr tests) needs a Bitbucket Server instance to run. Running "rebar3 proper" will check if there is one already running on http://localhost:7990 and start one using a docker container if no one is found. This functionality requires docker-compose.

BEC has support for some hooks (see bec_proper_gen:supported_hooks/0), as well as for the Workzone plugin. These hooks are not available in the default Bitbucket Server docker image used if you only use "rebar3 proper".

If you have a Bitbucket Server where these plugins/hooks are supported, you can run the PropEr tests against that server instead. To do this, set these environment variables:

  • BITBUCKET_SERVER_URL: The Bitbucket Server you want to use.
  • BITBUCKET_USERNAME: The username to use. Only http username/password authentication is supported for now.
  • BITBUCKET_PASSWORD: The password to use.

The following environment variables can be used to override which repo/users/groups will be used for testing. If these do not exist (or not specified), the test setup will attempt to create them. If $BITBUCKET_USERNAME does not have sufficient privileges to create repos/users/groups, you can specify pre-created users/groups here.

  • BITBUCKET_PROJECT_KEY: The Bitbucket project to use.
  • BITBUCKET_REPO_SLUG: The Bitbucket repository to use.
  • BITBUCKET_TEST_USERS: A comma-separated list of test users.
  • BITBUCKET_TEST_GROUPS: A comma-separated list of test groups.

Note: the test users and test groups should be the same length, and each user should be a member of the corresponding group, i.e.

BITBUCKET_TEST_USERS=user.a,user.b
BITBUCKET_TEST_GROUPS=group.a,group.b

where user.a is a member of group.a and user.b is a member of group.b.

Author

Roberto Aloi was the original author of BEC. Lots of people have contributed to its development since then.

How to contribute

See our guide on contributing.

Release History

See our changelog.

License

Copyright © 2020 Klarna Bank AB

For license details, see the LICENSE file in the root of this project.