Local development
Use this guide to develop Synchro itself. For application integration, start with First synchronization.
Run Make commands from the repository root.
Create ordinary work branches from dev and target their pull requests at dev.
master is the stable default branch, not the target for unfinished development.
The integration setup creates test tables, grants, registrations, and seed data.
Never point it at a production database or a database with application data.
| Work | Prerequisites |
|---|---|
| Server and Go | Go 1.25, Rust 1.92, cargo-pgrx 0.17, PostgreSQL 18, C build tools |
| Swift and iOS | macOS, Xcode, Swift 6, an installed iOS simulator |
| Kotlin and Android | JDK 17, Android SDK, platform tools, the required emulator image |
| React Native | Node 22.20.0, Corepack/Yarn 4.11.0, the platform tools above, CocoaPods for iOS |
| Documentation | Node 22.12 or later in the supported Node 22 line, npm, Python 3 |
Configure pgrx for the PostgreSQL installation you will use.
PGRX_PG_CONFIG must name that installation’s executable pg_config.
The default comes from the pg18 entry in ~/.pgrx/config.toml.
The pgrx configuration and actual binaries must refer to the same PostgreSQL installation.
Android targets use ANDROID_HOME for the SDK and ANDROID_JAVA_HOME for JDK 17.
Set both to your installed tool locations.
Install the SDK platform and build-tools versions declared in the Android Gradle projects.
Start the emulator required by the selected test target.
The CI emulator runner caches its pinned archive at $ANDROID_HOME/.synchro-cache/16428233/emulator.zip.
It verifies the archive size and SHA-256 before each installation.
Remove that cache file if validation reports damaged bytes.
Install the React Native workspace dependencies before bridge checks:
cd clients/react-nativecorepack enablecorepack yarn install --immutablecd ../..Checks without a running server
Section titled “Checks without a running server”Choose the checks relevant to your change:
make test-rust-coremake test-swift-unitmake test-kotlin-unitmake test-rn-unitmake docs-buildRun only platform targets supported by your installed toolchain. These commands do not replace the complete Candidate workflow.
Prepare integration artifacts
Section titled “Prepare integration artifacts”Build fresh immutable artifacts in a clean checkout:
make conformance-adapter-artifactmake conformance-seed-artifactmake conformance-pg18-extension-test-artifactmake conformance-update-baseline-extension-artifactThe extension update tests need the bundles from make conformance-update-baseline-extension-artifact.
Set SYNCHRO_CONFORMANCE_UPDATE_BASELINE_EXTENSION_ARTIFACT to the baseline bundle.
Set SYNCHRO_CONFORMANCE_UPDATE_ORIGIN_EXTENSION_ARTIFACTS to the directory of later released origins.
extensions/synchro-pg/update-origins.json pins each later released origin by version and archive digest.
The artifact targets refuse to replace existing output directories.
After implementation changes, use a fresh worktree and rebuild the artifacts rather than accidentally testing stale output.
The update baseline and origin bundles are pinned published release assets.
The other artifacts are local test inputs, not a published release.
Start a disposable database
Section titled “Start a disposable database”In the first terminal, run:
make local-postgres-runKeep this process running.
It creates an isolated PostgreSQL instance, role credentials, and a private connection file.
The default state directory is .ignore/r2/tmp/local-postgres.
Wait until its attach.env and postgres.url files exist.
In a second terminal at the repository root, load that fixture:
export SYNCHRO_ATTACH_DIR="$PWD/.ignore/r2/tmp/local-postgres"export WARM_CONNECT_ENV_FILE="$SYNCHRO_ATTACH_DIR/attach.env"set -a. "$WARM_CONNECT_ENV_FILE"set +aexport ADAPTER_TEST_URL="$(cat "$SYNCHRO_ATTACH_DIR/postgres.url")"export SYNCHRO_TEST_JWT_SECRET="$(cat "$SYNCHRO_CONFORMANCE_JWT_SECRET_FILE")"Do not print or commit these values. The connection file authorizes test setup in this disposable instance.
Run integration checks
Section titled “Run integration checks”The native and bridge Make targets prepare and start their adapter as needed:
make test-swiftmake test-kotlinmake test-rn-e2e-iosmake test-rn-e2e-androidRun these sequentially when they share the fixture, simulator, emulator, or package output. Use conformance guidance for focused selectors and server-side suites.
For manual requests, start the foreground adapter instead:
make synchrod-pg-test-serveIt prepares the disposable integration schema before listening on port 8091.
Add CLIENT_DATASET=1 to also prepare the synthetic training dataset in conformance/dataset and its authored seed.
That dataset registers the shared catalog scope, so every user in that database receives it.
Do not run another adapter owner on that port.
The helper rejects an occupied port rather than terminating its owner.
Run a CI job locally
Section titled “Run a CI job locally”Each test job in .github/workflows/ci.yml calls one make ci-<job> target.
Run the same target to run the same test commands as CI:
make ci-source-qualitymake ci-candidate-servermake ci-candidate-swiftmake ci-candidate-kotlinmake ci-candidate-rn-iosmake test-rn-e2e-android-buildmake ci-candidate-rn-androidThe workflow file keeps only tool setup, device setup, database start and stop, and artifact upload.
Install the tools and boot the device that the job sets up before you run its target.
The server candidate target creates its API-test fixture after the Rust targets.
It stops that fixture before the independent black-box and integration mutation targets.
Do not start a separate fixture for the server candidate target.
Failed API fixture logs remain under .ignore/r2/tmp/candidate-server-adapter.*.
The native candidate targets need a disposable database.
They read its URL from ADAPTER_TEST_URL and its attach.env file from WARM_CONNECT_ENV_FILE.
For a native candidate database on this machine, start it as CI does:
make local-postgres-startexport ADAPTER_TEST_URL="$(cat .ignore/r2/tmp/local-postgres/postgres.url)"export WARM_CONNECT_ENV_FILE="$PWD/.ignore/r2/tmp/local-postgres/attach.env"For a database on another machine, set ADAPTER_TEST_URL to its URL.
Set WARM_CONNECT_ENV_FILE to a local copy of its attach.env file.
After the run, stop the fixture with make synchrod-pg-test-stop and make local-postgres-stop.
make ci-candidate-server fetches the pinned update baseline bundles again on each run.
Stop and clean up
Section titled “Stop and clean up”Stop the adapter before the database:
make synchrod-pg-test-stopThen press Control-C in the first terminal. The provisioner closes its database and removes its generated credentials. Do not terminate unrelated port owners or delete another process’s state directory.
Local logs, credentials, build output, and test reports must remain outside tracked source. Use RELEASE.md for release operations.