LakeQL
Introduction
  • Overview
  • Why LakeQL
  • Key Concepts
Getting Started
  • Prerequisites
  • Quickstart
  • Environment
  • First Run
Architecture
  • System Overview
  • Data Flow
  • Request Lifecycle
Configuration
  • Config File
  • Runtime Lifecycle
  • Environment Variables
create-app
  • Usage
  • Template Structure
  • Post-Creation
Guides
  • Custom Resolvers
  • Extending the Schema
  • Mutations
  • Set Up a Trino Mutation
  • Deploying
Endpoints
  • Definition Format
  • Field Types
  • Nested Fields
  • Mutations
  • Glossary
Contributing
  • Local Development
  • Contribution Guide
  • Architecture
GitHub
LakeQL
  1. LakeQL
  2. Contributing
  3. Contribution Guide

On this page

  1. Getting Started
  2. Project Structure
  3. Development Workflow
    1. Building
    2. Running Tests
    3. Type Checking
    4. Linting and Formatting
  4. Commits
  5. Changelogs
  6. Testing create-app on a Feature Branch
    1. Running a preview build
  7. Pull Requests
    1. Workflow
    2. PR Guidelines
  8. Workspace Validation

Contribution Guide

Guidelines for contributing to LakeQL — branching, testing, linting, and PR workflow.

Getting Started #

Fork and clone

Fork the repository on GitHub, then clone your fork:

1
2
3
git clone https://github.com/<your-username>/lakeql.git
cd lakeql

Set up the environment

Follow the Local Development guide to install dependencies and start the local Trino cluster.

Create a feature branch

Always branch from main:

1
2
git checkout -b feat/my-feature main

Project Structure #

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22lakeql/
├── apps/
│   └── docs/              # Documentation site (Next.js)
├── packages/
│   ├── adapter-fabric/    # Fabric adapter
│   ├── adapter-trino/     # Trino adapter
│   ├── api/               # GraphQL API server (Pothos + Yoga)
│   ├── cli/               # CLI tool
│   ├── config/            # Shared configuration utilities
│   ├── create-app/        # Project scaffolding tool
│   ├── datasource/        # Data source abstraction
│   ├── fabric-client/     # Microsoft Fabric client
│   ├── query-builder/     # SQL query builder
│   ├── storage/           # Storage write operations
│   ├── trino-client/      # Trino REST API client
│   └── ...                # Internal packages (helpers, logger, etc.)
├── tooling/
│   ├── test-data/         # Test data generation and seed tooling
│   └── typescript/        # Shared TypeScript config
├── templates/             # App scaffolding templates
└── .minitrino/            # Local Trino cluster configuration

Development Workflow #

Building #

The monorepo builds packages with tsdown and orchestrates tasks with Turbo:

1
2
3
4
5
6
# Build all packages
pnpm build:pkg

# Build everything (packages + apps)
pnpm build

Running Tests #

Tests are written with vitest:

1
2
3
4
5
6
7
8
9
10
11
12
# Run all tests
pnpm test

# Run tests for a specific package
pnpm -F @lakeql/trino-client test

# Run with coverage
pnpm test -- --coverage

# Interactive UI
pnpm test:ui

Type Checking #

1
2
pnpm typecheck

Linting and Formatting #

The project lints with oxlint and formats with oxfmt. The shared rule presets come from Ultracite:

1
2
3
4
5
6
7
8
9
10
11
12
# Lint all files
pnpm lint

# Lint and auto-fix
pnpm lint:fix

# Check formatting
pnpm format

# Format all files
pnpm format:fix
Run pnpm lint and pnpm format before committing to catch issues early.

Commits #

Write clear, descriptive commit messages. Prefer the conventional commit format:

1
2
3
4
feat(api): add cursor-based pagination
fix(trino-client): handle empty result sets
docs: update quickstart guide

Keep each commit focused on a single logical change.

Changelogs #

LakeQL uses Tegami for versioning and changelogs. When your change affects a published @lakeql/* package, add a changelog file under .tegami/.

The fastest way is the interactive TUI. It prompts you for the affected packages and bump level, then writes the file for you:

1
2
pnpm tegami

To write the file by hand, create it under .tegami/ following the naming convention:

1
2
# File: .tegami/YYYY-MM-DD-<short-description>.md

Either way, the file declares affected packages in YAML frontmatter and carries user-facing release notes in a markdown body:

1
2
3
4
5
6
7
8
9
---
packages:
  "npm:@lakeql/trino-client":
    type: patch
---
### Fix empty result handling

Return an empty array instead of throwing when Trino returns zero rows.

When a changelog is needed:

  • Any change to a published @lakeql/* package — including bug fixes, features, and refactors

When a changelog is not needed:

  • Changes to tooling/ , docs, or dev infrastructure
  • Changes to private: true packages
Do not edit directly
Never edit .tegami/publish-lock.yaml or CHANGELOG.md files in packages. These are managed by Tegami during releases.

Testing create-app on a Feature Branch #

When a pull request touches packages/**, CI publishes a pkg.pr.new preview build of every package, including @lakeql/create-app. That preview build of create-app is self-consistent. It downloads the starter template from the PR's own branch and resolves @lakeql/* dependencies to that same commit's pkg.pr.new preview versions, instead of the main template and npm latest packages.

This means a maintainer can e2e-test create-app end to end against a feature branch — scaffold a project with the preview build and it pulls in the branch's own template and packages — rather than only being able to test against main + npm latest.

This behavior is CI-only infrastructure, driven by build-time environment variables the pipeline sets. The released create-lakeql-app is unaffected and keeps resolving the template from main and dependencies from npm latest.

Running a preview build #

The PR comment from pkg.pr.new lists an install URL for each package. To scaffold with the create-app preview, run its URL as a one-off with pnpm dlx or npx. Don't use pnpm create, which expects a package specifier rather than a URL:

1
2
3
pnpm dlx --config.block-exotic-subdeps=false \
  https://pkg.pr.new/noxify/lakeql/@lakeql/create-app@<sha> my-app

The --config.block-exotic-subdeps=false flag is required with pnpm. The preview build of create-app carries its own @lakeql/scaffold dependency as a pkg.pr.new URL, and recent pnpm versions block URL dependencies nested inside a package by default (ERR_PNPM_EXOTIC_SUBDEP). npx does not need the flag.

To confirm the self-consistency, check the generated project's package.json. Every @lakeql/* dependency should point at https://pkg.pr.new/noxify/lakeql/<package>@<sha> (the same commit), while non-@lakeql/* dependencies keep their normal npm versions.

Pull Requests #

Workflow #

Ensure all checks pass

Before opening a PR, verify your changes locally:

1
2
3
4
5
pnpm typecheck
pnpm lint
pnpm format
pnpm test

Push and open a PR

Push your branch and open a pull request against main. Reference any related issues in the PR description.

Address review feedback

Respond to review comments and push additional commits. Avoid force-pushing unless asked — it makes review harder to follow.

PR Guidelines #

  • Keep PRs focused on a single feature or fix
  • Include a brief summary of what changed and why
  • Add a Tegami changelog file if the change affects published packages
  • Make sure CI passes before requesting review

Workspace Validation #

The project validates workspace constraints with sherif, checking for consistent dependency versions and proper workspace references:

1
2
pnpm lint:ws

Run this if you add or update dependencies to verify the workspace stays consistent.

Previous page

Local Development

Next page

Architecture

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22