#!/usr/bin/env bash set -euo pipefail readonly HEADER_PATTERN='^(feat|fix|perf|refactor|test|docs|build|ci|chore|revert)(\([[:alnum:]./_-]+\))?!?: .+$' is_conventional_header() { [[ "$1" =~ ${HEADER_PATTERN} ]] } run_self_test() { local subject for subject in \ 'feat(rpc): add request timeout' \ 'fix!: preserve legacy config behavior' \ 'docs(release): document versioning'; do is_conventional_header "${subject}" || { echo "expected valid Conventional Commit: ${subject}" >&2 exit 1 } done for subject in 'update dependency' 'feature: invalid type' 'fix missing separator'; do if is_conventional_header "${subject}"; then echo "expected invalid Conventional Commit: ${subject}" >&2 exit 1 fi done } if [ "${1:-}" = "--self-test" ]; then run_self_test echo "Conventional Commit validator self-test passed" exit 0 fi baseline="${1:-v1.0.0}" git rev-parse --verify "${baseline}^{commit}" >/dev/null invalid=0 while IFS=$'\t' read -r commit subject; do if ! is_conventional_header "${subject}"; then echo "${commit}: ${subject}" >&2 invalid=1 fi done < <(git log --format='%H%x09%s' --no-merges "${baseline}..HEAD") if [ "${invalid}" -ne 0 ]; then echo "Conventional Commit validation failed after ${baseline}" >&2 exit 1 fi echo "Conventional Commit validation passed after ${baseline}"