Open-Source Wikis

/

Neon

/

How to contribute

/

Tooling

neondatabase/neon

Tooling

The build, lint, and CI tooling you'll touch as a contributor.

Build system

  • make at the repo root drives a multi-stage build: vendored Postgres trees → pgxn/neon per Postgres version → Rust workspace via cargo build. See Makefile and the included postgres.mk.
  • PG_INSTALL_CACHED=1 short-circuits the Postgres install step when nothing in vendor/postgres-v* has moved. Use it on every iterative rebuild.
  • BUILD_TYPE=release flips the debug/release toggle; WITH_SANITIZERS=yes adds AddressSanitizer/UndefinedBehaviorSanitizer to the Postgres build.

The Cargo workspace is single-rooted at Cargo.toml and lists every crate by path. [profile.release] keeps debug info on (debug = true) for backtraces; the release-line-debug-* profiles are the ones used by production images.

Cargo plugins you'll need

cargo install cargo-nextest      # unit tests
cargo install cargo-hakari        # workspace_hack manager
cargo install cargo-deny          # licenses + advisory checks
cargo install cargo-flamegraph    # profiling, optional
  • cargo nextest run is preferred over cargo test. CI uses it. See Testing.
  • cargo hakari generate && cargo hakari manage-deps must be re-run whenever you add a workspace dependency. The output edits workspace_hack/.
  • cargo deny check runs dependency policy checks (see deny.toml). It's gated in CI by .github/workflows/cargo-deny.yml. Common fixes are upgrading a transitive dep to a non-yanked version or adding an allowance to deny.toml.

Rust formatting and lint

  • ./scripts/reformat runs rustfmt over the whole tree plus the Python formatters.
  • ./run_clippy.sh runs cargo clippy with the project's strict flags pulled from .neon_clippy_args. CI reproduces this; if your PR is failing the clippy check, run this script first.
  • clippy.toml holds workspace-wide clippy config (cognitive complexity threshold, etc.).

Python tooling

The integration tests use a Poetry-managed venv.

  • ./scripts/pysync — install/refresh the venv from poetry.lock.
  • poetry shell or poetry run … — enter the venv.
  • poetry run ruff format . and poetry run ruff check . — formatter and linter.
  • poetry run mypy . — static types. Must be run from the repo root.

Config: pyproject.toml for ruff and mypy; pytest.ini for pytest defaults.

Pre-commit hook

pre-commit.py runs rustfmt on staged Rust files and the Python lints on staged Python files. Install once with make setup-pre-commit-hook. Skip with git commit --no-verify only when you have a reason.

OpenAPI

Several services ship an OpenAPI spec next to their HTTP code:

  • pageserver/src/http/openapi_spec.yml
  • compute_tools/src/openapi_spec.yml
  • safekeeper/src/http/openapi.yaml
  • storage_controller/src/http.rs (spec file under storage_controller/src/)

make lint-openapi-spec runs the Redocly linter via the build-tools/ Node project. CI does the same. New endpoints should be added to the spec at the same time as the handler.

C build

The C parts (Postgres extension code under pgxn/neon, plus walproposer-lib) are built by Make from pgxn/Makefile. The compilation database trick documented in docs/sourcetree.md lets CLion (or any clangd-based editor) understand the C tree:

make distclean
make -j$(nproc) --print-directory postgres-v17 neon-pg-ext-v17 | poetry run compiledb --verbose --no-build
echo /compile_commands.json >>.git/info/exclude

Docker

compute/compute-node.Dockerfile builds the production compute image. Dockerfile at the root builds a generic image for the storage services. Local development normally doesn't need Docker; tests use bare binaries.

docker-compose/ has a few compose files for common multi-service setups (proxy + postgres + redis, etc.) used by some integration tests.

CI helpers

  • .github/workflows/_*.yml — reusable workflows invoked by the others. Don't add workflow_dispatch triggers to these.
  • .github/workflows/build_and_test.yml — the main entry point.
  • .github/workflows/cargo-deny.yml — dependency policy.
  • .github/workflows/_check-codestyle-rust.yml and _check-codestyle-python.yml — formatter / linter gates.
  • .github/workflows/actionlint.yml — runs actionlint over the workflow YAML files themselves.
  • .github/workflows/build-build-tools-image.yml and pin-build-tools-image.yml — manage the build-tools Docker image used by CI runners.

Several workflows use a custom build-tools Docker image hosted in neondatabase/docker-images. Pinning a new image hash is done via pin-build-tools-image.yml:

gh workflow -R neondatabase/neon run pin-build-tools-image.yml \
  -f from-tag=cc98d9b00d670f182c507ae3783342bd7e64c31e

Local CLIs you'll use

  • cargo neon …neon_local from control_plane/. Local stack management.
  • pagectl … — pageserver offline diagnostic tool from pageserver/ctl/.
  • storcon-cli … — storage controller client from control_plane/storcon_cli/.

Editors

docs/sourcetree.md has detailed notes for CLion (with the Rust plugin and a clangd compilation database). VS Code with rust-analyzer is the most common setup; settings are not checked in. .git-blame-ignore-revs lists commits to skip when running git blame, mostly mass formatting passes.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Tooling – Neon wiki | Factory