The convention was documented in CONTRIBUTING.md but nothing enforced it, and no decision was on record for the pre-self-hosting `Phase` history. - tools/git-hooks/commit-msg — rejects a summary that is not a Conventional Commit. tools/git-hooks/lib.sh holds the single rule (types, scope, `!`, and the merge/revert/autosquash exemptions) so the hook and CI cannot drift. - tools/git-hooks/lint-range.sh — lints a commit range with that same rule. - .forgejo/workflows/commit-lint.yml — runs it over the new commits on every push and PR, as the backstop for contributors who have not enabled the hook. - Fix the pre-commit hook, which pointed at the old build/ludic-fmt path (the toolchain moved to bin/) and so silently no-op'd; it now finds bin/ludic-fmt. - CONTRIBUTING.md — full type/scope table, the one-line enable (`git config core.hooksPath tools/git-hooks`), and a **Git history** section recording the decision: leave the pushed `Phase`-era history as-is (a rewrite is destructive and non-reversible for anyone who cloned); enforce the convention going forward; let #33's first release tag double as the clean `v0` baseline that brackets the old prefix without touching a commit. Verified: the hook accepts feat/fix/ci/refactor(!)/merge/revert and rejects "added regex" / "Fix bug" / "WIP"; lint-range passes recent history and flags the old `Phase 8b:` commit. Closes #34 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
48 lines
1.8 KiB
YAML
48 lines
1.8 KiB
YAML
name: commit-lint
|
|
|
|
# Enforce Conventional Commits in CI, as a backstop to the local commit-msg hook
|
|
# (which a contributor only gets after `git config core.hooksPath tools/git-hooks`).
|
|
# Lints every new commit's summary line against tools/git-hooks/lib.sh — the same
|
|
# rule the hook uses, so the two can never drift.
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
workflow_dispatch: {}
|
|
|
|
jobs:
|
|
conventional-commits:
|
|
runs-on: docker
|
|
container: node:20-bookworm
|
|
steps:
|
|
- name: Check out with history
|
|
env:
|
|
BEFORE: ${{ github.event.before }}
|
|
BASE: ${{ github.base_ref }}
|
|
run: |
|
|
set -eu
|
|
git config --global --add safe.directory '*'
|
|
# Full clone so both endpoints of the range are present.
|
|
git clone https://git.workshopsoft.io/workshopsoft/ludic.git .
|
|
git checkout "${GITHUB_SHA}" 2>/dev/null || git checkout "${GITHUB_REF_NAME:-main}"
|
|
|
|
- name: Lint the new commits
|
|
env:
|
|
BEFORE: ${{ github.event.before }}
|
|
BASE: ${{ github.base_ref }}
|
|
run: |
|
|
set -eu
|
|
# Pick the range of *new* commits to lint:
|
|
# - pull_request: base branch .. this commit
|
|
# - push: the pushed range (event.before .. this commit)
|
|
# - new branch / unknown: just the tip commit
|
|
if [ -n "${BASE:-}" ]; then
|
|
git fetch --quiet origin "${BASE}" 2>/dev/null || true
|
|
RANGE="origin/${BASE}..${GITHUB_SHA}"
|
|
elif [ -n "${BEFORE:-}" ] && ! printf '%s' "$BEFORE" | grep -qE '^0+$'; then
|
|
RANGE="${BEFORE}..${GITHUB_SHA}"
|
|
else
|
|
RANGE="${GITHUB_SHA}~1..${GITHUB_SHA}"
|
|
fi
|
|
echo "linting range: $RANGE"
|
|
sh tools/git-hooks/lint-range.sh "$RANGE"
|