dbt commands
Send the artifacts dbt writes to target/ to Cassis, from the dbt project's CI: push after a merge to keep the project's dbt baseline current, check on a pull request to see what the change puts in doubt.
Both commands need cassis-cli 3.3. They run in the dbt project’s repository, which has no cassis/project.yml, so set CASSIS_PROJECT_ID or pass --project. The workflow is in Handle source changes; the CI jobs are below.
dbt push
Uploads manifest.json, and catalog.json when present, as the project’s new dbt baseline. Run it after dbt docs generate on your production target, after a merge to the production branch.
dbt docs generate --target prod
cassis dbt push target --project ...
It waits for Cassis to check the files, then prints how many dbt models and sources match tables of the project’s data source and how many tests they declare. Cassis compares the upload with the previous baseline and files each part of the context the change puts in doubt as an issue with the at_risk impact. The command lists those issues with their reach and a link to each.
dbt check
Uploads a pull request’s artifacts as a check. Run it after dbt compile (or dbt docs generate) on the production target.
dbt compile --target prod
cassis dbt check target --project ...
Cassis compares the artifacts with the project’s dbt baseline and the command prints the context tables, columns, joins, and metrics the change puts in doubt, grouped by context object, each with why it matters and the context change to make. Then it prints the tables and columns dbt no longer builds. A removed model names the joins, metrics, and virtual tables that use it, and a column that disappears while exactly one appears is reported as likely renamed. Within each section, the objects with the widest reach print first. Nothing is filed and the baseline does not move.
Options
Both commands take the same options.
- Target
- The positional argument is dbt’s target directory,
targetby default.manifest.jsonis required;catalog.jsonis sent when present. - Commit
--commit(default:HEADof the git checkout) and--commit-message(default: read from git). Outside a git checkout,--commitis required.- Pull request
--pr-titleand--pr-description. On GitLab CI and GitHub Actions they default to the merge request or pull request. After a merge,pushfinds the title of the pull request that merged the commit: on GitHub Actions through the GitHub API (exposeGITHUB_TOKENto the step; a failure is ignored), on GitLab from the merge commit.- Waiting
--poll-interval(2 seconds) and--timeout(10 minutes).- Links
--app-urlorCASSIS_APP_URLsets the web app’s address for the links to filed issues, when it is not served from the API host.- JSON
--jsonprints the upload record on stdout; the summary goes to stderr.- Size
- Up to 128 MB per file, and 32 MB once compressed. An oversized file fails before anything is sent.
Exit codes
| Code | dbt push | dbt check |
|---|---|---|
| 0 | Accepted as the baseline, or kept behind a newer upload | Checked, with or without findings |
| 1 | Rejected: an invalid file, an unsupported dbt version, or no relation matches the project’s data source | Rejected: an invalid file, or no baseline yet (run dbt push on the production branch first) |
| 2 | Usage error: no manifest.json, no commit, or a file over the size limit | Same |
| 3 | Transport error, or Cassis failed while processing the upload: push again | Same |
dbt check never fails your CI on findings. Gate on exit codes 1 to 3 only.
CI setup
Both jobs run in the dbt project’s repository. Store CASSIS_API_KEY as a secret and CASSIS_PROJECT_ID as a variable. The key needs edit access to the project; scope it to that project. The dbt steps run on your production target, so the job needs the same dbt setup and warehouse credentials as your other dbt jobs.
GitHub Actions
name: Cassis dbt
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
pull-requests: read
jobs:
cassis-dbt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
# Install dbt and its adapter, and configure the profile, as in your other dbt jobs.
- run: python -m pip install "cassis-cli~=3.3"
- if: github.event_name == 'push'
run: |
dbt docs generate --target prod
cassis dbt push target
env:
CASSIS_API_KEY: ${{ secrets.CASSIS_API_KEY }}
CASSIS_PROJECT_ID: ${{ vars.CASSIS_PROJECT_ID }}
GITHUB_TOKEN: ${{ github.token }}
- if: github.event_name == 'pull_request'
run: |
dbt compile --target prod
cassis dbt check target
env:
CASSIS_API_KEY: ${{ secrets.CASSIS_API_KEY }}
CASSIS_PROJECT_ID: ${{ vars.CASSIS_PROJECT_ID }}
GITHUB_TOKEN lets the push find the pull request that merged the commit, so the issues it files carry the pull request’s title. Change main if your production branch has another name.
GitLab CI
cassis-dbt-push:
image: python:3.12 # not -slim: the CLI reads the commit from git
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
# Install dbt and its adapter, and configure the profile, as in your other dbt jobs.
- python -m pip install "cassis-cli~=3.3"
- dbt docs generate --target prod
- cassis dbt push target
cassis-dbt-check:
image: python:3.12
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- python -m pip install "cassis-cli~=3.3"
- dbt compile --target prod
- cassis dbt check target
On GitLab the push reads the merge request’s title from the merge commit.