Every new PR that introduces new functionality must link to an approved issue. PRs without one may be closed at maintainer's discretion.
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.
You are responsible for the code you submit, even if a tool wrote it.
Using an AI assistant to help you code is fine. Submitting code you don‘t understand is not. Before you open a PR you must be able to explain what every part of the change does and why, answer review questions about it yourself, and defend the design without going back to the tool for an answer. If you can’t, the PR isn't ready.
While you‘re new to the project, please keep to one open PR at a time. Review takes longer than writing, so a queue of changes from one contributor holds up everyone else’s.
Maintainers may close a PR at first review if it reads as a relay between the reviewer and a model, rather than a change the author understands and takes responsibility for. That is a judgment about the submission, not about you, and it does not bar you from contributing again if you come back with a change you can take responsibility for.
Maintainers will not start reviewing a PR while its CI is failing. Get the pipeline green first - a red build, lint, or test means the PR is not ready for review.
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 HawkEye:
cargo install hawkeye --version "$(cat .github/config/hawkeye.version)" --locked ./scripts/ci/license-headers.sh --check ./scripts/ci/license-headers.sh --fix
We use prek:
cargo install prek
prek install
The hooks require bash >= 4.2 and refuse to run on anything older. Every current Linux distribution already satisfies this.
macOS ships bash 3.2 and never updates it, so this is the one platform that needs a step:
brew install bash
Homebrew's bash has to precede /bin on PATH, which is the default for a Homebrew install but not guaranteed. Check with:
bash --version
Git GUIs launched from the Dock get a minimal PATH where /bin wins, so the hook can still find bash 3.2 after the install. Committing from a terminal avoids this.
// 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.
Move a PR around the review queue by posting a slash command on its own line in a regular PR comment (not an inline review reply):
| Command | Who | Effect |
|---|---|---|
/ready | author or maintainer | mark S-waiting-on-review |
/author | maintainer or returning contributor | mark S-waiting-on-author |
/request-review @user-or-team ... | author or maintainer | request review from the listed @user / @org/team handles |
/pin | author or maintainer | add pinned, exempting the PR from the stale bot |
/unpin | author or maintainer | remove pinned |
Some labels move on their own: opening or marking a non-draft PR ready sets S-waiting-on-review; a “Request changes” review sets S-waiting-on-author; closing or converting to draft clears both.
Commands take up to ~90s. A 👍 reaction means applied, 😕 means you lacked permission; if neither shows up, check the PR Triage Apply run in the Actions tab.
PRs may be closed if:
Whoever closes leaves a comment saying why. If the thread holds a finding that outlives the change, open an issue for it and link it from that comment. The closed thread is the first place someone looks to find out whether anything fell through.
A bot labels a PR S-stale after 7 days without activity and closes it 7 days after that. A push, comment, review, reopen, or ready-for-review clears the label. Drafts and PRs labeled pinned are exempt. Issues are never labeled or closed by it. A closed PR can be reopened.
Discussions, Discord or the dev@iggy.apache.org mailing list (subscribe by emailing dev-subscribe@iggy.apache.org)
GitHub Discussions are mirrored to dev@. The mirror only runs one way: replies sent to the list do not appear in Discussions.