Thanks for your interest in contributing to lakebase-app-dev-kit. This is a Databricks Solutions project – community-supported, not officially supported by Databricks.
- Node.js 20+ and npm (matches
package.json#engines) - Databricks CLI v1.0.0 or later, authenticated to a workspace with Lakebase enabled. Earlier versions (0.x) hit an expired-Terraform-GPG-key error during
databricks bundle deploy. Install / upgrade withbrew upgrade databricks/tap/databrickson macOS or per the official install docs. - Python 3.10+ (used by
scripts/openai-foundry.py,scripts/skills.py, and the live driver's auto-provisioned alembic venv) - git (standard CLI)
- GitHub CLI (
gh) authenticated to your GitHub account, for the self-hosted-runner suite. The live driver defaults to running it; pass--no-github-runnerto opt out (see "Live testing" below). - JDK 17+ and the Flyway CLI for
schema-migrate-live-flyway.test.ts. The live driver downloads Flyway Community CLI from${LAKEBASE_KIT_REGISTRY_MAVEN_CENTRAL}on first run ifflywayis not already on PATH; pre-installing viabrew install flywayis fine. - A Python venv with alembic + sqlalchemy + psycopg2-binary for
schema-migrate-live.test.ts. The live driver auto-provisions.venv-live-tests/on first run. - Node.js with
npmandnpxon PATH forschema-migrate-live-knex.test.ts. The suite self-installsknex+pginto a scratch project directory in itsbeforeAll(); no script-level provisioning needed.
git clone https://github.com/databricks-solutions/lakebase-app-dev-kit
cd lakebase-app-dev-kit
npm install # `prepare` builds dist/ via tsupThe kit's substrate reads a number of LAKEBASE_KIT_* env vars to tune timeouts, package-registry URLs, and convention-branch TTLs (see scripts/lakebase/kit-config.ts for the full surface). Two committed files document the contract:
.env.template.test.config(committed): public-default values for every env-overridable knob. Sourced first byscripts/run-all-live-tests.sh..env.local.test.config(gitignored): your local overrides, e.g. corp-proxy package registries or a workspace-tighterLAKEBASE_KIT_FEATURE_BRANCH_TTL_MS. Sourced second so local values win.
Copy .env.template.test.config to .env.local.test.config and set the values your machine needs. The live driver auto-sources both.
npm run build # compile TS to dist/ (tsup)
npm run typecheck # tsc --noEmitprepare runs build automatically on install, so consumers that pin via git URL get a built dist/ without extra steps.
scripts/ # operations – CLI and module entry points
git/ # init, clone, commit-push, push, remote
github/ # auth, repo, pr, secrets, runner
lakebase/ # branch-*, get-connection, schema-diff, scaffold,
# create-project, migrate, schema-migrate-runners, ...
util/ # exec, delay, parse, env helpers
openai-foundry.py # generates tools/openai-foundry/*.tools.json
skills.py # regenerates manifest.json from skills/
sync-devhub-skills.ts # syncs vendored skills from databricks/devhub
run-live-tests.sh # live integration test runner with consent + cleanup
apps/mcp-server/ # MCP server entry (built to dist/apps/mcp-server/)
tools/openai-foundry/ # Pre-rendered OpenAI Foundry tool spec
skills/ # Per-workflow-domain agent surface (SKILL.md per domain)
lakebase-scm-workflows/ # kit-authored
lakebase-release-workflows/ # kit-authored
databricks-core/ # vendored from databricks/devhub – read-only
databricks-lakebase/ # vendored from databricks/devhub – read-only
templates/ # files shipped into bootstrapped projects
tests/bdd/ # vitest BDD tests – hermetic + live-gated
The kit has two parallel agent surfaces that must stay in sync:
- MCP server (
apps/mcp-server/tools.ts) – consumed by Claude Desktop, OpenAI Codex, Cursor-via-MCP - OpenAI Foundry tool spec (
tools/openai-foundry/lakebase-app-dev-kit.tools.json) – pre-rendered, regenerated bypython3 scripts/openai-foundry.py
Drift between the two is caught by python3 scripts/openai-foundry.py validate. Run it after touching tool definitions.
Vendored skills (skills/databricks-core/, skills/databricks-lakebase/) are read-only mirrors of databricks/devhub. To pull the latest, run npm run sync:devhub and commit any diff in a focused PR. CI runs npm run check:devhub to catch drift.
Two narrow auth paths, each enforced by a CI grep guard:
scripts/lakebase/get-connection.tsis the only path that mints Lakebase credentials. Every other workflow op callsgetConnection().scripts/github/auth.tsis the only path that resolves a GitHub token (GITHUB_TOKENenv → VS CodegetSessionin extension host →gh auth token).
When you add a code path that needs Lakebase credentials or a GitHub token, call one of these helpers. Adding a second call site (e.g. another databricks postgres generate-database-credential invocation, or another gh auth token invocation) fails the CI grep guard, intentionally.
All three tiers, every substantive PR. The hermetic tier is fast and catches most logic regressions; the live tier is the only layer that exercises real Lakebase project creation, branch lifecycle, endpoint provisioning, and migration runners. PRs that change anything in
scripts/lakebase/should include a live-tier run, or explain in the PR description what was and wasn't covered.
npm test # vitest run
npm run test:watch # vitest --watchRuns all of tests/bdd/ with the live-gated suites self-skipping when their LAKEBASE_TEST_* env vars are unset. Always run before pushing. The husky pre-push gate runs this plus typecheck.
The live tier hits a real Databricks workspace, creates real Lakebase projects, exercises Alembic + Flyway, optionally creates a real GitHub repo + self-hosted runner, and optionally deploys a real Databricks App. Two runners with different scope:
One command, one provisioned project, every gated test in the kit. Provisions a fresh Lakebase project, builds dist, sources .env.template.test.config + .env.local.test.config, and runs vitest with every LAKEBASE_TEST_* describe unlocked. Heavy: ~5 to 15 minutes including the Apps deploy + teardown.
bash scripts/run-all-live-tests.sh --profile <databricks-cli-profile> --no-promptDefaults to enabled coverage for every live-gated suite. Opt-out flags:
| Flag | Disables |
|---|---|
--no-github-runner |
self-hosted-runner suite (skip if no gh auth) |
--no-migrate-tools |
Auto-provisioning of .venv-live-tests/ (alembic) + Flyway CLI download |
Configuration flags (defaults shown in --help):
| Flag | Purpose |
|---|---|
--profile <name> |
Required. Databricks CLI profile (from ~/.databrickscfg). |
--project <id> |
Reuse an existing Lakebase project instead of auto-provisioning. |
--branch, --parent |
Override LAKEBASE_TEST_BRANCH / LAKEBASE_TEST_PARENT. |
--feature-ttl-days <n> |
Tighten the convention feature-branch TTL when the workspace's policy is shorter than the default 30 days. |
--teardown |
Delete the auto-provisioned orchestrator project on a fully green run. |
--no-prompt |
Skip the 5s grace period (use in CI). |
Older runner that supports --read-only and --all modes. Use when you only need a subset of suites against an existing project. The run-all-live-tests.sh orchestrator covers the same ground plus more.
| Mode | Required env + tools | What runs | Creates resources? |
|---|---|---|---|
| default (migrate) | DATABRICKS_HOST, LAKEBASE_TEST_E2E=1, authenticated databricks CLI, python3, java, flyway, npm |
tests/bdd/schema-migrate-live.test.ts (alembic) + tests/bdd/schema-migrate-live-flyway.test.ts + tests/bdd/schema-migrate-live-knex.test.ts |
Yes: migrate-7091-<ts> + migrate-7098-<ts> + migrate-7099-<ts> Lakebase projects, each deleted in their suite's afterAll() |
--read-only |
LAKEBASE_TEST_INSTANCE, LAKEBASE_TEST_BRANCH |
Read-only schema / endpoint / DSN suites against the configured branch | No |
--all |
both of the above | Everything vitest discovers when gating env is satisfied | Yes (default mode) |
export DATABRICKS_HOST=https://<your-workspace>.cloud.databricks.com
export LAKEBASE_TEST_E2E=1
npm run test:liveIf your network blocks Maven Central (where the Flyway CLI is hosted), install Flyway separately (brew install flyway, your internal mirror, etc.) and put it on PATH before invoking npm run test:live. The script's preflight finds the pre-installed binary and skips the download. The same LAKEBASE_KIT_REGISTRY_MAVEN_CENTRAL env override (set in .env.local.test.config) redirects the Flyway download to a proxy.
Consent model. Setting LAKEBASE_TEST_E2E=1 + DATABRICKS_HOST authorizes the suite to create a Lakebase project on your workspace. The helper script pauses for 5 seconds before the create call with a notice showing the workspace + project name pattern; ctrl-c aborts. Set LAKEBASE_TEST_NO_PROMPT=1 in CI to skip the pause.
Cleanup recovery. Teardown retries delete up to 3 times. If a project still leaks (signal interrupt, crash before afterAll(), network blip), clean up manually:
databricks postgres delete-project <projectId>
databricks apps delete <appName> # if a slice 3 deploy test was interrupted
gh repo delete <owner>/detect-language-verify-<ts> --yes # if the self-hosted-runner suite was interruptedProject names always have a timestamp suffix so re-runs and concurrent runs do not collide.
Individual gating env vars also light up subsets directly: LAKEBASE_TEST_INSTANCE + LAKEBASE_TEST_BRANCH activates the read-only live tests in any vitest run invocation; LAKEBASE_TEST_INITIALIZR=1 enables the Spring Initializr live fetch; LAKEBASE_TEST_PARENT configures the parent for diff suites; LAKEBASE_TEST_E2E_GITHUB=1 enables the self-hosted-runner suite.
The end-to-end TDD-workflow smoke lives in examples/tdd-workflow-smoke/. It scaffolds a real bug-tracker project and drives it through two sprints (/plan -> /design -> /build -> /deploy with the HITL gates played by the Human Proxy). It runs against your own Databricks workspace and GitHub owner, not anyone else's.
Configure , copy the template and fill in your values:
cp examples/tdd-workflow-smoke/.env.example ~/lakebase-smoke.env
# edit ~/lakebase-smoke.env
set -a; source ~/lakebase-smoke.env; set +aRequired env vars:
| Var | Purpose |
|---|---|
DATABRICKS_HOST |
Your workspace URL (or set DATABRICKS_CONFIG_PROFILE + have ~/.databrickscfg). |
GITHUB_OWNER |
Your sandbox GitHub user or org; the smoke creates + uses a repo under it. |
Optional: LAKEBASE_KIT_REF (pin the kit to a branch/tag/sha instead of this checkout's built dist/), LAKEBASE_KIT_DIR (point lk at a specific kit install), LAKEBASE_TDD_AUTO_CONTINUE=1 (auto-answer the pause-at-handoff gates in CI).
Run , the orchestrator has four scripts in examples/tdd-workflow-smoke/orchestrator/:
# 1. (maintainers) rebuild + push + warm the kit cache; only needed to validate a published ref
examples/tdd-workflow-smoke/orchestrator/rebuild-push-warm.sh
# 2. end-to-end against your workspace (--tiers 2 is required)
examples/tdd-workflow-smoke/orchestrator/run-smoke.sh --tiers 2
# pause just before the Navigator / Release Engineer handoffs (replay-fed)
examples/tdd-workflow-smoke/orchestrator/run-to-navigator.sh --tiers 2
examples/tdd-workflow-smoke/orchestrator/run-to-release-engineer.sh --tiers 2By default the smoke runs your local working tree's dist/. Pass --kit-ref <ref> to validate a published branch/tag instead. The scaffold target defaults to ~/code/tdd-workflow-smoke/; override with --project-dir <dir>. See examples/tdd-workflow-smoke/README.md for the full script reference.
| Change scope | Minimum |
|---|---|
| Docs / comments | Tier 1 |
scripts/util/* / hermetic helpers |
Tier 1 |
scripts/github/* / scripts/git/* |
Tier 1 + manual smoke on a throwaway repo |
scripts/lakebase/* (branch lifecycle, endpoints, migrate) |
Tier 2 mandatory |
| MCP / Foundry tool definitions | Tier 1 + python3 scripts/openai-foundry.py validate |
Vendored skills (skills/databricks-*) |
Pull via npm run sync:devhub only; do not hand-edit |
| TDD orchestrator / role agents / scaffolded commands | Tier 1 + the TDD-workflow smoke (Tier 2) |
- Branch off
main. Branch names:<email-username>/<short-description>. - One logical change per PR. Keep commits small and squashable.
- Commit messages: short subject (≤72 chars), then a body explaining why. Code already shows what. PRs are squash-merged; the squash subject is the PR title.
- The husky
pre-pushgate runstypecheck + test. Do not bypass it (HUSKY=0) unless the gate itself is broken. - Run the appropriate test tier(s) per the table above before opening the PR. The PR description should note what was run.
- Update
manifest.jsonautomatically viapython3 scripts/skills.pyif you added or renamed files underskills/. CI validates withpython3 scripts/skills.py validate. - If your PR adds a new CLI bin or changes the consumer-facing API, also update the relevant section of
README.md.
The package is consumed via git URL (github:databricks-solutions/lakebase-app-dev-kit#<tag>); npm publish is intentionally deferred (org/scope/runner questions). Cuts are tag-based:
- Land the change on
mainvia PR. - Bump
package.jsonversion on the current pre-release line (the v0.3.0 line graduated from alpha to beta:0.3.0-beta.<N+1>; seeCHANGELOG.mdfor the active series). - Tag the bump commit:
git tag v0.3.0-beta.<N> && git push origin v0.3.0-beta.<N>. - Consumers update their git URL pin to the new tag.
Tags are append-only by default; only force-move a tag when you've just merged a follow-up that should clearly ship under the same version (rare).
Use GitHub Issues. Include:
- The CLI verb or function name you ran
- The exact error message + stderr (with secrets redacted)
- Output of
databricks postgres list-branches "<project-path>"for branch-related bugs - Versions:
node --version(>= 20),databricks --version(>= 1.0.0),python3 --version(>= 3.10), this kit's version (package.json#versionor the pinned commit sha). Includeflyway --versionandjava --versionif a schema-migrate-live-flyway test was involved.
This project follows the Contributor Covenant.