64 lines
2.6 KiB
Markdown
64 lines
2.6 KiB
Markdown
# Git hooks
|
|
|
|
```
|
|
Status: Current
|
|
Owner: <who maintains this>
|
|
Last reviewed: <YYYY-MM-DD>
|
|
Governs: docs/architecture/githooks/** and the .githooks/ a project installs
|
|
Review trigger: A new guard the repository wants run before a commit; any change
|
|
to what a commit message must contain.
|
|
```
|
|
|
|
Three hooks, and the reason they live in the repository rather than in
|
|
`.git/hooks`: that directory is not versioned, so a hook living there protects
|
|
exactly one clone on exactly one machine. These are committed, and one command
|
|
points git at them.
|
|
|
|
## Install
|
|
|
|
```bash
|
|
mkdir -p .githooks
|
|
cp docs/architecture/githooks/{pre-commit,commit-msg,post-commit} .githooks/
|
|
chmod +x .githooks/*
|
|
git config core.hooksPath .githooks
|
|
```
|
|
|
|
`core.hooksPath` is per-clone, so every checkout runs that last line once. Say so
|
|
in the project README — an uninstalled hook fails silently, which is the same
|
|
class of problem the hooks exist to prevent.
|
|
|
|
## What each one does
|
|
|
|
| Hook | Guard |
|
|
| --- | --- |
|
|
| `pre-commit` | typecheck, then the test suite, when `.ts`/`.tsx` is staged |
|
|
| `commit-msg` | refuses a message with no conventional type |
|
|
| `post-commit` | pushes to the remote, so a guarded commit does not sit locally |
|
|
|
|
## Two settings worth making before you rely on them
|
|
|
|
**`pre-commit` will use a local test database if you tell it where one is.**
|
|
Set `TEST_DB_PORT` and `TEST_DB_URL` together. Leave them unset and the database
|
|
suites skip, which is the right default on a machine with no Postgres — but it
|
|
means the hook is running a fraction of the suite, so `release.sh` is
|
|
deliberately stricter and refuses rather than warns.
|
|
|
|
**`post-commit` pushes.** That is the intent — the commit that first added a
|
|
pre-commit hook to the reference project sat unpushed for a day, guarded and
|
|
invisible — but it is a surprise if you were not expecting it. Read it before
|
|
installing it on a repository with a protected branch.
|
|
|
|
It has a second consequence worth knowing about: the push is what the Command
|
|
Center reads, so **whatever documentation was not in that commit is now behind
|
|
the code by one push**. That is the mechanical reason `docs/WORK_CYCLE.md` asks
|
|
for doc edits in the same commit as the change rather than in a tidy-up
|
|
afterwards — with this hook installed, "I will document it next commit" means
|
|
the site has already published the version without it.
|
|
|
|
## Why a hook and not CI
|
|
|
|
Both. These are the guards that must run before the artifact exists: a hook that
|
|
fires after a push, or a CI job that fires after a publish, catches the problem
|
|
once it is already somewhere it cannot be taken back from. CI is the second
|
|
opinion; this is the one that runs first.
|