Contributing#
Commit messages#
We follow the Go commit message convention (the same style Tailscale uses). The subject line is:
pkg/path: short summary in the imperative mood
- Prefix: the package or path affected, from the repo root. Use a real Go
package (
appview/pages,knot2/xrpc) or the actual top-level path — e.g..tangled/workflows:, notworkflows:. If several packages are touched, either abbreviate to top-level names (api,lexicons:) or group subpackages with braces (appview/{config,state}:). Do not use Conventional Commit types (feat:,fix:,chore:); name the package instead. - Summary: a lowercase, imperative-mood verb phrase — "add", not "added" / "adds" / "adding". No trailing period. Keep it under ~76 characters.
- Leave a blank line between the summary and the body.
- Use the body to explain what changed and why, wrapped at ~76 columns.
Examples#
ogre: pluralize metrics # good
knot2/xrpc: forward X-Forwarded-For headers # good
api,lexicons: add lexicons for private xrpc # good
appview/{config,state}: gate xrpc router # good
fix: pluralize metrics in ogre # bad — Conventional Commit prefix
workflows/rust: run checks and tests # bad — no top-level `workflows/`; use `.tangled/workflows`
bobbin extra certs # bad — no package prefix
web: Added reactions # bad — capitalized, past tense
Reference: https://go.dev/wiki/CommitMessage.
Enforcement#
Commit messages are linted by .tangled/hooks/commit-msg-lint.sh,
which runs both in CI and, optionally, as a local git hook.
CI#
The commit-lint workflow runs on every
push and pull request to master. On a pull request it lints every commit
between the target branch and the PR head; on a push it lints the pushed commit.
Local git hook#
Install the repo's git hooks once, so bad messages are caught before you commit:
./.tangled/hooks/install.sh
This points core.hooksPath at .tangled/hooks. Bypass the check for a single
commit with git commit --no-verify. To undo: git config --unset core.hooksPath.
jj (jujutsu)#
jj does not run git hooks, so jj users rely on the CI check. You can lint a
change locally at any time:
.tangled/hooks/commit-msg-lint.sh --rev @ # lint the current change
.tangled/hooks/commit-msg-lint.sh --range main @ # lint a range