blob: bf1928937422171fc1345a9d5ecd15cef3035166 [file] [view]
# Contributing to Apache Iggy
## Issue First
Every new PR that introduces new functionality must link to an approved issue.
PRs without one may be closed at maintainer's discretion.
1. Create an issue or comment under existing
2. Wait for maintainer approval (`good-first-issue` label or comment)
- Maintainer may request for more details or a different approach
3. Then code
## Size Limits
For new contributors we require to keep PRs under 500 lines of code, unless explicitly approved by a maintainer under linked issue.
## High-Risk Areas
These require design discussion in the issue before coding:
- Persistence (segments, indexes, state, crash recovery)
- Protocol (binary format, wire encoding)
- Concurrency (shards, inter-shard)
- Public API (HTTP, SDKs, CLI)
- Connectors
## PR Requirements
### Run It Locally
**If you can't run it, you can't submit it.**
Authors of PRs must run the code locally. "Relying on CI" is not acceptable.
### Single Purpose
One PR = one thing. Bug fix, refactor, feature - separate PRs. Mixed PRs will be closed.
### Quality Checks
For Rust code:
```bash
cargo fmt --all
cargo clippy --all-targets --all-features -- -D warnings
cargo build
cargo test
cargo machete
cargo sort --workspace
```
For other languages, check the README in `foreign/{language}/` (e.g., `foreign/go/`, `foreign/java/`).
### Typos Checks
We use [typos](https://github.com/crate-ci/typos):
```bash
cargo install typos-cli --locked
typos
typos --write-changes
```
If it's indeed not a typo, you can set an exception in `.typos.toml`.
### Pre-commit Hooks
We use [prek](https://github.com/j178/prek):
```bash
cargo install prek
prek install
```
## Code Style
### Comments: WHY, Not WHAT
```rust
// Bad: Increment counter
counter += 1;
// Good: Offset by 1 because segment IDs are 1-indexed in the wire protocol
counter += 1;
```
Don't comment obvious code. Do explain non-obvious decisions, invariants, and constraints.
### Commit Messages
Format: `type(scope): subject`
**Good examples from this repo:**
```none
fix(server): prevent panic when segment rotates during async persistence
fix(server): chunk vectored writes to avoid exceeding IOV_MAX limit
feat(server): add SegmentedSlab collection
refactor(server): consolidate permissions into metadata crate
chore(integration): remove streaming tests superseded by API-level coverage
```
Keep subject under 72 chars. Use body for details if needed.
## PR Triage Commands
You can move a PR around the review queue by posting a slash command in the
PR conversation. The pattern is similar to `rust-lang/triagebot`. The
machinery lives in
[`./.github/workflows/pr-triage-apply.yml`](./.github/workflows/pr-triage-apply.yml)
(with a read-only collector in
[`./.github/workflows/pr-triage-collect.yml`](./.github/workflows/pr-triage-collect.yml)
that hops the token-permission gap for fork PRs) if you want to peek.
### Commands
| Command | Who can use it | What it does |
| --- | --- | --- |
| `/request-review @user-or-team ...` | the PR author or a maintainer | Requests review from one or more `@user` or `@org/team` handles |
| `/ready` | the PR author or a maintainer | Marks the PR `S-waiting-on-review` |
| `/author` | a maintainer, or any returning contributor (>=1 merged PR) | Marks the PR `S-waiting-on-author` |
A "maintainer" here means someone with write access to apache/iggy
(in practice, the `@apache/iggy-committers` team). Automated comments from
bots like Dependabot do not run commands.
Each command has to start its own line. Leading whitespace is fine, but
prose like `please /ready` will not match. You can put more than one command
in a single comment: `/request-review` plus `/ready`, or `/request-review`
plus `/author`. `/request-review` may carry several handles on one line and
may also repeat across lines; all of them are collected and requested
together. For `/ready` and `/author`, the last one wins, so `/ready` then
`/author` in the same comment ends up as `S-waiting-on-author`.
### Typical flow
1. You open a PR. CODEOWNERS pings `@apache/iggy-committers` automatically.
2. A maintainer reviews. Submitting a "Request changes" review moves the
PR to your queue automatically; they can also comment `/author`.
3. You push fixes, then comment `/ready`. The PR moves back to the review
queue.
4. Either side can comment `/request-review @somebody` to pull in a
specific person or team.
To find PRs waiting on review, filter with
`is:open is:pr label:S-waiting-on-review` on the Pulls tab.
### Lifecycle automation
Some labels are managed for you based on what happens to the PR:
| When | What happens |
| --- | --- |
| You open a PR (not a draft) | Gets `S-waiting-on-review`, unless an `S-*` label is already set |
| You mark a draft "Ready for review" | Gets `S-waiting-on-review`, unless an `S-*` label is already set |
| You convert the PR back to a draft | Both `S-*` labels are removed |
| The PR is closed or merged | Both `S-*` labels are removed |
Reopening a PR does not re-label it. Drop a `/ready` or `/author` comment
to put it back in a queue.
Drafts are skipped by the automatic labelling, but `/ready` and `/author`
still work on drafts if you want to signal intent before clicking "Ready
for review".
### Review state
Submitting a review with "Request changes" is treated as an implicit
`/author`: the PR moves to `S-waiting-on-author`. Anyone GitHub recognizes
as a repo contributor or above can trigger this - the same set that can
issue an explicit `/author`. If your review body also contains an explicit
`/ready` or `/author`, that command wins.
### Tips
- **One comment per command burst.** To request several reviewers at once,
list them on a single `/request-review` line (or several lines) in one
comment. Posting separate comments back-to-back can lose the middle one
due to how CI runs are scheduled.
- **Edits don't re-trigger.** If you typo a command and edit the comment, it
will not run. Post a new comment instead.
- **Use the main conversation, not inline review replies.** Commands posted
as replies on a specific line of the diff are ignored. Post them in the
PR's main comment thread.
- **Suffixes don't match.** `/ready-to-merge` or `/readyish` will not flip
state - only `/ready` followed by a space or end-of-line counts.
### When something goes wrong
Commands take up to ~90s to apply: the read-only collector hands the
event off to the write-capable apply workflow via an artifact, which
adds latency on top of GitHub Actions scheduling. Wait for a reaction
before re-issuing - duplicate commands can interleave.
The workflow reacts on your comment so you get quick feedback: a 👍 means
a command was applied, a 😕 means a command was recognized but you lacked
permission to run it. A failed `/request-review` also posts a one-line
reply naming the handles GitHub rejected. Commands posted in a review body
(rather than a normal comment) cannot be reacted to, so they stay
log-only.
If no reaction appears within a couple of minutes, the apply run likely
failed. Open the repo's "Actions" tab and look at the `PR Triage Apply`
run for the comment you posted - the run log says exactly what it saw
and why (no permission, unknown user, transient API error, etc.). The
`PR Triage Collect` run that appears on the PR's "Checks" tab is just
the read-only event collector; the actual labelling happens in
`PR Triage Apply`, which is triggered via `workflow_run` and is not
attached to the PR's checks.
### Examples
Mark your PR ready after addressing feedback:
```text
/ready
```
Ask the author to take another look:
```text
/author
```
Request a specific reviewer and mark ready in one comment:
```text
/request-review @somebody
/ready
```
Request several reviewers in one go (do this instead of posting separate
comments). They can share one line, span multiple lines, or both:
```text
/request-review @alice @bob @apache/iggy-committers
```
## Close Policy
PRs may be closed if:
- Maintainer feels like proxy between maintainer and LLM
- No approved issue or no approval from a maintainer
- Code not ran and tested locally
- Mixed purposes or purposes not clear
- Can't answer questions about the change
- Inactivity for longer than 7 days
## Questions?
[Discussions](https://github.com/apache/iggy/discussions) or [Discord](https://discord.gg/apache-iggy)