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:

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:

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:

cargo install prek
prek install

Code Style

Comments: WHY, Not WHAT

// 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:

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 (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.

Commands

CommandWho can use itWhat it does
/request-review @user-or-team ...the PR author or a maintainerRequests review from one or more @user or @org/team handles
/readythe PR author or a maintainerMarks the PR S-waiting-on-review
/authora 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:

WhenWhat 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 draftBoth S-* labels are removed
The PR is closed or mergedBoth 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:

/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

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 or Discord