Contributing

Get in Touch

Picking Up Issues

Before starting work on an issue:

  1. Check for existing PRs. Search the open pull requests to make sure nobody is already working on it.
  2. Claim the issue. Leave a comment on the issue (e.g., "I'd like to work on this") and wait for a maintainer to acknowledge before writing code.
  3. One at a time for new contributors. If you haven't had a PR merged into iceberg-go yet, please work on one issue at a time. Get it reviewed, address feedback, get it merged — then pick up the next one. This helps us give your work the attention it deserves and avoids wasted effort from overlapping contributions.

If two PRs land for the same issue, we will generally keep the one from the contributor who claimed it first.

Submitting a Pull Request

  • Reference the issue number in your PR description (e.g., "Fixes #123").
  • Keep PRs focused — one issue per PR.
  • Run make test and make lint before pushing. CI runs all of these too, but catching issues locally saves a round-trip. make lint-install will install the linter if you don't have it yet.
  • All commits must have a Signed-off-by line (DCO).
  • CI checks the exported API against the base branch with apidiff. If your PR changes it incompatibly on purpose, mark the PR title as breaking with a !, for example refactor(io)!: add context to IO.Open. You can run the same check locally with dev/check-api-compat.sh after installing the apidiff version it names.

Code Review

  • Maintainers may request changes. This is normal — it doesn't mean the PR is bad, it means we want to get it right.
  • Respond to review comments by pushing new commits (don't force-push over reviewed code).
  • If your PR has been waiting for review for more than a few days, ping on Slack.

Development Setup

git clone https://github.com/apache/iceberg-go.git
cd iceberg-go
go build ./...
make test # runs all unit tests
make test-race # runs all unit tests with race detector

Integration Tests

Integration tests require Docker and are gated behind a build tag:

docker compose -f internal/recipe/docker-compose.yml up -d rest object-store create-bucket --wait
go test -tags integration ./...

External REST Catalog Conformance

TestExternalRestCatalogConformance runs the catalog conformance suite against any REST catalog server. It is skipped unless REST_CATALOG_URI is set. CI runs it against Apache Polaris; to do the same locally (requires jq):

make integration-setup-polaris
make integration-external-rest

To test another catalog, override the Polaris defaults with REST_CATALOG_URI, REST_CATALOG_CREDENTIAL (client_id:client_secret), REST_CATALOG_SCOPE and REST_CATALOG_WAREHOUSE. Set any of them to an empty value to leave it unset, for example:

REST_CATALOG_URI=http://localhost:8181 REST_CATALOG_CREDENTIAL= REST_CATALOG_SCOPE= REST_CATALOG_WAREHOUSE= \
  make integration-external-rest