|
| 1 | +name: Branch Name Validation |
| 2 | + |
| 3 | +permissions: |
| 4 | + contents: read |
| 5 | + |
| 6 | +on: |
| 7 | + push: |
| 8 | + branches-ignore: |
| 9 | + - main |
| 10 | + pull_request: |
| 11 | + types: [opened, reopened, synchronize] |
| 12 | + |
| 13 | +jobs: |
| 14 | + check-branch-name: |
| 15 | + name: Check Branch Name |
| 16 | + runs-on: ubuntu-latest |
| 17 | + |
| 18 | + outputs: |
| 19 | + branch_valid: ${{ steps.validate.outputs.branch_valid }} |
| 20 | + |
| 21 | + steps: |
| 22 | + - name: Branch Name Validation |
| 23 | + id: validate |
| 24 | + shell: bash |
| 25 | + run: | |
| 26 | + BRANCH_NAME="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME:-${GITHUB_REF#refs/heads/}}}" |
| 27 | + echo "Checking branch: $BRANCH_NAME" |
| 28 | +
|
| 29 | + # Allow main explicitly |
| 30 | + if [[ "$BRANCH_NAME" == "main" ]]; then |
| 31 | + echo "Branch is main. OK." |
| 32 | + echo "branch_valid=true" >> "$GITHUB_OUTPUT" |
| 33 | + exit 0 |
| 34 | + fi |
| 35 | +
|
| 36 | + # New pattern: category/slug |
| 37 | + # - category: one of the common branch prefixes (see allowed list below) |
| 38 | + # - slug: 3-50 chars, lowercase letters or digits, may include '-' or '_' inside |
| 39 | + # but MUST start and end with an alphanumeric character (no leading/trailing -/_) |
| 40 | + # Examples: feature/add_something, bug/fix-login-issue, docs/update-readme |
| 41 | + PATTERN='^(feature|bug|fix|chore|docs|test|testing|performance|refactor|ci\-cd|build|release|hotfix|experiment|task|security|special|status)\/[a-z0-9][a-z0-9_-]{1,48}[a-z0-9]$' |
| 42 | +
|
| 43 | + if [[ "$BRANCH_NAME" =~ $PATTERN ]]; then |
| 44 | + echo "✅ Branch name is valid: $BRANCH_NAME" |
| 45 | + echo "branch_valid=true" >> "$GITHUB_OUTPUT" |
| 46 | + exit 0 |
| 47 | + else |
| 48 | + echo "" |
| 49 | + echo "❌ Invalid branch name: $BRANCH_NAME" |
| 50 | + echo "-------------------------------------------------------------------" |
| 51 | + echo "Expected format: <category>/<slug>" |
| 52 | + echo " - category: a short lowercase prefix that indicates intent (examples below)." |
| 53 | + echo " - slug: human-readable identifier (3-50 chars), lowercase letters/digits, may" |
| 54 | + echo " include '-' or '_' inside, but MUST NOT start or end with '-' or '_'" |
| 55 | + echo "" |
| 56 | + echo "Allowed category examples (map to your repo labels):" |
| 57 | + echo " feature, bug, fix, chore, docs, test/testing, performance, refactor, ci-cd," |
| 58 | + echo " build, release, hotfix, experiment, task, security, special, status" |
| 59 | + echo "" |
| 60 | + echo "Branch naming rules summary:" |
| 61 | + echo " - Lowercase only (a-z), numbers (0-9), '-' and '_' allowed inside the slug" |
| 62 | + echo " - Exactly one '/' separating category and slug (no extra path segments)" |
| 63 | + echo " - Slug must start/end with alphanumeric (no leading/trailing '-' or '_')" |
| 64 | + echo " - Slug length: 3 to 50 characters" |
| 65 | + echo "" |
| 66 | + echo "Examples of valid branch names:" |
| 67 | + echo " feature/add_something" |
| 68 | + echo " bug/fix-login-issue" |
| 69 | + echo " docs/update-readme" |
| 70 | + echo " hotfix/urgent-db-fix" |
| 71 | + echo " chore/cleanup-config" |
| 72 | + echo " security/fix-vulnerability" |
| 73 | + echo "" |
| 74 | + echo "Labels guidance (informational): map your category to the appropriate label group." |
| 75 | + echo " e.g. 'feature' -> type: feature, 'bug' -> type: bug, 'docs' -> docs:update needed" |
| 76 | + echo " Use labels after creating the PR; this check only enforces branch naming." |
| 77 | + echo "-------------------------------------------------------------------" |
| 78 | + echo "" |
| 79 | + echo "branch_valid=false" >> "$GITHUB_OUTPUT" |
| 80 | + exit 1 |
| 81 | + fi |
0 commit comments