This guide assumes you've installed Mergetastic into your Bitbucket account and enabled it for your repository.

Integrating Mergetastic with Bitbucket Pipelines is easy. If you're generally familiar with Bitbucket Pipelines, here's a short TL;DR. If not, the rest of this article should guide you step-by-step.

TL;DR;

  1. Let's say your target branch is called main. Setup your Mergetastic Queue by creating a mergetastic.yaml file in the root directory that looks like:
  
queues:
  main: 
    required_builds: 1
  
  1. Because the Mergetastic queue is called main, Mergetastic will run the queue build on the branch mergetastic-main. You'll need to setup Bitbucket Pipelines to run your tests on mergetastic-main and post a build status with the key MY_BUILD_STATUS_KEY.
  2. That's it! When you add your pull requests to the queue, Mergetastic will create merge commits on that branch and merge these commits once Bitbucket Pipelines posts the appropriate build statuses.

If any of that was unclear, the rest of this article should be able to walk you through the steps.

Detailed walkthrough

For this walkthrough, we'll use this demo repository.

Figure 1: Mergetastic and Bitbucket Pipelines integration demo repository overview

The repository contains an extremely simple "code file" called adder.py containing a simple function called add. As you can imagine, add merely adds 2 numbers.

  
def add(x, y):
    return x + y
  

There's also a file containing tests (test_adder.py). Interestingly, it contains 2 tests:

  
import pytest

from adder import add


def test_that_positive_numbers_can_be_added():
    assert add(2, 3) == 5


@pytest.mark.slow
def test_that_numbers_can_be_doubled_by_adding():
    for number in range(-1000000, 1000000):
        assert add(number, number) == number * 2
  

Note that one of the tests is "marked slow". This is similar to how tests are in the real-world: some tests are slow and others are fast. Typically, the "fast" tests are your linting and unit tests and the "slow" tests are your integration tests. The fast tests can catch most of the issues very quickly. But some bugs can slip through. This is where the "slow" tests come in. The downside is that the slow tests take a lot of time and use up a lot of build minutes.

In real-world codebases, the test suite can be divided into "fast" and "slow". The fast tests quickly catch most of the issues, but some bugs can slip through. The slow tests might catch these issues, but they take up a lot of time and build minutes.

The general idea here is to run the "fast" tests on each commit for all the pull requests, but reserve the "slow" tests for the merge queue. This is where Mergetastic can help you save both time and money.

Setup your Mergetastic Queue

For this walkthrough, we want to guard the main branch from getting commits that don't pass the tests. So that's where we'll setup the Mergetastic queue using the following mergetastic.yaml file:

  
queues:
  main: 
    required_builds: 1
  

This basically says: setup a queue for the main branch and consider a commit to have "passed the tests" if 1 passing build status is posted to it. 

Unfortunately, Bitbucket pipelines does not allow us to reliably know the key of the build status, otherwise we would have been able to list out the required builds by name.

Now when we look at the Mergetastic tab, we see an empty queue.

Figure 2: An empty Mergetastic queue

Setting up Bitbucket Pipelines

The first thing you're going to want to do is enable Bitbucket Pipelines. Just head over to the Pipelines tab and hit the Enable button. 

Once that's in place, you'll need to create a bitbucket-pipelines.yml file at the root directory. For this walkthrough, the file looks like:

  
image: python:3.8

pipelines:
  default:
    - parallel:
        - step:
            name: Linting
            script:
              - pip install flake8
              - flake8 . --show-source --statistics
        - step:
            name: Unit tests
            caches:
              - pip
            script:
              - pip install pytest
              # Skip slow tests when not running on the Mergetastic build branch
              - pytest -v --junitxml=test-reports/report.xml -m 'not slow' .
  branches:
    # This defines CI for the mergetastic-main branch, which is where
    # Mergetastic will create the merge commits for the main queue.
    mergetastic-main:
      - parallel:
          - step:
              name: Linting
              script:
                - pip install flake8
                - flake8 . --show-source --statistics
          - step:
              name: Unit tests
              caches:
                - pip
              script:
                - pip install pytest
                # Run the full test suite here. The commits these tests run on
                # will literally become part of the main branch if these tests
                # pass.
                - pytest -v --junitxml=test-reports/report.xml .
  

That looks like a lot of stuff. Let's walk through it slowly:

  • There are 2 distinct areas of this file: one for the Merge Queue (the mergetastic-main section) and another for everything else (the default section).
  • The default pipeline runs for all commits not reachable by the mergetastic-main branch. Mergetastic will create builds on the mergetastic-main branch for the pull requests that are added to the queue. So this is the pipeline that will run for the commits in your pull requests. See this document for more details on how Mergetastic works.
  • We want the pipeline for the pull requests to only run the "fast" subset of the test suite. That is why you see -m 'not slow' included in the command for running the unit tests. Unless you also use Python and pytest for your codebase, you may have to use a different strategy for separating out the fast and slow tests. Some tests suites (like pytest) allow you to annotate individual tests. If your test suite does not support this, consider separating them out into separate files and folders.
  • When we run the pipeline on the mergetastic-main branch, we go all out. It is important to run all the tests in the queue pipeline (both fast and slow).

Introducing a failing pull request

To see the system in action, let's introduce a failing pull request.

Figure 3: A failing pull request

Note that this pull request changes the add function such that it passes our fast tests, but fails our slow tests. 

Figure 4: The "fast" tests fail to detect the bug

To add the pull request to the queue, we only need to hit the "Add to merge queue" button (see Figure 3). The pull request now gets added to the queue and the full test-suite is thrown at it.

Figure 5: The queue now contains our pull request and is running it

As we expected, the tests fail. We can see this in the queue, which is once again empty:

Figure 6: The queue is empty once again

The logs show that the full test suite was run.

Figure 7: The full test suite was run on the mergetastic-main branch

And there you have it! Mergetastic is integrated with Bitbucket Pipelines and we've seen it in action. If you have any questions, feel free to contact support and we'll help you out as best as we can.