From 63908f8d29b723b6e855bba362e0e48360926dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Repe=C4=87?= Date: Mon, 15 Jun 2026 13:45:29 +0200 Subject: [PATCH] chore: Improve tbls availability for schema docs generation (#32244) Co-authored-by: Claude Opus 4.8 (1M context) --- CONTRIBUTING.md | 15 ++++++++++ lefthook.yml | 7 +---- packages/@n8n/db/scripts/schema-docs.mjs | 35 ++++++++++++++++++++---- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dc09e06539b..5e70ac087bb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -135,6 +135,21 @@ brew install actionlint ``` > **Note:** actionlint is only required if you're modifying workflow files. It runs automatically via git hooks when workflow files are changed. +#### tbls (for database schema docs) + +The database schema docs under [`docs/generated/`](docs/generated) are generated from the migrations with [tbls](https://github.com/k1LoW/tbls). If you plan to modify DB migrations, you'll need **either** tbls installed **or** Docker available. + +**macOS (Homebrew):** +```bash +brew install tbls +``` + +For other platforms, see the [tbls install guide](https://github.com/k1LoW/tbls#install). + +> **Note:** tbls is only required if you're modifying DB migrations. It runs automatically via git hooks when migration files are changed. + +--- + ### Actual n8n setup > **IMPORTANT**: All the steps below have to get executed at least once to get the development setup up and running! diff --git a/lefthook.yml b/lefthook.yml index 961bbeb62a4..e7d1abfa0f1 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -42,12 +42,7 @@ pre-commit: - rebase db_schema_check: glob: 'packages/@n8n/db/src/migrations/{common,postgresdb,sqlite}/*.ts' - run: | - if command -v tbls >/dev/null 2>&1; then - pnpm run db:schema:check:sqlite - else - echo "tbls not installed (brew install tbls) — skipping db schema check" - fi + run: pnpm run db:schema:check:sqlite skip: - merge - rebase diff --git a/packages/@n8n/db/scripts/schema-docs.mjs b/packages/@n8n/db/scripts/schema-docs.mjs index acfed1c1f55..8cbbde31a09 100644 --- a/packages/@n8n/db/scripts/schema-docs.mjs +++ b/packages/@n8n/db/scripts/schema-docs.mjs @@ -170,7 +170,7 @@ async function tbls(command, dbType, dsn, docker) { } async function main() { - const { command, dbType, docker } = parseArgs(process.argv.slice(2)); + let { command, dbType, docker } = parseArgs(process.argv.slice(2)); if (command !== 'doc' && command !== 'diff') { fail('usage: schema-docs.mjs --db= [--docker]'); } @@ -178,10 +178,35 @@ async function main() { fail('--db must be sqlite or postgres'); } - // Fail fast on a missing binary, before spinning up a DB and running migrations. - const requiredBin = docker ? 'docker' : 'tbls'; - const probe = spawnSync(requiredBin, ['version'], { stdio: 'ignore' }); - if (probe.error) fail(spawnErrorMessage(requiredBin, probe.error)); + // Resolve which tbls runtime to use, before spinning up a DB and running + // migrations. Prefer a local tbls binary; fall back to the Docker image when + // it's absent. `--docker` (or CI) forces the Docker path. + const probeBin = (cmd) => { + const { error, status } = spawnSync(cmd, ['version'], { stdio: 'ignore' }); + if (error) return 'missing'; + return status === 0 ? 'ok' : 'broken'; + }; + + if (docker) { + const state = probeBin('docker'); + if (state === 'missing') fail(spawnErrorMessage('docker', { code: 'ENOENT' })); + if (state === 'broken') + fail('docker is installed but not responding — is the Docker daemon running?'); + } else if (probeBin('tbls') !== 'ok') { + if (probeBin('docker') === 'ok') { + docker = true; + console.info( + 'tbls not available — falling back to running in Docker. ' + + 'Install tbls (`brew install tbls` or see ' + + 'https://github.com/k1LoW/tbls#install) to run locally.', + ); + } else { + fail( + 'neither tbls nor docker is available. Install tbls (`brew install tbls`, ' + + 'see https://github.com/k1LoW/tbls#install) or ensure Docker is set up.', + ); + } + } const provisioned = await provision(dbType); try {