Examples

Real-world configurations and usage patterns for different team workflows.

Team Configurations

Small Startup Team

Simple, flexible setup with optional ticket IDs:

import { defineConfig } from '@branchwright/cli';

export default defineConfig({
  branchTypes: [
    { name: 'feat', label: '✨ Feature' },
    { name: 'fix', label: '🐛 Bug Fix' },
    { name: 'chore', label: '🔧 Chore' },
  ],
  
  template: '{{type}}/{{desc}}',
  maxDescriptionLength: 40,
  
  // No ticket requirements
  rules: {
    ticketId: 'off',
  },
  
  // Streamlined workflow
  extraQuestions: {
    baseBranch: false,
    checkout: false,
    pushToRemote: false,
  },
});

Enterprise Team with Jira

Strict naming with required Jira tickets:

import { defineConfig } from '@branchwright/cli';

export default defineConfig({
  branchTypes: [
    { name: 'feature', label: 'Feature' },
    { name: 'bugfix', label: 'Bug Fix' },
    { name: 'hotfix', label: 'Hotfix' },
    { name: 'release', label: 'Release' },
  ],
  
  template: '{{type}}/{{ticket}}-{{desc}}',
  maxDescriptionLength: 50,
  descriptionStyle: 'kebab-case',
  
  rules: {
    ticketId: ['required', { 
      prefix: 'PROJ-',
      pattern: /^PROJ-\d+$/,
      message: 'Ticket must be format: PROJ-123'
    }],
  },
  
  ignoredBranches: [
    'main',
    'master', 
    'develop',
    'staging',
    'production'
  ],
  
  questions: {
    branchType: 'Select work type:',
    ticketIdRequired: 'Enter Jira ticket (PROJ-###):',
    description: 'Brief description (kebab-case):',
  },
});

GitHub Flow Team

Optimized for GitHub issues and pull requests:

import { defineConfig } from '@branchwright/cli';

export default defineConfig({
  branchTypes: [
    { name: 'feat', label: 'Feature' },
    { name: 'fix', label: 'Fix' },
    { name: 'docs', label: 'Documentation' },
    { name: 'refactor', label: 'Refactor' },
  ],
  
  template: '{{type}}/{{ticket}}-{{desc}}',
  
  rules: {
    ticketId: ['optional', { 
      prefix: 'gh-',
      pattern: /^gh-\d+$/
    }],
  },
  
  questions: {
    ticketId: 'GitHub issue number (optional):',
    description: 'PR description:',
  },
});

Monorepo Configuration

Include package/workspace names in branches:

import { defineConfig } from '@branchwright/cli';

export default defineConfig({
  branchTypes: [
    { name: 'feat', label: 'Feature' },
    { name: 'fix', label: 'Fix' },
    { name: 'chore', label: 'Chore' },
  ],
  
  // Custom template with package name
  template: '{{type}}/{{package}}-{{desc}}',
  
  // In practice, you might prompt for package
  // or detect it from the current directory
});

CI/CD Integration

GitHub Actions Validation

# .github/workflows/validate-branch.yml
name: Validate Branch Name

on:
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      
      - name: Install Branchwright
        run: npm install -g @branchwright/cli
      
      - name: Validate Branch Name
        run: brw lint ${{ github.head_ref }}
        env:
          BRANCH_NAME: ${{ github.head_ref }}

GitLab CI Validation

# .gitlab-ci.yml
validate-branch:
  stage: validate
  image: node:20
  script:
    - npm install -g @branchwright/cli
    - brw lint $CI_COMMIT_REF_NAME
  only:
    - merge_requests

Husky Pre-push Hook

# Install husky
npm install --save-dev husky
npx husky init

# .husky/pre-push
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# Validate branch name before push
npx @branchwright/cli lint || {
  echo ""
  echo "❌ Branch name validation failed"
  echo "Fix your branch name or use:"
  echo "  brw create"
  exit 1
}

Scripting Examples

Batch Branch Creation

#!/bin/bash

# Create multiple feature branches from a list
features=(
  "user-authentication"
  "payment-integration"
  "email-notifications"
  "admin-dashboard"
)

for feature in "${features[@]}"; do
  brw create -t feat -d "$feature" -y
  echo "Created feat/$feature"
done

Ticket-Based Branch Creation

#!/bin/bash

# Create branch from Jira ticket
TICKET=$1
DESCRIPTION=$2

if [ -z "$TICKET" ] || [ -z "$DESCRIPTION" ]; then
  echo "Usage: ./create-jira-branch.sh PROJ-123 'description'"
  exit 1
fi

brw create -t feat --ticket "$TICKET" -d "$description" -y --push

Integration with gh (GitHub CLI)

#!/bin/bash

