engineering-handbook/commit-messages.md

138 lines
5.1 KiB
Markdown

# Commit Messages
> Adapted from [commit-messages-guide](https://github.com/RomuloOliveira/commit-messages-guide) by Romulo Oliveira, licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/).
Sea Haven uses [Conventional Commits](https://www.conventionalcommits.org/) for every commit and PR title. A structured `type(scope): description` header keeps history scannable, drives tooling (changelogs, release tagging, PR-title linting), and maps cleanly onto [SemVer](git-workflow.md#versioning).
## Format
```
type(scope): description
```
- **type** (required): the category of change, from the [Types](#types) table below.
- **scope** (optional): the area of the codebase affected, in parentheses and lowercase (`auth`, `api`, `parser`, `deps`). Omit it when the change is broad or no single scope fits.
- **description** (required): a short summary in imperative mood, lowercase, with no trailing period.
Examples:
```
feat(parser): add retry logic for transient upstream failures
fix(auth): correct null check in session handler
docs: document the CI-on-merge workflow
chore(deps): bump aws-cdk-lib to 2.150.0
```
## Types
| Type | Use for |
|---|---|
| `feat` | A new feature or capability |
| `fix` | A bug fix |
| `docs` | Documentation only |
| `style` | Formatting or whitespace with no behavior change |
| `refactor` | A code change that neither fixes a bug nor adds a feature |
| `perf` | A change that improves performance |
| `test` | Adding or correcting tests |
| `build` | Build system, packaging, or dependency changes |
| `ci` | CI/CD configuration and workflows |
| `chore` | Routine maintenance that doesn't touch source or tests |
| `revert` | Reverting a previous commit |
| `release` | Cutting a release (version bump, tag, changelog) |
## Rules
### Keep the header short
Keep the whole header (type, scope, and description) under 72 characters, and aim to keep the description itself around 50. The header is for scanning; details go in the body.
### Use imperative mood in the description
Write what the commit *does*, not what you *did*.
| Good | Bad |
|---|---|
| `feat: add retry logic to payment processor` | `feat: added retry logic to payment processor` |
| `fix: correct null check in auth handler` | `fix: fixed null check in auth handler` |
| `refactor: remove deprecated endpoint` | `refactor: removing deprecated endpoint` |
### Lowercase the description, no trailing period
The type carries the emphasis, so the description stays lowercase and unpunctuated.
| Good | Bad |
|---|---|
| `fix: correct null check in auth handler` | `fix: Correct null check in auth handler.` |
### Explain "why," not "what"
The diff shows what changed. The body should explain why.
| Good | Bad |
|---|---|
| `perf: increase timeout to handle slow upstream responses` | `perf: change timeout from 30 to 60` |
| `build: switch to arm64 to reduce Lambda cold start cost` | `build: update architecture setting` |
### No generic descriptions
A valid type does not excuse a vague description. These are not acceptable:
- `fix: stuff`
- `chore: update code`
- `chore: misc changes`
- `chore: address review comments`
Every commit should describe a specific change. `WIP` commits do not belong on shared branches.
### No self-referential language
| Good | Bad |
|---|---|
| `fix: correct race condition in queue processor` | `fix: this commit fixes a race condition` |
| `feat: add input validation for email field` | `feat: this PR adds validation` |
| `refactor: simplify auth middleware for clarity` | `refactor: I refactored the auth middleware` |
## Breaking changes
Mark a breaking change with a `!` before the colon, and add a `BREAKING CHANGE:` footer describing the migration. Breaking changes drive a SemVer MAJOR bump (see [Versioning](git-workflow.md#versioning)).
```
feat(api)!: remove the deprecated /v1/receipts endpoint
BREAKING CHANGE: clients must migrate to /v2/receipts. The v1
response shape is no longer returned.
```
## Template
```
type(scope): description (header under 72 chars, imperative, lowercase)
Optional body wrapped at 72 characters. Explain the problem
this commit solves and why this approach was chosen. Mention
side effects or non-obvious consequences.
Refs: PROJ-123, #123
```
## Referencing issues
Use the `Refs:` trailer to point at the work this commit relates to:
- **Jira key** (`DEV-123`, `PLAT-7`, `SEC-4`) when the work tracks a Jira issue. The GitHub for Jira app reads the key and threads the commit into the issue's development panel. See [git-workflow.md](git-workflow.md#linking-to-jira).
- **GitHub issue** (`#123`) for repos where GitHub Issues are enabled (contractor and fork repos only).
The Jira key is required in the PR title suffix `(KEY-123)`. Including it in the `Refs:` trailer of each commit is recommended but not required — the link forms as long as the key appears in the PR title.
## Example
```
feat(payments): add retry logic for transient upstream failures
The payment processor occasionally returns 503 during
deployments. Without retries, these surface as user-facing
errors. This adds exponential backoff with 3 attempts,
which matches the upstream's documented recovery window.
Refs: PROJ-123
```