In this page

What is this?

This page describes the solution for common problems and efficient techniques to implement powerful commit policies with Jira.

Well-formatted commit messages

Minimum length

Use the commit message condition with this regex to require at least 10 character long commit messages (excluding whitespace):

(?:\S|\S\s*){10,} ## regex

Issue key in the beginning of the commit message

Use the commit message condition with this regex, so that users need to enter an issue key from the FOO or BAR projects in the commit message. Use this with a JQL condition within the same rule, to restrict the issue keys allowed:

(?s)(?:FOO|BAR)-\d+.* ## regex

The leading (?s) allows multi-line commit messages.

Enforcing the 50/72 rule (Linux Kernel style formatting for commit messages)

To adopt this best practice promoted by the Linux Kernel team, check out our blog post .

Powerful JQL conditions

Committing against a project

Use the JQL condition with this query (JXLS is the key of the project):

project = JXLS

Committing against issues assigned to the committer

For any other Version Control System, but Subversion, use the JQL condition with this query (JXLS is the key of the project):

project = JXLS and assignee = currentUser()

For Subversion, the JQL is:

project = JXLS and assignee = "$committer.userName"

For more about the two approaches, read the $committer.username JQL variable.

Committing against issues assigned to the committer or generally by a reviewer

This is a smarter version of the previous tip. The problem with original version is that if the changes are reviewed by another developer (supervisor), then he can't commit his additional changes against the original issue, because that is assigned to the developer making the original changes. To solve this, we allow project leads to commit against any issue in their projects, in addition to the original rule! This is dead simple and works wonderfully in practice.

For any other Version Control System, but Subversion, use the JQL condition with this query (JXLS is the key of the project):

project = JXLS and (assignee = currentUser() or project in projectsLeadByUser())

For Subversion, the JQL is:

project = JXLS and (assignee = "$committer.userName" or project in projectsLeadByUser("$committer.userName"))

For more about the two approaches, read the $committer.username JQL variable.

Committing against user stories in the current sprint

Use the JQL condition with this query:

project = JXLS and issuetype = Story and sprint in openSprints()

Committing against the current version

Use the JQL condition with this query:

project = JXLS and fixVersion in (1.0.0, 1.0.1)

Committing against a list of unresolved issues

Use the JQL condition with a query enumerating the allowed issue keys:

key in ("JXLS-1", "JXLS-2", "JXLS-3") and resolution is empty

Committing against subtasks of unresolved issues, linked issues, versions matching a pattern, etc.

Although the default JQL function set is great, the ScriptRunner and the JQL Tricks app provide various additional JQL functions! Make sure to check those out if you have more sophisticated requirements.

Simple access control

Committer must be in a list of users

Use the committer attribute condition to match the username attribute to a glob pattern that enumerates the names of the allowed committers:

{john,jack,tom} ## glob

Committer must be in the "jira-developers" group

Use the committer must have a valid Jira account condition, and select the jira-developers group.

Filtering files by file types

Allowing files by file types

Use the file condition with a simple glob pattern enumerating the allowed file extensions in alphabetical order:

*.{css,java,js,py,soy,xml,vm} ## glob

Rejecting files by file types

As an inverse of the previous technique, enumerate the file extensions that are not allowed:

!({*.class,*.pyc,*.tmp}) ## glob

File naming conventions

Enforcing Java file naming conventions

Standard Java source code filename conventions.

(((.*/|^)([A-Z][a-z0-9_-]+)+\.java)|(((?!\.java$)[/\w.-])+))$ ## regex

Locking

Locking repositories

Disable all commits to the repository:

(?!.*) ## regex

Locking directories

Disable commits touching any file a specific top-level directory:

!(temp/) ## glob

The same works for complete paths, too:

!(src/main/java/com/company/internal/) ## glob

Locking files

Disable commits to a certain file, regardless of which directory it is located in:

!({*/README.txt,README.txt}) ## glob

