Screenshot from Bit-Booster - Global Git and JIRA Hooks rejecting a foxtrot.
bit-booster monster

Control Freak for Bitbucket Server

Documentation
 
Oct 2017

Table of Contents

Introduction

Control Freak for Bitbucket Server allows Bitbucket admins to define and encourage consistent git policy across all projects and repositories within their Bitbucket Server and Bitbucket Datacenter installations.

Advantages

  • Global Git policy configured in one place
  • Branching Model binds rules to branch groups
  • Improved performance
  • Compatible with Fork-Based Workflows

The add-on accomplishes this through independent rule groups. Admins can define JIRA policy, branch naming policy, rebase policy, commit authorship policy, etc. The add-on also includes rules to help prevent common nuisances in git repos such as foxtrot merges or accidental multi-rewrite pushes.

A master ruleset is defined once through the global config screen. By default the policy is enabled for all normal non-empty repos, but per-project and per-repo kill switches are available. A subset of the rules can also be overridden per-project or per-repo.

Problem

Bitbucket comes with many powerful configuration options and add-ons to help enforce repository policy (e.g., branch permissions, hooks, merge checks). But setting these up for each newly created repository is repetitive and error-prone, and not everyone with the "Create New Repository" permissions is always aware of their organization's preferred setup.

Control Freak for Bitbucket Server solves this problem by allowing admins to define a global default that is applied to all repositories. Projects and repos where the global settings are inappropriate can opt-out or override to suit their own needs. This results in more repositories that comply with the organization's preferred setup, thanks to this "opt-out" approach rather than Bitbucket's out-of-the-box "opt-in" approach.

Installation Requirements

  1. Install this add-on using Bitbucket's "Manage Add-Ons" page, or from our Atlassian Marketplace page: https://marketplace.atlassian.com/plugins/com.bit-booster.bb.hooks
  2. You must be using version 4.13.0 of Bitbucket Server or newer.
  3. Optional: to enable the online components of the JIRA Git Policy, your JIRA administrator must connect JIRA to your Bitbucket Server instance via the “Application Link” feature of JIRA.
     
    (Note: if you have more than one JIRA instance connected to your Bitbucket, this add-on will only use the application link marked as “primary”. This is a temporary limitation we plan to address by Q1 2018).

Enabling Your Global Git Policy

The very top of the global config screen includes the enable/disable control:

Enabled For:
Regular
Repos
Regular
Forks
Personal
Repos
Personal
Forks
Empty
Repos

By default Bit-Booster - Global Git and JIRA Hooks is enabled for regular repositories and regular forks, and disabled for all other types. Note: repositories can also be moved between the personal and project areas of Bitbucket. After a move, the configured policy will apply to all new commits, but older commits are grandfathered. The repository types are:

  • Regular Repos - These are regular repositories created using the "new repository" function within a project.
  • Regular Forks - These are forked repositories created using the "fork repository" function where a project is chosen as the target location for the new fork.
  • Personal Repos - These are repositories created using the "new repository" function within a user's personal area in Bitbucket.
  • Personal Forks - These are forked repositories created using the "fork repository" function where a user's personal area is chosen as the target location for the new fork.
  • Empty Repos - Any repository without any commits is considered an empty repository. Disabling the global policy for empty repositories helps admins importing repos from other sources (e.g., Github or after a svn2git conversion), since the git policy is likely to complain about many of the imported commits. After an initial import the policy is enabled for all subsequent commits, since the repository is no longer considered empty.

Authorship Policy

