Commit policy plugin

The Bitbucket Cloud commit policy plugin validates commits against different rules and creates checks for them. It can be used for compliance and keeping your commit messages tidy and clean.

Commit policy check example

Message rule

Require commit messages to match a Regex.

You can enforce that commit is linked to a Jira ticket, for instance.

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

function configure(config: Config | (() => Config)): voidconfigure({
  Config.plugins?: PluginDef<unknown>[] | undefinedplugins: [
    function commitPolicy(options: CommitPolicyPluginOptions): PluginDef<CommitPolicyPluginOptions> (+1 overload)commitPolicy({
      message?: MessageRule | undefinedmessage: {
        matches: RegExpmatches: /^PROJ-\d+.*$/,
        errorMessage?: string | undefinederrorMessage:
          "Commit must start have a reference to a ticket e.g., PROJ-123",
      },
    }),
  ],
})

Author email rule

Bitbucket Cloud links the commits in the UI based on the author commit email and their account, however it will also accept emails that do not have a corresponding account and end up unknown authors in the commit log.

To minimize this issue, you can validate that authors are using your organization email.

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

function configure(config: Config | (() => Config)): voidconfigure({
  Config.plugins?: PluginDef<unknown>[] | undefinedplugins: [
    function commitPolicy(options: CommitPolicyPluginOptions): PluginDef<CommitPolicyPluginOptions> (+1 overload)commitPolicy({
      author?: UserRule | undefinedauthor: {
email: {
    matches: RegExp;
    errorMessage?: string;
}
email
: {matches: RegExpmatches: /.*@myorg.com/}},
}), ], })

Maximum commits and squashed rule

Specify the number of commits per pull request, this is useful if you require squashed commits, for instance.

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

function configure(config: Config | (() => Config)): voidconfigure({
  Config.plugins?: PluginDef<unknown>[] | undefinedplugins: [
    function commitPolicy(options: CommitPolicyPluginOptions): PluginDef<CommitPolicyPluginOptions> (+1 overload)commitPolicy({
      maximumCommits?: number | undefinedmaximumCommits: 1,
    }),
  ],
})

Custom error messages

It allows you to specify custom messages for when a rule is violated. Messages can be formatted using Markdown, allowing for better instructions to users, e.g., directing them to your own organization commit policy documentation site as below.

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

function configure(config: Config | (() => Config)): voidconfigure({
  Config.plugins?: PluginDef<unknown>[] | undefinedplugins: [
    function commitPolicy(options: CommitPolicyPluginOptions): PluginDef<CommitPolicyPluginOptions> (+1 overload)commitPolicy({
      message?: MessageRule | undefinedmessage: {
        matches: RegExpmatches: /^PROJ-\d+.*$/,
        errorMessage?: string | undefinederrorMessage:
          "Message must comply with [commit policy](https://docs.myorg.com/commit-policy#message)",
      },
    }),
  ],
})

Include/exclude

When specifying the rules you can also include or exclude the commits that the rules should apply to, based on the commit attributes.

By default, merge commits are excluded.

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

function configure(config: Config | (() => Config)): voidconfigure({
  Config.plugins?: PluginDef<unknown>[] | undefinedplugins: [
    function commitPolicy(options: CommitPolicyPluginOptions): PluginDef<CommitPolicyPluginOptions> (+1 overload)commitPolicy({
      message?: MessageRule | undefinedmessage: {
        matches: RegExpmatches: /^PROJ-\d+.*$/,
      },
      // Ignore messages from Renovate bot
      exclude?: PolicyFilter | undefinedexclude: {
        message?: RegExp | undefinedmessage: /^Renovate.*/,
      },
    }),
  ],
})

A complete example

In this example, we are using conditions to restrict the policy to the main branch only. It enforces that the message follows the Conventional Commits format, and the author’s email matches the organization domain. Additionally, it will also enforce that merge commits start with Merge.

import {const configure: (config: Config | (() => Config)) => voidconfigure} from "flowie.app"
import {function target(...branches: Array<string | RegExp> & NonEmptyArray): ChainableConditiontarget} from "flowie.app/conditions"
import {const commitPolicy: OptionsPluginNoDefault<CommitPolicyPluginOptions, false>commitPolicy} from "flowie.app/plugins"

function configure(config: Config | (() => Config)): voidconfigure({
  Config.plugins?: PluginDef<unknown>[] | undefinedplugins: [
    function commitPolicy(...rules: Rules<CommitPolicyPluginOptions | undefined>): PluginDef<CommitPolicyPluginOptions> (+1 overload)commitPolicy([
      function target(...branches: Array<string | RegExp> & NonEmptyArray): ChainableConditiontarget("main"),
      [
        {
          message?: MessageRule | undefinedmessage: {
            matches: RegExpmatches:
              /^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([a-z ]+\))?: [\w ]+$/,
            errorMessage?: string | undefinederrorMessage:
              "Message must follow [Conventional Commits](https://www.conventionalcommits.org/) format",
          },
          author?: UserRule | undefinedauthor: {
            
email: {
    matches: RegExp;
    errorMessage?: string;
}
email
: {matches: RegExpmatches: /^[^\s@]+@myorg\.com$/},
}, }, { message?: MessageRule | undefinedmessage: {matches: RegExpmatches: /Merge .*/}, include?: PolicyFilter | undefinedinclude: {mergeCommits?: boolean | undefinedmergeCommits: true}, }, ], ]), ], })