docs(contributing): add PR description template and convention #123

Merged
rootiest merged 4 commits from docs/pr-template into main 2026-09-01 02:42:38 +00:00
2 changed files with 157 additions and 0 deletions
+109
View File
@@ -0,0 +1,109 @@
<!--
PR title: Conventional Commits — type(scope): description
e.g. fix(mv): bring header and completions up to repo conventions
Lowercase after the colon, imperative mood, no trailing period.
Append `!` after the scope for a breaking change: feat(logging)!: ...
Types in use: feat, fix, docs, test, chore, perf, refactor, style.
See CONTRIBUTING.md § Commit Conventions.
Still writing code? Prefix the title with `WIP:` —
WIP: feat(media): add play-media fzf picker
Gitea recognizes the prefix, marks the PR a draft, and blocks merging
until you remove it. The prefix goes before the whole conventional
subject, and comes off when the branch is complete.
`WIP:` means MORE CHANGES ARE COMING. It is not for a finished branch
waiting on verification — that is what an unchecked box in Verification
already signals. A complete branch with open checkboxes is a normal PR,
not a WIP.
Keep the two headings below, in this order, and delete these comments.
Optional sections may be added between them (see the note above
"Verification").
-->
## Summary
<!--
What changed and why. A short prose paragraph, 2-5 bullets, or a
paragraph followed by bullets — whichever fits the change.
- Name concrete paths and identifiers in backticks (`functions/mv.fish`,
`$__fish_config_op_autoexec`), not vague descriptions.
- Lead a bullet with a **bold phrase** when it covers a distinct file or
behavior, so the list scans at a glance.
- Explain the reasoning, not just the diff — a reader should understand
why this approach over the obvious alternative.
- Say so explicitly when there is no behavioral change, when a file is
generated by the docs pipeline, or when the change is scoped to the
site build only.
If this PR resolves a tracked issue, close it with a trailing line at the
end of this section — not at the very bottom, since Verification is
always last:
Closes #42
Gitea and GitHub both auto-close the issue on merge. `Fixes #N` and
`Resolves #N` work identically; pick whichever reads correctly. Use one
line per issue (`Closes #42, closes #43` — the keyword must be repeated,
a bare `#43` after a comma is only a link and will NOT close). For an
issue that is related but should stay open, reference it without a
keyword: `Refs #42`. Omit all of this entirely when no issue is involved
— do not leave an empty `Closes #` behind.
-->
<!--
OPTIONAL SECTIONS — add any `##` heading here that the change actually
needs, and skip them entirely for a straightforward one. Used in this
repo, roughly in order of frequency:
## Root cause — for a bug fix, what was actually wrong
## Why — motivation, when it isn't obvious
## How it works — mechanism, for a non-trivial new feature
## Behavior — user-visible behavior before/after
## Changes — a longer breakdown than Summary can carry
## Docs — documentation touched by this change
## Notes — caveats, follow-ups, deferred work
## Scope note — what this deliberately does NOT cover
## Opinionated guard (C1-C6)
— which tier gates this, and behavior when off
## ⚠️ Breaking Change — required whenever the title carries `!`;
state the break and the migration path
A "Why not <alternative>?" heading is also common when a reviewer would
reasonably ask why the obvious approach was rejected.
-->
## Verification
<!--
Every check this change needs, as a checkbox list. Always the last
section.
A CHECKED box means verified — either it ran programmatically (test
suite, linter, docs verifier, CI) or the author performed it by hand and
confirmed the result. Check these off before opening the PR.
An UNCHECKED box is an outstanding manual check the reviewer still has to
perform. Leave anything you could not verify yourself unchecked rather
than dropping it, so it stays visible.
**This list is the merge gate: the PR does not merge until every box is
checked.** So only put things here that can actually be resolved — a
check nobody is able to run blocks the PR forever. Genuinely unverifiable
caveats, assumptions, and known limitations belong in a `## Notes`
section instead, where they inform the review without gating it.
- One check per line, imperative, with the exact command in backticks
and the expected result stated.
- Cover the regression path, not just the happy path: the old behavior
still working, the opinionated toggle disabled, the error branch.
- Include the repo's standing gates when the change touches what they
guard: `fish -n <file>`, `fish_indent`, `python3 docs/verify-manual.py`,
`python3 docs/build-manual.py --site`, `fish tests/run-tests.fish`.
- Reset any universal variable you set during a check.
-->
- [ ]
- [ ]
+48
View File
@@ -48,6 +48,19 @@ assumes you *do* have push access (maintainers, regular contributors).
branching doesn't touch the working tree.)
- **Merge target is `main`, via PR.** Contributors open the PR; the repo
owner merges it. Don't merge your own PR.
- **Don't merge until the `## Verification` checklist is fully checked.**
Unchecked boxes are outstanding manual checks, not decoration. See
[Pull request descriptions](#pull-request-descriptions) below.
- **Prefix in-progress PRs with `WIP:`.** If the branch still has code
changes coming, open it as `WIP: type(scope): description`. Gitea
recognizes the prefix, flags the PR as a draft, and refuses to merge it
until the prefix is removed; drop it once the branch is complete.
`WIP:` signals **more changes are coming** — not "done but unverified".
A finished branch waiting on manual checks is an ordinary PR whose
`## Verification` boxes aren't all ticked yet; that's already the merge
gate above and doesn't need the prefix. The two are independent: a PR
can be WIP with everything ticked, or complete with checks outstanding.
- **Keep feature branches focused.** If you stumble onto something unrelated
to your current task while working (a pre-existing bug, a stray cleanup),
don't fold it into the same commit or PR. Handle it with one of these,
@@ -64,6 +77,41 @@ assumes you *do* have push access (maintainers, regular contributors).
approval before doing this** — there's no standing exception, no matter
how trivial the change looks.
### Pull request descriptions
Fill in `.github/PULL_REQUEST_TEMPLATE.md` — Gitea pre-loads it into the
description box when you open a PR. Every PR carries, in this order:
- **`## Summary`** — what changed and why, as a short paragraph, 2-5
bullets, or both. Name concrete paths and identifiers in backticks, and
explain the reasoning rather than restating the diff.
- **Optional `##` sections** — add what the change actually needs
(`Root cause`, `Why`, `How it works`, `Behavior`, `Docs`, `Notes`,
`Scope note`, `Opinionated guard (C1-C6)`), and skip them entirely for a
straightforward change. A breaking change (title ending in `!` before
the colon) must include `## ⚠️ Breaking Change` with the migration path.
- **`## Verification`** — always last. Every check this change needs, as a
checkbox list, each with the exact command and its expected result.
A **checked** box means verified, whether programmatically (test suite,
linter, docs verifier, CI) or by hand; check those off before opening the
PR. An **unchecked** box is an outstanding manual check the reviewer
still has to perform — leave anything you couldn't verify yourself
unchecked rather than dropping it.
**This list is the merge gate: a PR isn't merged until every box is
checked.** Only list checks that can actually be resolved — one nobody
can run blocks the PR indefinitely. Put genuinely unverifiable caveats,
assumptions, and known limitations in `## Notes` instead, where they
inform the review without gating it.
When a PR resolves a tracked issue, close it with a trailing `Closes #42`
line at the end of `## Summary` — not at the very bottom of the body, since
`## Verification` is always last. `Fixes #N` and `Resolves #N` behave
identically. Repeat the keyword for each issue (`Closes #42, closes #43`); a
bare `#43` is only a link and won't close anything. To point at a related
issue that should stay open, drop the keyword and use `Refs #42`. Leave the
line out entirely when no issue is involved.
## Commit Conventions
Commit subjects follow [Conventional Commits](https://www.conventionalcommits.org/):