CI Integration
The check
dfmt check .
Exit 0 if everything is formatted, 1 if anything is not. Nothing is ever written. The summary is one line:
2 files checked, 2 would be reformatted, 0 already formatted, 0 not assessed (parse warnings), 0 failed (148ms)
Each counter is a different outcome, and two of them are easy to conflate:
- would be reformatted — dfmt formatted the file and the result differs from what is on disk.
- not assessed — dfmt declined to judge: it could not parse the file under the declared dialect, or the file is a template and no dbt project was found to evaluate it against.
- failed — the run itself broke: unreadable file, bad config.
check fails on "not assessed" as well as on "would be reformatted". A file nobody could
assess is not a passing file; if it were treated as passing, a dialect mistake in dlab.json would
look like a clean repository. When files go unassessed, dfmt names the declared dialect in a hint,
because the usual cause is that the dialect is wrong rather than the SQL.
Showing the diff in the log
check says which files are wrong. diff says what is wrong with them:
dfmt diff .
They are separate runs — the output modes are mutually exclusive — so a job that wants both runs
check to set the exit code, and diff when it fails.
GitHub Actions
name: SQL format
on: [pull_request]
jobs:
dfmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # --changed-since needs history
# Install dfmt: download the release archive for the runner's platform
# (dlab-x86_64-pc-linux.tar.gz) and put the binary on PATH.
- run: dfmt check .
- if: failure()
run: dfmt diff .
fetch-depth: 0 matters only if you use --changed-since; the default shallow checkout has no
origin/main to diff against.
Only what the PR touched
dfmt check --changed-since origin/main
--changed-since asks git for changed .sql files and then intersects them with the
include/exclude patterns in dlab.json, so files outside your project are not checked even if
they changed.
This is a smaller check, not a weaker one — but it does mean a file that was already unformatted
before the PR stays unformatted. Run the full dfmt check . on the default branch if you want the
whole repository held to the standard.
Pre-commit
repos:
- repo: local
hooks:
- id: dfmt
name: dfmt
entry: dfmt check
language: system
types: [sql]
To format instead of complain, make the entry dfmt write and let the hook restage.
dbt projects
Package macros have to be present before dfmt can evaluate a template that calls them, so dbt deps
comes first:
- run: dbt deps
- run: dfmt check .
Without it, dfmt stops the run and tells you: a project whose packages.yml is uninstalled is
misconfigured, and formatting its models anyway would expand every missing macro to nothing and
format the result. That is a wrong answer dressed as a successful one, so it is an error and not a
warning.