Merge plugin

The merge plugin replaces the default merge functionality from Bitbucket Cloud and adds support for:

The simplest configuration is:

import {const configure: (config: Config | (() => Config)) => voidconfigure} from "flowie.app"
import {const merge: OptionsPlugin<MergePluginOptions, false>merge} from "flowie.app/plugins"

function configure(config: Config | (() => Config)): voidconfigure({
  Config.plugins?: PluginDef<unknown>[] | undefinedplugins: [function merge(): PluginDef<MergePluginOptions> (+2 overloads)merge()],
})

Advanced examples using options:

import {const configure: (config: Config | (() => Config)) => voidconfigure} from "flowie.app"
import {const merge: OptionsPlugin<MergePluginOptions, false>merge} from "flowie.app/plugins"

function configure(config: Config | (() => Config)): voidconfigure({
  Config.plugins?: PluginDef<unknown>[] | undefinedplugins: [
    function merge(options: MergePluginOptions): PluginDef<MergePluginOptions> (+2 overloads)merge({
      MergePluginOptions.allow?: RulesOr<string[] | undefined>allow: ["Team leaders"],
      MergePluginOptions.strategies?: RulesOr<"rebase_fast_forward" | "merge" | "fast_forward" | "fast_forward_only" | "rebase_merge" | "squash" | "squash_fast_forward" | ("rebase_fast_forward" | "merge" | "fast_forward" | "fast_forward_only" | "rebase_merge" | "squash" | "squash_fast_forward")[] | undefined>strategies: "rebase_fast_forward",
      MergePluginOptions.select?: RulesOr<boolean | ("strategy" | "commitMessage" | "closeBranch" | "preventRedundantBuilds")[] | undefined>select: false,
    }),
  ],
})

using rules and conditions:

import {const configure: (config: Config | (() => Config)) => voidconfigure} from "flowie.app"
import {const merge: OptionsPlugin<MergePluginOptions, false>merge} from "flowie.app/plugins"
import {function target(...branches: Array<string | RegExp> & NonEmptyArray): ChainableConditiontarget, const labels: Labelslabels, function otherwise(): trueotherwise} from "flowie.app/conditions"

function configure(config: Config | (() => Config)): voidconfigure({
  Config.plugins?: PluginDef<unknown>[] | undefinedplugins: [
    function merge(...rules: Rules<MergePluginOptions | undefined>): PluginDef<MergePluginOptions> (+2 overloads)merge([
      function target(...branches: Array<string | RegExp> & NonEmptyArray): ChainableConditiontarget("main"),
      {
        MergePluginOptions.autoMerge?: RulesOr<boolean | undefined>autoMerge: const labels: Labelslabels.Labels.has(label: string | LabelRef): ChainableCondition (+1 overload)has("Auto-Merge"),
      },
    ]),
  ],
})

Options:

autoMerge - Enables smart auto merge , which automatically merges the pull request when all the extended checks are passing. It relies on the default values for the merge options as well. Default: false

allow - The groups that are allowed to merge. By default, anyone that has write permissions is allowed to merge.

strategies - The strategies that can be used to merge the pull request. It can also be a single strategy. Default is all existing strategies. e.g. "rebase_merge" or ["merge", "squash", "fast_forward"]. See all supported strategies here.

closeBranch - Whether the branch should be closed after the merge is performed. Default: Inherits the value specified when the pull request was created.

commitMessageTemplate - Template for using for the merge commit message.

preventRedundantBuilds - Redundant builds prevention feature when merging. Default: false

select - Defines the options that can be selected. It affects the merge commit dialog. Default is to allow all values to be selected; false locks the values to the defaults.

Enforcing merge checks

The merge plugin will only show the merge button once all the extended merge checks are passing.

Passing checks

Permissions

In order to support enforced extended checks, Flowie uses Bitbucket branches restrictions . It updates the permissions of the repository to only allow Flowie to perform merges. This is due to current Bitbucket limitations on creating custom checks, so to overcome this limitation Flowie implements its own enforced checks.

The changes to permissions are performed when applying the configurations and the merge plugin is enabled. The default changes are usually suitable for most installations, but if you need to customise it, you can use the branch.restrictions property in the configuration. You can also disable the permissions change for debugging purposes or to work around an issue.

When the merge plugin is removed or the branch.restrictions are disabled, the previous permissions will be restored.

Restricting merge options and default values

It’s common when defining your workflow to pick a merge strategy, e.g., only use merge commits when applying to the main branch. The merge plugin allows you to enforce and restrict the options available.

By default, all the merge strategies will be available, but you can use the strategies option to restrict them:

function merge(options: MergePluginOptions): PluginDef<MergePluginOptions> (+2 overloads)merge({
  MergePluginOptions.strategies?: RulesOr<"merge" | "fast_forward" | "fast_forward_only" | "rebase_merge" | "rebase_fast_forward" | "squash" | "squash_fast_forward" | ("merge" | "fast_forward" | "fast_forward_only" | "rebase_merge" | "rebase_fast_forward" | "squash" | "squash_fast_forward")[] | undefined>strategies: ["merge", "squash"],
  MergePluginOptions.closeBranch?: RulesOr<boolean | undefined>closeBranch: true,
})

This configuration will restrict the options to only the strategies specified and close branch will be selected by default.

Restricing strategies

You can also restrict the options that can be selected in the dialog using the select option:

