Issues and pull requests are welcome.
You need a recent stable Rust toolchain (see rust-toolchain.toml) and PostgreSQL 18 with the extensions in docker/init.sql (pgvector among them). The simplest way:
docker compose up -d # PostgreSQL 18 with the integrated extensions (docker/test-pg), database graphpg_test on localhost:5432
cargo test --workspaceTo use another database, set TEST_DATABASE_URL. The tests create their own schemas (*_fixture, app_public, interfaces_and_unions) and leave them in place; use a throwaway database.
The repository is a moon workspace: Rust in crates/graphpg, the embedded web UIs (crates/graphpg-ui, built from the JS packages in packages/, GraphiQL in packages/graphiql-ui), the end-to-end suite in e2e/ (TypeScript, with Drizzle owning the test schema and migrations), and the documentation website in packages/website. moon installs the pinned Rust and Node/pnpm toolchains (.moon/toolchains.yml) itself. Install moon, then from the repository root:
pnpm install # once: Node dependencies (git hooks are installed on the first moon run)
pnpm db:up # PostgreSQL 18 + pgvector (db:down stops it, db:reset wipes it)
pnpm dev # build the UI, run graphpg against DATABASE_URL (copy .env.example to .env), GraphiQL on
moon run graphiql-ui:dev # in a second terminal: rebuild the UI on change (a debug graphpg reads it from disk, reload the page)
pnpm build # build the UI, then cargo build
pnpm bundle:graphiql # build the GraphiQL UI only
pnpm test # Rust integration tests, then the end-to-end suite
pnpm test:e2e # Drizzle migrates + seeds, the built graphpg is queried
pnpm test:e2e:watch # the same, re-run on change
pnpm db:generate # after editing e2e/src/schema.ts: writes the next SQL migration
pnpm verify # typecheck, lint and format check (Rust and TypeScript), as CI runs first
pnpm fix # apply rustfmt and Biome fixes
pnpm check # verify + all tests
moon run website:dev # the documentation website at localhost:5173, from docs/, README.md and CHANGELOG.mdTwo git hooks are installed by moon (defined in .moon/workspace.yml, no setup needed):
- pre-commit runs typecheck, lint and format on the projects with staged changes, and checks only the staged TypeScript files, so the checks CI runs first fail on your machine first.
- pre-push runs the tests affected by the commits you are pushing (against
origin/main), including the projects that depend on them. It needs PostgreSQL:pnpm db:up.
Skip either in an emergency with git commit --no-verify / git push --no-verify.
- Each file in
crates/graphpg/tests/is an integration test against a real database. A file creates the schema it needs, guarded by an advisory lock; when you change a fixture, bump its version string so it is rebuilt. - Shared fixtures live in
crates/graphpg/tests/fixtures/andtests/common/mod.rs. - The end-to-end suite (
e2e/) also explores the schema it serves (e2e/src/explore.ts): every root field, relation, ordering and page, aggregate, grouping and filter the schema advertises is requested, and every filter operator, cursor and id is sent malformed and boundary values. The engine may refuse a request (a typed error), never fail on one (a 5xx or an untyped database error). Run it against any graphpg, a large schema of your own included:pnpm --filter @graphpg/e2e explore http://localhost:4000/graphql [--only <regex>] [--max <n>](it needsgraphql.introspection). - The generated-schema snapshot (
tests/snapshots/) is reviewed withcargo insta review, or accepted withINSTA_UPDATE=always cargo test --test forum_schema. - Tests in one file run in parallel: don't assert on counts of rows that other tests in the file create.
- Keep changes focused, add or update tests, and run
cargo test --workspacebefore pushing. - Describe behaviour in
docs/when you add or change a feature. The website copiesdocs/,README.mdandCHANGELOG.mdas they are: a new page indocs/also needs a sidebar entry inpackages/website/src/.vitepress/config.mts. - By contributing you agree that your work is licensed under the project's licenses (MIT OR Apache-2.0).
How CI, publishing and dependency updates fit together is described in docs/pipelines.md.
Releases are cut by tagging; the Publish workflow does the rest.
- Bump
versioninCargo.toml(andCargo.lock: runcargo build), and runchangelog.d/collect.sh <version>to move the changelog fragments into a section ofCHANGELOG.md. Merge tomainthrough a pull request. - Tag that commit and push the tag:
Use a pre-release suffix (
git tag -a v1.0.2 -m "graphpg 1.0.2" && git push origin v1.0.2
v1.1.0-rc.1) for release candidates: they get a pre-release on GitHub and nolatest,X.YorXtags. - The workflow refuses a tag that is not on
mainor whose version differs fromCargo.toml, runs the tests, builds the image, scans it, pushes it, signs it and creates the GitHub Release with generated notes.
Every push to main also publishes ghcr.io/mihailtd/graphpg:sha-<short hash> and :edge.
Release notes are generated from merged pull requests and grouped by label (breaking, feature, bug, security, documentation, dependencies; skip-changelog hides one). Label pull requests before tagging.