From 5582cc7cdcea6bdf8fdd21da87efc64f22a01ed8 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Mon, 27 Oct 2025 20:26:47 +0100 Subject: [PATCH] build: add commit-msg hook to enforce Conventional Commits format Adds a commit-msg hook that validates commit messages follow the Conventional Commits format before allowing the commit. This prevents commits with incorrectly formatted messages (e.g., 'Fix:' instead of 'fix:') and ensures compatibility with our GitHub CI checks. The hook is installed via: cp .githooks/commit-msg .git/hooks/ chmod +x .git/hooks/commit-msg Or configure git to use the hooks directory: git config core.hooksPath .githooks [AI-assisted debugging and comment] --- .githooks/README.md | 72 ++++++++++++++++++++++++++++++++++++++++++++ .githooks/commit-msg | 41 +++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 .githooks/README.md create mode 100755 .githooks/commit-msg diff --git a/.githooks/README.md b/.githooks/README.md new file mode 100644 index 000000000..e7bcafeb3 --- /dev/null +++ b/.githooks/README.md @@ -0,0 +1,72 @@ +# Git Hooks + +This directory contains git hooks that enforce code quality and commit message standards. + +## Installation + +To install these hooks, run from the repository root: + +```bash +# Install commit-msg hook +cp .githooks/commit-msg .git/hooks/ +chmod +x .git/hooks/commit-msg + +# Or configure git to use this hooks directory +git config core.hooksPath .githooks +``` + +## Available Hooks + +### commit-msg + +Validates that commit messages follow [Conventional Commits](https://www.conventionalcommits.org/) format. + +**Required format:** +``` +type(scope): description + +[optional body] + +[optional footer(s)] +``` + +**Allowed types:** +- `feat`: New feature +- `fix`: Bug fix +- `docs`: Documentation changes +- `style`: Code style changes (formatting, etc.) +- `refactor`: Code refactoring +- `perf`: Performance improvements +- `test`: Adding or modifying tests +- `build`: Build system or dependency changes +- `ci`: CI/CD changes + +**Examples:** +```bash +fix: resolve WebSocket connection timeout +feat(network): add peer reputation scoring +build(deps): bump tokio from 1.0 to 1.1 +fix!: breaking change to API +``` + +**Important:** +- Type must be **lowercase** (e.g., `fix:` not `Fix:`) +- This matches the CI check on GitHub PRs +- Breaking changes can be indicated with `!` after the type + +### pre-commit + +The pre-commit hook (already installed in `.git/hooks/pre-commit`) checks: +- Code formatting with `cargo fmt` +- Clippy lints +- Special TODO comments that block commits +- Disabled tests using Claude + +**Note:** The pre-commit hook is specific to your local setup and is already installed by git hooks installation scripts. It's not included in this directory as it's environment-specific. + +## Why This Matters + +- **CI Compatibility**: Our GitHub Actions CI checks PR titles for Conventional Commits format +- **Consistency**: Everyone uses the same commit message style +- **Automation**: Makes it easier to generate changelogs and release notes +- **Early Feedback**: Catch issues locally before pushing to GitHub diff --git a/.githooks/commit-msg b/.githooks/commit-msg new file mode 100755 index 000000000..66cd9c530 --- /dev/null +++ b/.githooks/commit-msg @@ -0,0 +1,41 @@ +#!/bin/bash +# Commit message hook that validates Conventional Commits format + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Get the commit message file path (passed as first argument) +COMMIT_MSG_FILE=$1 + +if [ ! -f "$COMMIT_MSG_FILE" ]; then + echo -e "${RED}Error: Commit message file not found${NC}" + exit 1 +fi + +# Get the first line of the commit message +FIRST_LINE=$(head -n1 "$COMMIT_MSG_FILE") + +# Conventional Commits pattern: type(scope): description OR type: description +# type must be lowercase and from allowed list +# type can optionally be followed by ! for breaking changes +CONVENTIONAL_PATTERN="^(feat|fix|docs|style|refactor|perf|test|build|ci)(\([a-z0-9_-]+\))?!?: .+" + +if echo "$FIRST_LINE" | grep -qE "$CONVENTIONAL_PATTERN"; then + exit 0 +else + echo -e "${RED}✗ Commit message doesn't follow Conventional Commits format${NC}" + echo -e "${YELLOW}First line must match pattern: type(scope): description${NC}" + echo -e "${YELLOW}Allowed types: feat, fix, docs, style, refactor, perf, test, build, ci${NC}" + echo -e "${YELLOW}Type must be lowercase. Examples:${NC}" + echo -e " ${GREEN}fix: resolve WebSocket connection timeout${NC}" + echo -e " ${GREEN}feat(network): add peer reputation scoring${NC}" + echo -e " ${GREEN}build(deps): bump tokio from 1.0 to 1.1${NC}" + echo -e " ${GREEN}fix!: breaking change to API${NC}" + echo "" + echo -e "${RED}Your commit message:${NC}" + echo -e "${YELLOW}$FIRST_LINE${NC}" + exit 1 +fi