# Create branch from GitHub issue
ISSUE_NUMBER=$(gh issue view --json number -q .number)
ISSUE_TITLE=$(gh issue view --json title -q .title | tr '[:upper:]' '[:lower:]' | tr ' ' '-')

brw create -t feat --ticket "gh-$ISSUE_NUMBER" -d "$ISSUE_TITLE" -y

# Create PR
gh pr create --title "feat: $ISSUE_TITLE" --body "Closes #$ISSUE_NUMBER"

Custom Rule Examples

Enforce Team Prefix

import { defineRule, defineConfig } from '@branchwright/cli';

const teamPrefixRule = defineRule(
  {
    id: 'team-prefix',
    meta: {
      title: 'Team prefix required',
      description: 'Branch must include team identifier',
    },
    defaultSeverity: 'required',
  },
  (context) => {
    const { teams } = context.options;
    const hasTeamPrefix = teams.some(team => 
      context.branchName.includes(`-${team}-`)
    );
    
    if (!hasTeamPrefix) {
      return {
        message: `Branch must include team: ${teams.join(', ')}`,
        suggestions: teams.map(t => 
          context.branchName.replace('-', `-${t}-`)
        ),
      };
    }
    return null;
  }
);

export default defineConfig({
  rules: {
    'team-prefix': ['required', { 
      teams: ['frontend', 'backend', 'mobile'] 
    }],
  },
});

Prevent WIP Branches

import { defineRule, defineConfig } from '@branchwright/cli';

const noWipRule = defineRule(
  {
    id: 'no-wip',
    meta: {
      title: 'No WIP branches',
      description: 'Work-in-progress markers not allowed',
    },
    defaultSeverity: 'required',
  },
  (context) => {
    const wipPatterns = ['wip', 'tmp', 'temp', 'test'];
    const hasWip = wipPatterns.some(pattern =>
      context.branchName.toLowerCase().includes(pattern)
    );
    
    if (hasWip) {
      return {
        message: 'Remove work-in-progress markers from branch name',
        suggestions: [
          wipPatterns.reduce(
            (name, pattern) => name.replace(pattern, ''),
            context.branchName
          ),
        ],
      };
    }
    return null;
  }
);

export default defineConfig({
  rules: {
    'no-wip': 'required',
  },
});

Maximum Branch Age

import { defineRule, defineConfig } from '@branchwright/cli';
import { execSync } from 'child_process';

const maxAgeRule = defineRule(
  {
    id: 'max-age',
    meta: {
      title: 'Branch age limit',
      description: 'Branches older than X days should be cleaned up',
    },
    defaultSeverity: 'optional',
  },
  (context) => {
    const { maxDays } = context.options;
    
    // Get branch creation date
    const timestamp = execSync(
      `git log --format=%ct ${context.branchName} | tail -1`
    ).toString();
    
    const ageInDays = (Date.now() - parseInt(timestamp) * 1000) / (1000 * 60 * 60 * 24);
    
    if (ageInDays > maxDays) {
      return {
        message: `Branch is ${Math.floor(ageInDays)} days old (max: ${maxDays})`,
      };
    }
    return null;
  }
);

export default defineConfig({
  rules: {
    'max-age': ['optional', { maxDays: 30 }],
  },
});

Advanced Workflows

Multi-Environment Setup

import { defineConfig } from '@branchwright/cli';

export default defineConfig({
  branchTypes: [
    { name: 'feat', label: 'Feature' },
    { name: 'fix', label: 'Fix' },
    { name: 'release', label: 'Release' },
    { name: 'hotfix', label: 'Hotfix' },
  ],
  
  template: '{{type}}/{{env}}-{{desc}}',
  
  ignoredBranches: [
    'main',
    'develop',
    'staging',
    'production',
  ],
  
  // Custom prompts for environment
  questions: {
    environment: 'Target environment:',
  },
});

Semantic Release Integration

import { defineConfig } from '@branchwright/cli';

export default defineConfig({
  // Match semantic-release branch types
  branchTypes: [
    { name: 'feat', label: 'Feature (minor)' },
    { name: 'fix', label: 'Fix (patch)' },
    { name: 'perf', label: 'Performance (patch)' },
    { name: 'revert', label: 'Revert (patch)' },
  ],
  
  template: '{{type}}/{{desc}}',
  
  // Enforce conventional commit style
  descriptionStyle: 'kebab-case',
  maxDescriptionLength: 50,
});

Release Train Workflow

import { defineConfig } from '@branchwright/cli';

export default defineConfig({
  branchTypes: [
    { name: 'feat', label: 'Feature' },
    { name: 'fix', label: 'Fix' },
    { name: 'release', label: 'Release Branch' },
  ],
  
  template: '{{type}}/{{version}}-{{desc}}',
  
  ignoredBranches: [
    'main',
    'develop',
    /^release\/v\d+\.\d+$/,  // release/v1.2
  ],
});