The same for multiple files:

!({*/README.txt,README.txt,*/LICENSE.txt,LICENSE.txt,*/pom.xml,pom.xml}) ## glob

Automatic development workflows

You can easily automate development workflows (without writing code) by installing Better DevOps Automation for Jira, a companion app for Better Commit Policy. Learn more about configuring automation rules in this app's documentation.

On commit, branch and tag creation

Better DevOps Automation offers the following triggers for the workflows that should be triggered by VCS events:

  1. Changeset Accepted
  2. Changeset Rejected
  3. Branch Created
  4. Tag Created
  5. Commit Created

Using these triggers, you can automatically send notifications, run CI/CD builds, execute programs, etc.

On commands entered to the commit message

In addition to the previous triggers, you can also use Genius Commit Created. It can parse custom commands and their parameters from the commit messages, then trigger workflows using the parsed values as variables.

Although Genius Commits are somewhat similar to Smart Commits, this feature is much more flexible as it allows defining custom commands with custom parameters and custom behavior. Make sure you check it out!

Bypassing commit verification

Bypassing commit verification for a series of commits

It might happen that you have a strong excuse why not to verify a bunch of commits.

For example:

  • You have commits created before you started using Better Commit Policy and you now want to push them to the repo.
  • You merged a branch that contained valid commits at the time of creation, but at the moment, they are not satisfying the policy.
    A common case is when the policy utilizes a JQL expression that no longer holds, e.g. status = In Progress.
  • A team member forgot to set up his company email address on his new workstation and only realizes this when it's too late or tedious to fix everything up.
    You may decide to accept the changes and ask him kindly to be more prudent next time.

In these cases, you can either create a dummy commit (which only touches some whitespace) or amend your last commit message (better). In both cases, the trick is to include the bypass expression in the message.

Bypassing a single condition

If you have a condition "A" that you want to enforce generally, but not for a specific user, there is an easy trick:

  1. Move "A" to its own rule.
  2. Add another condition "B" to the same rule, with the type Committer attribute must match a pattern.
  3. Configure "B" to accept the commit only if the user name is "alice".
  4. Set the rule encompassing "A" and "B" to require "at least one" condition.

If "alice" commits, then ("B" is true and) "A" does not matter. For other users, "A" must be true (and "B" cannot ever be true). And this is what we want.

Selecting the actor user for the app

All commit conditions are evaluated on behalf of the Jira user account, who is specified by its username in the hook configuration. This affects e.g. the behavior of the JQL condition, because the JQL query is executed based on that user's permissions. If your JQL is project = FOOBAR, but the user has no access to FOOBAR, the query will return nothing even if the commit message mentioned an issue from FOOBAR.

A good practice is to choose a user account who has view access to most resources: all projects, all issues, groups, user accounts, etc. Please note this user does not need to have update permissions, only view!

Recommendations:

  • Simplest: use your admin account (this is the default in the generated hook configuration).
  • Safest: create an intuitively named user account (ex: commitpolicy), give this account view permissions to everything relevant, and use this account in the hook configuration.

Resetting the failed login attempts counter

As its default behavior, Jira will lock your account and present a CAPTCHA on the login form after a few unsuccessful login attempts. Since the hook scripts authenticate each REST API requests separately, the unsuccessful login attempts limit can be reached very quickly if you mis-configured the username and password in the hook configuration. Unfortunately, not being presented with a graphical user interface in the hook script you will not be able to enter the CAPTCHA text, thus you will not be able to authenticate even after triple-checking the username and password!

To resolve this, you normally have to logout and re-login via the web UI, which resets the unsuccessful login attempts counter.

If you are an administrator (and you are, if you generated the hook script using the app's wizard) there is also a quicker solution: go to Administration → User management and clear the failed login attempts counter with one click.

Tip: you can increase the allowed login attempts or even disable this feature altogether in Jira.

Questions?

Ask us any time.