Authorship policy inspects the "Author" and "Committer" metadata for each incoming commit, and accepts or rejects the commit based on the selected rules. The user's email address and display name (as recorded in the commit metadata) must match exactly the values stored in Bitbucket to satisfy these rules. By default all three of these rules are disabled.
Authorship Policy:

  • Author must be a valid Bitbucket User - If enabled, all new commits arriving via push (or via merge if coming from a fork) must contain author values that match existing records inside Bitbucket's user database.
    remote: -----
    remote: Commit e4d06580fc0024e rejected.
    remote:
    remote: Author "G. Sylvie Davies <sylvie@bit-booster.com>" is not known to Bitbucket.
    remote:
    remote: Please either have an admin create the Bitbucket user record, or adjust
    remote: your git config and amend (or rebase) the problematic commit(s).
    remote: -----
    
  • Committer must be a valid Bitbucket User - If enabled, all new commits arriving via push (or via merge if coming from a fork) must contain committer values that match existing records inside Bitbucket's user database. We recommend enabling this rule.
    remote: -----
    remote: Commit e4d06580fc0024e rejected.
    remote:
    remote: Committer "G. Sylvie Davies <sylvie@bit-booster.com>" is not known to Bitbucket.
    remote:
    remote: Please either have an admin create the Bitbucket user record, or adjust
    remote: your git config and amend (or rebase) the problematic commit(s).
    remote: -----
    
  • Committer must be current logged-in User - If enabled, all new commits arriving via push (or via merge if coming from a fork) must contain a committer value that exactly matches the email address and display name of the current logged-in Bitbucket user performing the operation.
    remote: -----
    remote: Commit e4d06580fc0024e rejected.
    remote:
    remote: Committer "G. Sylvie Davies <sylvie@bit-booster.com>" does not match your current credentials.
    remote: You are currently logged in as: "Administrator <admin@example.com>"
    remote:
    remote: Please get "G. Sylvie Davies <sylvie@bit-booster.com>" to push their own commits,
    remote: or adjust your git config and amend (or rebase) the problematic commit(s).
    remote: -----
    

Branch Policy

New Branch Names
Must Match:


