Contributing
Workflow, conventions, and code style for working on dbsync.
Branching and PRs
- Branch off
main. PRs targetmain. - Keep PRs focused. A new extractor is one PR; a refactor of the Follow loop is another.
- Use the commit history to tell a coherent story. Squash noisy WIP commits before opening the PR; keep the meaningful ones.
- The PR description should call out anything an operator would care about — schema changes, config-shape changes, performance changes — even if the code change is small.
Code comments
Comments should give the next developer a brief understanding of what a function or module does. They're not:
- A history of how the code got here. The repo is greenfield and pre-release; there's no backwards-compatibility story worth narrating.
- A full explanation of every detail. If a comment is becoming convoluted, the code probably needs a clearer name or a smaller function.
- Cross-references to plans, design docs, or prior iterations.
Formatting and linting
The repo doesn't enforce a specific formatter via CI — running
fourmolu or hlint is a developer-side convenience, not a
requirement. Match the surrounding file's style; the per-module
defaults (NoImplicitPrelude, OverloadedStrings,
DerivingStrategies, GeneralizedNewtypeDeriving, LambdaCase)
are declared once in each cabal file's common defaults.
-Werror is onThe GHC warnings listed in the common warnings block of each
.cabal file are enforced as errors. -Wall, -Wcompat,
-Wincomplete-record-updates, -Wincomplete-uni-patterns,
-Wmissing-deriving-strategies, -Wpartial-fields,
-Wunused-packages, etc. A PR that adds warnings won't compile.
For local iteration where you want to ignore them temporarily, see
the -Wwarn override in
Building from source.
Adding a new module
- Create the file under the right directory in
dbsync/src/,dbsync-db/src/, ortests/lib/. - Add the module name to the
exposed-moduleslist in the matching.cabalfile. Tests go underother-modulesintests/dbsync-tests.cabal. - If the module needs a new dependency, add it to the same
.cabalfile'sbuild-depends. The-Wunused-packageswarning will catch unused entries on rebuild. - For test modules, register the spec in
tests/main/Main.hsunder the appropriate tierdescribeblock.
Adding a dependency
- Internal: just import it. The two internal libraries (
dbsync-db,dbsync-testlib) are wired throughbuild-depends. - External: add it to the relevant
.cabaland runcabal build. Use the version constraints already in place where possible; CHaP pins (cardano-* packages) and Hackage pins (everything else) are resolved throughcabal.project'sindex-staterather than individual upper bounds. - New transitive bounds: if you hit a version conflict, prefer
bumping the index state in
cabal.projectover adding anallow-newerclause.
Repository layout reminder
.
├── dbsync/ # the sync engine
├── dbsync-db/ # schema layer
├── dbsync-smash/ # SMASH server (stub)
├── tests/ # tests + dbsync-testlib + dbsync-mock
├── config-examples/ # shipped config JSON (presets + pg-config example)
├── scripts/ # operator scripts
├── docs/ # this documentation site
└── cabal.project # workspace + CHaP pin
See Repository layout for the per-directory breakdown.
Running the test suite locally
Before opening a PR:
cabal build all
cabal test all
PG-touching tests need PostgreSQL ≥ 16 running locally with the
current user holding CREATEDB. See Testing for tier
selection.
Releases
Pre-release; no formal release process yet. A release that changes the
schema carries a migration: bump currentSchemaVersion, generate the
migration file with gen-migration, and let the pin test, boot gate,
and ladder test enforce the rest. See
Schema versioning and migrations.