diff --git a/.gitea/pull_request_template.md b/.gitea/pull_request_template.md new file mode 100644 index 0000000..85df9db --- /dev/null +++ b/.gitea/pull_request_template.md @@ -0,0 +1,30 @@ + + +## Summary + +## Motivation + +## Implementation notes + +## Verification + +- [ ] `pnpm ci:check` green locally +- [ ] `pnpm ci:audit` green (or pre-existing drift acknowledged) +- [ ] Tested manually: +- [ ] Architecture diagram updated (if `docs/architecture.md` was affected) +- [ ] ADR amended or added (if a decision changed) + +## Related diff --git a/docs/development.md b/docs/development.md index 5d4ee93..6817bb7 100644 --- a/docs/development.md +++ b/docs/development.md @@ -249,6 +249,51 @@ pnpm ci:perf # production build + Lighthouse CI against the static-served 5. To cut a release: tag `vX.Y.Z` on `main`. The `release.yml` workflow will pick it up (currently a stub; populated alongside the on-prem deploy ADR). +### PR conventions + +The squash-merge subject on `main` is the **PR title**, not the individual commits on the feature branch (those collapse into the squash). Two practical consequences: + +1. **The PR title must itself be a valid Conventional Commits message.** Same format as a commit message — `(): `, imperative mood, lowercase, no trailing period, target ≤ 70 chars. The CI `commits` job (commitlint on the PR commit range) catches violations. +2. **Individual commits on the feature branch can be exploratory.** The local `commit-msg` hook still validates each commit's format, but the squash makes granular history irrelevant on `main`. Granular history stays available in the PR for review. + +#### Type vocabulary + +| Type | When | +| ---------- | ----------------------------------------------- | +| `feat` | new user-facing feature or capability | +| `fix` | bug fix | +| `docs` | documentation only (no code) | +| `style` | formatting / whitespace (no logic change) | +| `refactor` | code change that is neither a fix nor a feature | +| `perf` | performance improvement | +| `test` | tests added or updated | +| `build` | build system, dependencies | +| `ci` | CI configuration | +| `chore` | maintenance, scaffolding, project metadata | +| `revert` | revert a previous commit | + +#### Scope vocabulary (optional) + +| Scope | Examples | +| ------------- | ----------------------------------------------------------- | +| App | `portal-shell`, `portal-bff` | +| Lib | `shared-tokens`, `shared-ui`, `shared-util`, `feature-auth` | +| Cross-cutting | `decisions` (ADR work), `docs`, `ci`, `deps` | + +Scope is optional. Omit when the change spans too many areas to scope cleanly (e.g., a workspace-level rename). + +#### PR body template + +When a PR is opened against `main`, Gitea pre-populates the body from `.gitea/pull_request_template.md`: + +- **Summary** — 1–3 bullets describing what changed. +- **Motivation** — why, with ADR / issue / incident links. +- **Implementation notes** — trade-offs, alternatives considered, follow-ups deferred. +- **Verification** — CI gates checked, manual test description, ADR / diagram update flags. +- **Related** — ADR-XXXX, related PRs, follow-up issues. + +The template guides without enforcing — sections can be left blank when irrelevant. The point is to make "what does the reviewer need to know" explicit, not to add ceremony. + --- ## 6. Where to look