remote: -----
remote: Push rejected. Invalid branch name: "abc"
remote: New branches must comply with the repository's branching model.
remote: Allowed names: bugfix/*, feature/*, hotfix/*, release/*
remote: -----
remote: -----
remote: Push rejected. Invalid branch name: "abc"
remote: New branch names must contain a JIRA ticket.
remote: -----
remote: -----
remote: Push rejected. Cannot validate branch name: "ABC-1"
remote: Your Bitbucket instance does not have an application link to a JIRA instance.
remote: Please configure your Bitbucket instance.
remote: (Or disable the JIRA branch check of this global hook.)
remote: -----
remote: -----
remote: New branch names must contain a JIRA ticket, but Bitbucket
remote: cannot access JIRA to see if "[ABC-1]" exists.
remote: Your Bitbucket account is missing OAUTH credentials into JIRA.
remote:
remote: Use this URL to set that up:
remote: http://localhost:7990/bitbucket/plugins/servlet/applinks/oauth/login-dance/authorize
remote: -----
remote: -----
remote: Push rejected. Rejected new branch "ABC-1"
remote: Rejected because ticket "ABC-1" does not exist in JIRA.
remote: -----
remote: -----
remote: Push rejected. Invalid branch name: "ABC-1"
remote: New branches must satisfy the configured branch regex.
remote: Failed Regex: (.*xyz)
remote: -----

Tag Pushing Policy

Allow Tag Pushes:

remote: -----
remote: PUSHED TAG DELETES ARE NOT PERMITTED!
remote: Sorry, you cannot delete tag "signed_tag" via git push.
remote: Please delete tags using Bitbucket's web UI instead.
remote: -----
remote: To reset your tags to match Bitbucket's (assumes 'origin' points to Bitbucket):
remote:
remote: git fetch --prune origin "+refs/tags/*:refs/tags/*"
remote: -----
remote: -----
remote: PUSHED TAG CREATES/EDITS ARE NOT PERMITTED!
remote: Sorry, you cannot create tag "1.2.3" via git push.
remote: Please create tags using Bitbucket's web UI instead.
remote: -----
remote: To reset your tags to match Bitbucket's (assumes 'origin' points to Bitbucket):
remote:
remote: git fetch --prune origin "+refs/tags/*:refs/tags/*"
remote: -----

Foxtrot Policy

Block Foxtrot Merges On:       
   
remote: -----
remote: Commit rejected. Foxtrot merges not allowed on "master".
remote:
remote: Commit 7a5fea716c2048f contains a foxtrot merge.
remote: A rebase will repair the problem:
remote:
remote:   git rebase origin/master
remote:
remote: Alternatively, redo the merge in the opposite direction.
remote: -----

Branch Pushing Policy (a.k.a. Protected Branches)

Block Branch Deletes On:       
Block History Rewrites On:
Block "force pushes" 
       
Always Require Pull-Requests:       
Block Multi-Rewrites:
Avoid push.default=matching disasters 
     
remote: -----
remote: Push rejected.
remote: You are not allowed to delete branch "master".
remote: -----
remote: -----
remote: Push rejected. History rewrites not allowed on "release/ABC-1".
remote: -----
remote: -----
remote: Push rejected. Direct pushes not allowed on "release/ABC-1".
remote: This branch can only be modified through pull requests.
remote: -----
remote: -----
remote: Push rejected. Multiple history rewrites
remote: in a single push not allowed.
remote:
remote: Is your "push.default" config is set to "matching"?
remote: Try setting it to "simple" instead.
remote:
remote: Trying to mirror a repo? In that case, disable
remote: "Bit-Booster - Global Git and JIRA Hooks" for this repository.
remote: (Repository Settings -> Bit-Booster - Global Hooks)
remote: -----

Rebase Policy

Require Fast-Forwardable Merges Into:
Merges-between selected not blocked  
       
Require Squashed Merges Into:
Merges-between selected not blocked  
       
Merge issues

There is 1 issue preventing you from merging this pull request.

  • Bit-Booster - Global Git and JIRA Hooks: [master] only permits fast-forward merges - you must rebase or squash [TKT-123]
Merge issues

There is 1 issue preventing you from merging this pull request.

  • Bit-Booster - Global Git and JIRA Hooks: [master] only permits merges from squashed branches, but [TKT-123] has 2 commits

JIRA Policy

Apply JIRA Policy Against:       
   

1. JIRA Commit Message Rules (Offline Checks)

Commit Messages Must:
Look for JIRA References:
Only Check JIRAs In Brackets:
"[TKT-8, TKT-9] UTF-8 bugs in TKT-5" 

2. JIRA Reference Rules (Online Checks)

JIRA References Must:

Invalid statuses:
JIRA Project Key Blacklist:
Ignore these JIRA imposters  
remote: -----
remote: Commit d8ce451e404e575 rejected.
remote:
remote: This commit does not reference a JIRA ticket in its commit message.
remote: Note: JIRA references must be in the first line of the commit message.
remote:       Also, they must be in brackets, e.g., [TKT-123]
remote: -----
remote: -----
remote: Commit messages on "master" must reference valid JIRA tickets,
remote: but Bitbucket cannot access JIRA to see if "[ABC-1]" exists.
remote: Your Bitbucket account is missing OAUTH credentials into JIRA.
remote:
remote: Use this URL to set that up:
remote: http://localhost:7990/bitbucket/plugins/servlet/applinks/oauth/login-dance/authorize
remote: -----
remote: -----
remote: Commit rejected.
remote: Commits on "master" must satisfy JIRA policy.
remote: The following JIRA tickets do not exist on your JIRA server:
remote:
remote:   [ABC-1]
remote:
remote: Please remove references to those tickets from your commit messages.
remote: -----
remote: -----
remote: Push rejected. Commits to "master" must satisfy JIRA policy.
remote: The following JIRA tickets have invalid statuses for receiving commits:
remote:
remote:   [ABC-1] - Done.
remote:
remote: Either remove references to those tickets from your commit messages,
remote: or adjust the tickets in JIRA so they satisfy the status check.
remote: -----
remote: -----
remote: Push rejected. Commits to "master" must satisfy JIRA policy.
remote: Some referenced JIRA tickets failed the JQL validation check.
remote:
remote: JQL:   "TYPE != task"
remote:
remote: Failing JIRA tickets:
remote:
remote:   [ABC-1]
remote:
remote: Either remove references to those tickets from your commit messages,
remote: or adjust the tickets in JIRA so they satisfy the JQL validation.
remote: -----