diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e86ae434..fd779c98 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,3 +1,4 @@ +default_install_hook_types: [pre-commit, commit-msg] repos: - repo: https://github.com/AleksaC/hadolint-py rev: v2.14.0 @@ -12,3 +13,8 @@ repos: language: system entry: scripts/run-super-linter-pre-commit.sh pass_filenames: true + - id: commitlint + name: commitlint + language: system + entry: env npm_config_ignore_scripts=true npx --yes --package @commitlint/cli@21.2.2 --package @commitlint/config-conventional@21.2.2 commitlint --edit + stages: [commit-msg] diff --git a/AGENTS.md b/AGENTS.md index cbc33ff7..97dca334 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -51,7 +51,7 @@ Do not implement on `main` (or `master`). Before the first file change, create o When the work is ready, **recommend one Conventional Commit** (subject + short body) and stop. Do not `git add` or `git commit` unless the user asks. Default is **one commit for the whole change**; split only if they ask. -[Conventional Commits](https://www.conventionalcommits.org/). CI lints the PR title **and** every commit (`@commitlint/config-conventional`). Use `feat` / `fix` for version bumps. `chore`, `docs`, `ci`, and similar are patch when a release runs. +[Conventional Commits](https://www.conventionalcommits.org/). A local `commit-msg` hook lints the message at commit time; CI still lints every PR commit and the PR title (`@commitlint/config-conventional`). Use `feat` / `fix` for version bumps. `chore`, `docs`, `ci`, and similar are patch when a release runs. Do **not** use a `BREAKING CHANGE` footer or `feat!:` / `fix!:` on `0.x` unless the user explicitly wants **1.0.0**. That rewrite changes the public API prefix from `/tagbase/api/v0` to `/tagbase/api/v1`. Operator-facing breaks (ports, env) go in the commit **body**, not the footer. diff --git a/wiki/Release-Management.md b/wiki/Release-Management.md index c238a38c..1915a97d 100644 --- a/wiki/Release-Management.md +++ b/wiki/Release-Management.md @@ -90,12 +90,20 @@ Renovate titles such as `chore(deps): …` are patches when a release actually r ## Pull request lint (commitlint) +Local gate: [`.pre-commit-config.yaml`](https://github.com/tagbase/tagbase-server/blob/main/.pre-commit-config.yaml) installs a `commit-msg` hook (`default_install_hook_types` includes `pre-commit` and `commit-msg`). On commit it runs the same pins as CI, with `npm_config_ignore_scripts=true`, and reads the message through `commitlint --edit` and [`commitlint.config.cjs`](https://github.com/tagbase/tagbase-server/blob/main/commitlint.config.cjs). + +```bash +pre-commit install --hook-type pre-commit --hook-type commit-msg +``` + +That hook checks the message being committed. PR title lint stays in CI. + [`.github/workflows/commitlint.yml`](https://github.com/tagbase/tagbase-server/blob/main/.github/workflows/commitlint.yml) runs on `opened` / `synchronize` / `reopened` / `edited`. It fails if: - any commit from the PR base SHA to the head SHA is not Conventional, or - the **PR title** is not Conventional (`@commitlint/config-conventional`). -Pinned in the workflow via `npx` (no root `package.json`): `@commitlint/cli@21.2.2` and `@commitlint/config-conventional@21.2.2`. Config: [`commitlint.config.cjs`](https://github.com/tagbase/tagbase-server/blob/main/commitlint.config.cjs). There is no Husky hook; CI is the gate. +Pinned in the workflow via `npx` (no root `package.json`): `@commitlint/cli@21.2.2` and `@commitlint/config-conventional@21.2.2`. Config: [`commitlint.config.cjs`](https://github.com/tagbase/tagbase-server/blob/main/commitlint.config.cjs). Agents: see [AGENTS.md](https://github.com/tagbase/tagbase-server/blob/main/AGENTS.md) Commits. Do not commit unless the user asks. @@ -105,6 +113,7 @@ Agents: see [AGENTS.md](https://github.com/tagbase/tagbase-server/blob/main/AGEN .github/workflows/semantic-release.yml # cron + dispatch; Node 24; npx semantic-release .github/workflows/publish-ghcr.yml # GitHub Release published (+ dispatch): bake GHCR + compose publish .github/workflows/commitlint.yml # PR title + commits +.pre-commit-config.yaml # local commit-msg hook (same pins) .releaserc.json # plugins, releaseRules, git assets, tagFormat scripts/semantic-release-fortnight-gate.sh scripts/semantic-release-auth-preflight.sh # RELEASE_TOKEN must be a human PAT