Skip to content
Raw Markdown

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, target by default. manifest.json is required; catalog.json is sent when present.
Commit
--commit (default: HEAD of the git checkout) and --commit-message (default: read from git). Outside a git checkout, --commit is required.
Pull request
--pr-title and --pr-description. On GitLab CI and GitHub Actions they default to the merge request or pull request. After a merge, push finds the title of the pull request that merged the commit: on GitHub Actions through the GitHub API (expose GITHUB_TOKEN to the step; a failure is ignored), on GitLab from the merge commit.
Waiting
--poll-interval (2 seconds) and --timeout (10 minutes).
Links
--app-url or CASSIS_APP_URL sets the web app’s address for the links to filed issues, when it is not served from the API host.
JSON
--json prints 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

Codedbt pushdbt check
0Accepted as the baseline, or kept behind a newer uploadChecked, with or without findings
1Rejected: an invalid file, an unsupported dbt version, or no relation matches the project’s data sourceRejected: an invalid file, or no baseline yet (run dbt push on the production branch first)
2Usage error: no manifest.json, no commit, or a file over the size limitSame
3Transport error, or Cassis failed while processing the upload: push againSame

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.