Branch Name Lint

BranchNameLint

Flexible git branch naming convention checker with some extra validating features

Pub

Usage

Requirements:

  • Dart 3.6.0+
  • Git 2.22.0+

Installation

dart pub add --dev branch_name_lint

Command Line Arguments

The tool supports the following command line arguments:

--branch-name / -b

Override the branch name instead of using the current git branch. This is especially useful in CI/CD environments where you want to validate a specific branch name.

Examples:

# Local usage (uses git to get current branch)
dart run branch_name_lint

# Using environment variables in CI/CD
dart run branch_name_lint -b $CI_BRANCH_NAME
dart run branch_name_lint -b $GITHUB_HEAD_REF

--help / -h

Display usage information and available options.

dart run branch_name_lint --help

Git hook

With husky (a tool for managing git hooks), commitlint cli can be used in commmit-msg git hook

Set pre-push hook:

dart pub add --dev husky
dart run husky install
dart run husky set .husky/pre-push 'dart run branch_name_lint'

Make a commit:

git add .
git commit -m "Keep calm and commit"
# `dart run branch_name_lint` will run

To get the most out of commitlint you'll want to automate it in your project lifecycle. See our Setup guide for next steps.

Configuration

Config schema

interface Config {
  pattern: String;
  params: Record<String, String[]>;
  prohibited: String[];
  allowed: String[];
}

User provided configuration

Under the hood BranchNameLint uses cosmicconfig to load its configuration.

You can create one of the following:

  • branch_name_lint property in the pubspec.yaml file
  • Extensionless "rc file" in .yaml format
    • branch_name_lint
  • "rc file" with .json or .yaml extensions
    • branch_name_lint.yaml
    • branch_name_lint.dart
  • ".config.dart" file
    • branch_name_lint.config.dart

Moreover, these filenames support dot as the first char start's writing (like .branch_name_lint.yaml)

don't forget to do final config = Config.create{...} in .dart config files

BranchNameLint will merge found configuration with its defaults.

Default configuration

pattern: ":type/:task_:description"

params:
  type:
    - feature
    - fix
    - hotfix
    - release
  task: "[0-9]+"
  description: "[a-z0-9-]+"
prohibited:
  - 'main'
  - 'ci'
allowed:
  - test

Linting

BranchNameLint uses path-to-regexp to check if branch name matches the pattern provided in config.

Firstly branch name will be checked if its prohibited or not. On the next step, if params are provided, pattern parts will be modified/populated using respective keys. For example:

(default configuration)
:type/:name => :type(feature|fix|misc|docs)/:name([a-z0-9-]+)

Please refer to path-to-regexp docs for advanced patterns.

Configuration recipes

Only check for protected branches

pattern:

params:

prohibited: 
  - main
  - main
  - build
  - test
  - wip
  - ci
  - release

Always allow whitelist branches

pattern: ":type/:task"

params:
  type: [ feature, release, hotfix, fix]
  task: "[0-9]+"

allowed: 
  - main
  - development
  - ci

Dot-separated username & issue id

example/branch_name_lint_example.dart

import 'package:branch_name_lint/branch_name_lint.dart';

final config = Config.create((context) => {
  'pattern': ':username:type/:issue',
  'params': {
    'type': [
      'feature',
      'fix',
      'misc',
      'docs',
    ],
    'issue': ['lbn-[a-z0-9-]+'],
  },
  'prohibited': [
    'main',
  ],
});

Scopes for monorepo

feature/my-awesome-app/yet-another-great-feature

(imaginary monorepo structure)
packages/
    app
    shared
branch_name_lint.yaml
import 'package:branch_name_lint/branch_name_lint.dart';

final config = Config.create((context) => {
  'pattern': ':type/:scope/:description',
  'params': {
    'type': [
      'feature',
      'fix',
      'misc',
      'docs',
    ],
    'scope': context.readDirectories('./packages'),
  },
  'prohibited': [
    'main',
    'main',
    'build',
    'test',
    'wip',
    'ci',
    'release',
  ],
});

Credits

This package is dart adaptation of the npmjs package

Libraries

branch_name_lint