function merge(options: MergePluginOptions): PluginDef<MergePluginOptions> (+2 overloads)merge({
  MergePluginOptions.strategies?: RulesOr<"merge" | "fast_forward" | "fast_forward_only" | "rebase_merge" | "rebase_fast_forward" | "squash" | "squash_fast_forward" | ("merge" | "fast_forward" | "fast_forward_only" | "rebase_merge" | "rebase_fast_forward" | "squash" | "squash_fast_forward")[] | undefined>strategies: ["merge", "squash"],
  MergePluginOptions.closeBranch?: RulesOr<boolean | undefined>closeBranch: true,
  MergePluginOptions.select?: RulesOr<boolean | ("strategy" | "commitMessage" | "closeBranch" | "preventRedundantBuilds")[] | undefined>select: ["strategy"],
})
Restricing options with select

Now ‘close branch’ will always be true and can’t be changed, the user can only choose the strategy.

You can also enforce all the options by setting select to false as below:

function merge(options: MergePluginOptions): PluginDef<MergePluginOptions> (+2 overloads)merge({
  MergePluginOptions.strategies?: RulesOr<"rebase_fast_forward" | "merge" | "fast_forward" | "fast_forward_only" | "rebase_merge" | "squash" | "squash_fast_forward" | ("rebase_fast_forward" | "merge" | "fast_forward" | "fast_forward_only" | "rebase_merge" | "squash" | "squash_fast_forward")[] | undefined>strategies: "rebase_fast_forward",
  MergePluginOptions.closeBranch?: RulesOr<boolean | undefined>closeBranch: true,
  MergePluginOptions.select?: RulesOr<boolean | ("strategy" | "commitMessage" | "closeBranch" | "preventRedundantBuilds")[] | undefined>select: false,
})
Restricing options with select false

Because there is nothing to select, Flowie will show the merge button without a dialog and when pressed it will use rebase as the merge strategy and close the branch.

Commit message template

Commit message can be defined using a template with dynamic content. For instance, you can set the default message using the pull request’s id and description variables:

function merge(options: MergePluginOptions): PluginDef<MergePluginOptions> (+2 overloads)merge({
  
MergePluginOptions.commitMessageTemplate?: RulesOr<((ctx: {
    pullRequest: PullRequest;
}) => string) | undefined>
commitMessageTemplate
: ({pullRequest: PullRequestpullRequest}) =>
`#${pullRequest: PullRequestpullRequest.PullRequest.id: numberid}: - ${pullRequest: PullRequestpullRequest.
PullRequest.summary: {
    raw: string;
    markup: "markdown" | "creole" | "plaintext";
    html: string;
}
summary
}`,
})

Smart auto merge

Flowie’s smart auto merge lets you specify the condition and requirements, or which checks should be passed for it to trigger a merge automatically.

Differently from Bitbucket’s auto merge when build passes functionality, which is limited, since you need for instance to wait or watch for reviewers, or other checks before you can request a merge on build success.

Strategies

The merge plugin supports all the Bitbucket Cloud strategies and adds support for additional strategies, including rebase.

Merge commit   (--no-ff)
merge

Always create a new merge commit and update the target branch to it, even if the source branch is already up to date with the target branch.

Fast-forward   (--ff)
fast_forward

If the source branch is out of date with the target branch, create a merge commit. Otherwise, update the target branch to the latest commit on the source branch.

Fast-forward only   (--ff-only)
fast_forward_only

If the source branch is out of date with the target branch, reject the merge request. Otherwise, update the target branch to the latest commit on the source branch.

Rebase, merge   (rebase + merge --no-ff)
rebase_merge

Commits from the source branch onto the target branch, creating a new non-merge commit for each incoming commit. Creates a merge commit to update the target branch.

Rebase, fast-forward   (rebase + merge --ff-only)
rebase_fast_forward

Commits from the source branch onto the target branch, creating a new non-merge commit for each incoming commit. Fast-forwards the target branch with the resulting commits.

Squash   (--squash)
squash

Combine all commits into one new non-merge commit on the target branch.

Squash, fast-forward only   (--squash --ff-only)
squash_fast_forward

If the source branch is out of date with the target branch, reject the merge request. Otherwise, combine all commits into one new non-merge commit on the target branch.

Autosquash (Rebase) NEW

If your commits contain Git autosquash directives, e.g., fixup!, Flowie will automatically process them during rebase.

This is useful for code reviews when implementing requested changes. Instead of rewriting the commits, or creating separated ones and having to manually squash them later, you create --fixup/--squash commits. These are easier to review, as they clearly show what was changed for the review, and let Flowie clean them up later by combining them automatically during merge.

Auto squash commits

Redundant builds prevention

Avoiding redundant builds saves time and resources by eliminating the need to reprocess unchanged code, leading to cost savings and more efficient use of continuous integration servers. This also shortens the feedback loop for developers, boosting productivity, and allows them to focus on valuable tasks like adding features or fixing bugs.

Whenever a Git operation results in an identical set of changes, altering only the commit log, Flowie can prevent a redundant build and preserve the status if there is already a passing build for those changes. This applies when the branch is up-to-date and a fast-forward merge is executed, or when rebasing it solely to eliminate merge logs.

Redundant build prevention

Although you might try to manually bypass the build process, pushing changes such as a rebase will reset the build results. Consequently, if your workflow requires a passing build check, you’ll need to rerun the build for those changes.

This behavior can be toggled on or off in the plugins that support this functionality.

Further reference

BCLOUD-19402, BCLOUD-12918