48 lines
2.6 KiB
Markdown
48 lines
2.6 KiB
Markdown
|
|
# Contributing
|
||
|
|
|
||
|
|
How change lands in this repo. The short version: PRs are born as drafts,
|
||
|
|
three reviewer bots take the first rounds, a human takes the last word — and
|
||
|
|
labels tell you where everything is without opening anything.
|
||
|
|
|
||
|
|
## The PR loop
|
||
|
|
|
||
|
|
1. **Fork and branch.** Contributors work from forks; upstream branches are
|
||
|
|
for maintainers. Title the PR conventionally (`feat:`, `fix:`, `docs:`),
|
||
|
|
and include a `CHANGELOG.md` entry under `## Unreleased` when the change
|
||
|
|
deserves one.
|
||
|
|
2. **Open as a draft** while you build. Drafts are invisible to the reviewer
|
||
|
|
bots on purpose.
|
||
|
|
3. **When it's ready**: mark ready-for-review and request all three bots —
|
||
|
|
`claude-bot-andresmgsl`, `codex-bot-andresmgsl`, `grok-bot-andresmgsl`.
|
||
|
|
They poll roughly every 15 minutes.
|
||
|
|
4. **Rounds are answered whole.** Wait until all three have reviewed, then
|
||
|
|
answer the entire round in a **single reply**, push the fixes, and
|
||
|
|
re-request the bots that didn't approve. Prefer verification over
|
||
|
|
argument: a test settles what a comment thread can't.
|
||
|
|
5. **When all three approve**, the final review goes to the maintainer — the
|
||
|
|
labels workflow requests it automatically.
|
||
|
|
6. **Checks must be green**: `shellcheck` and `bash test/cli.sh` locally
|
||
|
|
mirror what CI runs; the multi-user rehearsal runs in CI on a real Incus.
|
||
|
|
|
||
|
|
## Labels — who sets what
|
||
|
|
|
||
|
|
The full taxonomy lives in [LABELS.md](LABELS.md). What matters day to day is
|
||
|
|
who sets each kind — most of it is machinery, and hand-moving a
|
||
|
|
machine-owned label just gets corrected on the next pass:
|
||
|
|
|
||
|
|
| Labels | Set by |
|
||
|
|
|---|---|
|
||
|
|
| `state:*` | the labels workflow ([.github/workflows/labels.yml](.github/workflows/labels.yml)) — recomputed from GitHub's own facts every 15 minutes and on PR events. Never by hand. |
|
||
|
|
| `stale` | the same workflow — 48h without commits, comments, or reviews. `blocked` PRs are exempt: they are quiet legitimately. |
|
||
|
|
| `scope:*` on PRs | actions/labeler, from the changed paths ([.github/labeler.yml](.github/labeler.yml)). Additive — you may add more, the machine won't remove them. |
|
||
|
|
| `scope:*` on issues | you, when opening or triaging — issues have no paths to derive from. |
|
||
|
|
| `blocked`, `release` | you — automation never guesses intent. |
|
||
|
|
| `bug` / `enhancement` / `documentation` | you, on issues only — a PR's type already lives in its title. |
|
||
|
|
|
||
|
|
## Issues
|
||
|
|
|
||
|
|
Give issues the same care as PR titles: say the surface in the title, apply a
|
||
|
|
`scope:` label and a type label (`bug` / `enhancement` / `documentation`) when
|
||
|
|
you open one, and `blocked` when it waits on something — that is what keeps
|
||
|
|
the board navigable as the issue count grows.
|