Skip to content

Contributing

Alexander Birkner edited this page Aug 31, 2026 · 2 revisions

Contributing

Dev container (recommended)

Open the repo in VS Code and "Reopen in Container", or run devcontainer up --workspace-folder ..

The devcontainer (.devcontainer/) gives you a Rust toolchain plus sibling postgres and seaweedfs services — the same shape as a real deployment — with the bucket already created. Ports are auto-forwarded to the host:

port service
8080 silo (gRPC + HTTP)
5432 postgres
8333 seaweedfs S3 API
8888 seaweedfs filer web UI (browse the bucket under /buckets/silo)

remoteEnv sets SILO_TEST_DATABASE_URL, SILO_SERVER, and SILO_CLIENT_CONFIG for every terminal the editor opens, so integration tests run against the sibling Postgres rather than skipping.

The container's postCreateCommand (.devcontainer/setup.sh) installs protoc and jq, adds the rustfmt/clippy components, warms the build cache, and writes a ready-to-use .devcontainer/config.yaml (gitignored) pointed at the sibling services. The cargo registry and target/ live in named volumes, so a container rebuild isn't a cold build.

Getting started

Everything below works on first open:

cargo test --workspace --features silo-core/test-util,silo-pkg/test-util
cargo clippy --workspace --all-targets --features silo-core/test-util,silo-pkg/test-util -- -D warnings

# Run the server. The bootstrap admin password prints once, in the server log,
# on first start against an empty database.
SILO_CONFIG=.devcontainer/config.yaml cargo run -p silo-server

In another terminal:

cargo run -p silo-cli -- login --username admin
cargo run -p silo-cli -- version

Without a dev container

cargo test --workspace --features silo-core/test-util,silo-pkg/test-util
cargo clippy --workspace --all-targets --features silo-core/test-util,silo-pkg/test-util -- -D warnings
cargo fmt --all

Database-backed integration tests skip rather than fail when no database is configured, so the suite runs on any machine — but that silently drops most of the coverage on a real check. Start one and point the tests at it:

docker run -d --name silo-test-pg -p 55432:5432 \
  -e POSTGRES_USER=silo -e POSTGRES_PASSWORD=silo -e POSTGRES_DB=silo \
  postgres:16-alpine
export SILO_TEST_DATABASE_URL=postgres://silo:silo@localhost:55432/silo

Queries are runtime-checked rather than sqlx::query!-checked, so cargo build needs neither a live database nor a checked-in offline cache.

The Helm chart has its own checks, needing helm and pyyaml:

helm lint charts/silo
ci/check-chart.py

End-to-end suite

ci/e2e.sh            # ~5 minutes; needs docker
KEEP=1 ci/e2e.sh      # leave the stack up afterwards

This is the only suite that tests silo against software it doesn't control. It builds a package per format with that ecosystem's own tooling (rpmbuild, abuild, npm pack, makepkg, dpkg-deb), publishes all five to a real silo backed by a real Postgres and a real SeaweedFS, and installs them with real dnf, apk, npm, pacman and apt in their own distro containers, with signing on throughout. Anything touching the HTTP surface, the index formats, or signing needs this run, not just cargo test.

Checks before pushing

CI runs five jobs — lint, proto, test, helm, e2e — all runnable locally:

cargo fmt --all -- --check
cargo clippy --workspace --all-targets \
    --features silo-core/test-util,silo-pkg/test-util -- -D warnings
cargo machete --with-metadata
shellcheck ci/*.sh ci/e2e/*.sh .devcontainer/*.sh
SILO_TEST_DATABASE_URL=postgres://silo:silo@localhost:55432/silo \
    cargo test --workspace --features silo-core/test-util,silo-pkg/test-util
ci/check-chart.py
ci/e2e.sh

CI's clippy tracks the current stable release, which is usually ahead of a local toolchain; rustup run stable cargo clippy ... matches it.

Commit conventions

Conventional Commits, since release-please derives the version and changelog from them: fix: patch, feat: minor, feat!: or BREAKING CHANGE major. Use chore:, ci: or test: for work that changes nothing an operator would notice.

Documentation describes the present

The README, doc comments, config comments, and this wiki describe what silo does now — not what it used to do or what changed. That narrative belongs in commit messages, changelog entries, and pull request descriptions. Avoid "MVP", "previously", "used to", "legacy", "deprecated", or "we now ..." when describing silo's own design (these are fine describing something external and still true — npm's legacy clients, rpm's deprecated signature tags).

The version lives in one number

[workspace.package] version in the root Cargo.toml is silo's version. Member crates inherit it, silo-core re-exports it as silo_core::VERSION, and the chart's version/appVersion carry the same number. Nothing bumps any of it by hand — release-please rewrites the workspace version, the Cargo.lock entries, and the chart fields together, driven by Conventional Commits. ci/check-chart.py fails if they drift apart.

Clone this wiki locally