Skip to content

Latest commit

 

History

History
159 lines (112 loc) · 6.39 KB

contributing.md

File metadata and controls

159 lines (112 loc) · 6.39 KB

Contributing to SQLAnvil

Thanks for your interest in SQLAnvil — an open-source SQL workflow tool for BigQuery, PostgreSQL, and Supabase. Contributions of all kinds are welcome: bug reports, docs, adapter improvements, and new features.

How to contribute (no access request needed)

SQLAnvil follows the standard GitHub fork-and-pull-request model. You do not need to be granted access to contribute — anyone can fork the repo and open a PR.

  1. Fork sqlanvil/sqlanvil to your account.
  2. Clone your fork and branch off main:
    git clone [email protected]:<you>/sqlanvil.git
    cd sqlanvil
    git checkout -b my-change
  3. Make your change, then build and test (see below).
  4. Push to your fork and open a Pull Request against sqlanvil/sqlanvil main.

For anything larger than a small fix, open an issue first to discuss the approach before writing code.

Want push access?

There is no self-serve access request — that is by design. The fork-and-PR flow above is the contribution path. If you become a regular contributor and want direct push access, open an issue asking, and reference your merged PRs.

Build and test

SQLAnvil uses Bazel for all build and test targets. There are no npm run scripts — everything goes through Bazel. The JavaScript side of the build is rules_js + rules_ts over a pnpm lockfile (pnpm-lock.yaml); Bazel downloads its own Node and pnpm, so neither needs to be installed globally to build.

Prerequisites

  • Bazelisk — npm install -g @bazel/bazelisk
  • Docker (for the database integration-test containers; optionally for the hermetic build container)
  • Node.js 20+ LTS (used by some tooling outside Bazel)

Add new npm dependencies

Do not edit pnpm-lock.yaml by hand and do not use a global pnpm (its version must match MODULE.bazel). Add through Bazel's pnpm, with --dir so it does not install into Bazel's output tree:

bazel run -- @pnpm//:pnpm --dir "$PWD" add <package>
bazel run -- @pnpm//:pnpm --dir "$PWD" add -D <package>     # dev dependency

Then reference it from the deps of the ts_library that imports it as //:node_modules/<package> (and //:node_modules/@types/<package> for its types). A package the published CLI must install at runtime also goes in externals in packages/@sqlanvil/cli/BUILD. Security pins live in pnpm.overrides in package.json; scripts/check_upstream_resolutions compares them against upstream Dataform's.

macOS build note

Native Bazel works on macOS since the Bazel 7 + bzlmod migration (#41) — deliverables and tests build with no flags; a full bazel build //... (which includes C++/abseil corners) wants --config=macos-cpp. The Docker dev container remains available as an optional hermetic environment (if you use it, reach test databases as host.docker.internal instead of 127.0.0.1):

# Optional: build inside the container
./scripts/docker-bazel build //protos:sqlanvil_proto

# Optional: interactive shell
./scripts/docker-bazel

Run the CLI

# Via the wrapper script (builds first if needed)
./scripts/run help
./scripts/run compile path/to/project
./scripts/run run path/to/project

# Via Bazel directly
bazel run //packages/@sqlanvil/cli:bin -- help

Run tests

# All tests
bazel test //...

# Core compiler tests only
bazel test //core/...

# Integration tests (requires warehouse credentials)
bazel test //tests/integration/...

Integration test setup

BigQuery: Place a GCP service account key at test_credentials/bigquery.json.

Postgres: The Postgres integration tests use a Docker fixture started by Bazel:

bazel test //tests/integration:postgres
# Bazel launches tools/postgres/postgres_fixture.ts automatically inside the sandbox

Code style

  • TypeScript throughout (no JavaScript in core/ or cli/)
  • eslint.config.js and .prettierrc at the repo root: ./scripts/lint runs eslint over every .ts file (including the core/ no-Node-built-ins guard and import ordering) and prettier over the files your branch changed; ./scripts/format rewrites those files with prettier.
  • Run bazel build //... and bazel test //... before submitting a PR

Package names

All packages are scoped under @sqlanvil/:

  • @sqlanvil/core — compiler and action types
  • @sqlanvil/cli — command-line interface
  • @sqlanvil/sample-extension — example extension package

Pull request guidelines

  • One logical change per PR. Keep diffs focused and reviewable.
  • Clear description — what changed and why; link the related issue.
  • Match existing style (see Code style above). Add or update tests for behavior changes.
  • Adapters generate idiomatic SQL. The Postgres adapter is not a BigQuery adapter with translated SQL — it emits native Postgres DDL/DML (INSERT ... ON CONFLICT, native CREATE INDEX, PARTITION BY RANGE/LIST/HASH). Don't leak BigQuery quirks (OPTIONS(...), CLUSTER BY, NOT ENFORCED) into Postgres output.
  • Rename is complete. All packages are scoped under @sqlanvil/. Do not reintroduce dataform identifiers in new code.

Branch strategy

Feature branches target main. Postgres/Supabase adapter work proceeds in sequence:

  1. rename/dataform-to-sqlanvil — rename sweep (complete)
  2. adapter/postgres-first-class — Postgres adapter, SQL generator, proto changes
  3. adapter/supabase-variant — Supabase adapter and new action types

Upstream sync

The upstream remote points at github.com/dataform-co/dataform. Pull upstream changes before starting new work:

git fetch upstream
git rebase upstream/main

The rename sweep is complete. Upstream merges/cherry-picks should be straightforward (resolve any remaining conflicts on a case-by-case basis).

Because we take upstream selectively, security pins in package.json → resolutions drift without anything flagging it — upstream adds them via Dependabot PRs that land on their main between tagged releases. Check on every sync:

./scripts/check_upstream_resolutions          # exit 1 lists what we are missing

The full sync procedure (conflict playbook, verification, clean-up) lives in the SQLAnvil/docs repo: upstream_merge_guide.md.