Every new PR that introduces new functionality must link to an approved issue. PRs without one may be closed at maintainer's discretion.
good-first-issue label or comment)For new contributors we require to keep PRs under 500 lines of code, unless explicitly approved by a maintainer under linked issue.
These require design discussion in the issue before coding:
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.
One PR = one thing. Bug fix, refactor, feature - separate PRs. Mixed PRs will be closed.
For Rust code:
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/).
We use typos:
cargo install typos-cli --locked typos typos --write-changes
If it's indeed not a typo, you can set an exception in .typos.toml.
We use prek:
cargo install prek
prek install
// 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.
Format: type(scope): subject
Good examples from this repo:
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.
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 (with a read-only collector in ./.github/workflows/pr-triage-collect.yml that hops the token-permission gap for fork PRs) if you want to peek.
| 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.
@apache/iggy-committers automatically./author./ready. The PR moves back to the review queue./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.
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”.
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.
/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./ready-to-merge or /readyish will not flip state - only /ready followed by a space or end-of-line counts.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.
Mark your PR ready after addressing feedback:
/ready
Ask the author to take another look:
/author
Request a specific reviewer and mark ready in one comment:
/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:
/request-review @alice @bob @apache/iggy-committers
PRs may be closed if: