The merge queue feature is a way for Bitbucket to ensure pull requests will not break their target branch, by running checks on the merge commit before the merge is actually applied.
To achieve this, when a pull request is added to the merge queue Bitbucket creates a temporary, restricted branch (the merge queue branch). A single commit (the prepared merge commit) is created on the branch, which is the merge of the pull request's source branch into the target branch using the selected merge strategy. This is the exact same commit ID that will be propagated to the target branch upon merge.
The prepared merge commit can be used by CI systems to validate the merge. Out of the box, merge queues support the “Required Builds” feature. It uses the build status API to ensure a set of builds are successful before a queued pull request can be merged. This functionality already exists for direct pull request merges, and has been extended to support merge queues.
If a queued pull request is accepted, the merge commit is propagated to the target branch and the pull request is closed
as Merged. If rejected, the pull request is removed from the queue without merging, and returned to Open. In both
cases merge queue processing continues with the next pull request in the queue.
In addition to the Required Builds feature, plugins can supply additional checks through our P2 Plugin API. A MergeQueueCheck class can be implemented to enforce a specific merge pre-condition on pull requests in merge queues. For example a merge queue check could integrate with external CI systems, or enforce custom policies on the prepared merge commit.
During merge queue processing all registered MergeQueueCheck implementations are invoked to determine if the
pull request is ready to merge. Collectively the check's results control whether the pull request can merge, should wait
in the queue for a future processing cycle, or should be immediately ejected from the queue.
Merge queue checks receive a MergeQueueCheckContext parameter, which contains:
They return a MergeQueueCheckResult
containing a State enumeration, one of:
ACCEPTED - Indicates that the check has finished and the queued pull request can be mergedREJECTED - Indicates that the check has finished and the pull request should be removed from the queuePENDING - Indicates that the check is still waiting to finish. Checks in this state will be re-run during the next
merge queue processing cycle.A MergeQueueCheckResult may optionally provide:
PENDING state longer than the configured merge timeout.Merge queue checks are part of Bitbucket Data Center's SPI (its service provider interface).
atlas-create-bitbucket-plugin generates pom.xml with this dependency already in place, but for reference the
dependency looks like this:
1 2<dependency> <groupId>com.atlassian.bitbucket.server</groupId> <artifactId>bitbucket-spi</artifactId> <scope>provided</scope> </dependency>
MergeQueueCheck class1 2package com.example.bitbucket.mergequeue.checks; import com.atlassian.bitbucket.i18n.I18nKey; import com.atlassian.bitbucket.pull.mergequeue.*; import javax.annotation.Nonnull; /** * A simple merge queue check that always accepts the merge. */ public class ExampleMergeQueueCheck implements MergeQueueCheck { @Nonnull @Override public MergeQueueCheckResult run(@Nonnull MergeQueueCheckContext context) { // This "merge hash" is the commit that would become the new tip of the // target branch if the queued merge is applied. Use it to query build // statuses or perform other checks against the merged state of the // pull request. String mergeCommitHash = context.getMergeHash(); // Pull request that was added to the merge queue PullRequest pullRequest = context.getPullRequest(); // Choose a result for this check // TODO Implement real logic here MergeQueueCheckResult.State result = MergeQueueCheckResult.State.ACCEPTED; log.info("Merge Queue Check ran for PR #{}: mergeCommitHash={}, result={}", pullRequest.getId(), mergeCommitHash, result); return new SimpleMergeQueueCheckResult.Builder(result) // Optionally provide a reason for the result to display in PR // activities and notifications .reason(new I18nKey("plugin.example.mergequeue.check.passed")) // Optionally provide a URL with more details about the check's // result .detailsUrl("http://ci.example.com/check/123") .build(); } }
In atlassian-plugin.xml add a merge queue check module. For full details see the plugin module
reference documentation.
1 2<merge-queue-check key="exampleMergeQueueCheck" class="com.example.bitbucket.mergequeue.checks.ExampleMergeQueueCheck"/>
Plugins can listen to the following events to react to changes:
Plugins can publish the following events to trigger merge queue processing:
Plugins can trigger merge queue processing (and therefore re-evaluation of merge queue checks) by publishing an event.
For example, the following code snippet shows how to trigger processing for a pull request in the merge queue by
publishing a MergeQueuePullRequestChangeEvent:
1 2package com.example.bitbucket.mergequeue.checks; import com.atlassian.bitbucket.pull.mergequeue.MergeQueuePullRequestChangeEvent; import com.atlassian.event.api.EventPublisher; public class ExampleMergeQueueCheckTrigger { private final EventPublisher eventPublisher; public ExampleMergeQueueCheckTrigger(EventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } /** * Trigger checks for the merge queue containing {@code pullRequestId}. * @param repositoryId the repository ID * @param pullRequestId the pull request ID */ public void triggerMergeQueueCheck(int repositoryId, long pullRequestId) { eventPublisher.publish( new MergeQueuePullRequestChangeEvent( this, repositoryId, pullRequestId)); } }
Plugins can listen to merge queue events to respond to the preparation of merge commits. For example, the following code
snippet shows how to listen to MergeQueueBranchPreparedEvent:
1 2package com.atlassian.bitbucket.sample; import com.atlassian.bitbucket.pull.PullRequest; import com.atlassian.bitbucket.pull.mergequeue.MergeQueueBranchPreparedEvent; import com.atlassian.bitbucket.repository.Branch; import com.atlassian.event.api.EventListener; public class ExampleMergeQueueEventListener { @EventListener public void onEvent(MergeQueueBranchPreparedEvent event) { // The ID of the prepared merge commit, that represents the result of // merging the pull request into the target branch String preparedMergeCommit = event.getPreparedMergeCommit(); // The pull request in the queue PullRequest pullRequest = event.getPullRequest(); // The merge queue branch that holds the preparedMergeCommit Branch branch = event.getBranch(); // TODO react to the merge queue branch being prepared } }
Rate this page: