How to Set Up CI/CD Pipelines for dbt with GitHub Actions
Setting up CI/CD pipelines for dbt with GitHub Actions involves creating a workflow file that installs dbt, authenticates to your data warehouse, and executes commands like dbt deps, dbt seed, dbt run, dbt test, and dbt docs generate on every push or pull request.
Automating your dbt (data build tool) workflows ensures that data models are tested and documentation stays current without manual intervention. The DataTalksClub/data-engineering-zoomcamp repository demonstrates this pattern within its analytics engineering module, providing a production-ready blueprint for continuous integration in data pipelines.
Repository Structure and Prerequisites
Before configuring the pipeline, ensure your dbt project follows the standard layout shown in the Zoomcamp materials. The example project resides in 04-analytics-engineering/taxi_rides_ny/ and contains the essential configuration file at [04-analytics-engineering/taxi_rides_ny/dbt_project.yml](https://github.com/DataTalksClub/data-engineering-zoomcamp/blob/main/04-analytics-engineering/taxi_rides_ny/dbt_project.yml). This file defines your project name, target database, and materialization settings that the CI runner will reference.
You must also configure GitHub Secrets to store data warehouse credentials securely. Navigate to your repository Settings and add secrets such as BIGQUERY_KEY or SNOWFLAKE_USER depending on your adapter. Never commit credential files to version control.
Creating the GitHub Actions Workflow
Create a file at .github/workflows/dbt.yml in your repository root. This YAML definition establishes the automated pipeline that runs on Ubuntu latest and triggers on pushes and pull requests to the main branch.
name: dbt CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
dbt:
runs-on: ubuntu-latest
defaults:
run:
working-directory: 04-analytics-engineering/taxi_rides_ny
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dbt (BigQuery adapter)
run: |
python -m pip install --upgrade pip
pip install dbt-core dbt-bigquery
- name: Configure BigQuery credentials
env:
BIGQUERY_KEY: ${{ secrets.BIGQUERY_KEY }}
run: |
echo "$BIGQUERY_KEY" > credentials.json
export GOOGLE_APPLICATION_CREDENTIALS=$PWD/credentials.json
- name: dbt deps
run: dbt deps
- name: dbt seed
run: dbt seed
- name: dbt run
run: dbt run
- name: dbt test
run: dbt test
- name: Generate docs
run: dbt docs generate
- name: Upload dbt artifacts
uses: actions/upload-artifact@v4
with:
name: dbt-target
path: target/
The working-directory directive ensures all dbt commands execute within 04-analytics-engineering/taxi_rides_ny, matching the project structure documented in [4_3_1_dbt_project_structure.md](https://github.com/DataTalksClub/data-engineering-zoomcamp/blob/main/04-analytics-engineering/class_notes/4_3_1_dbt_project_structure.md).
Configuring Data Warehouse Authentication
Authentication happens during the "Configure BigQuery credentials" step. The workflow writes the secret to a temporary JSON file and sets the GOOGLE_APPLICATION_CREDENTIALS environment variable. For Snowflake or Redshift, replace this step with their respective connection methods—such as setting environment variables for SNOWFLAKE_ACCOUNT, SNOWFLAKE_USER, and SNOWFLAKE_PASSWORD from secrets.
This approach keeps credentials out of logs and source code while allowing dbt to connect using standard adapter profiles referenced in dbt_project.yml.
Running the dbt Pipeline
The workflow executes a specific sequence of dbt commands that mirror the local development workflow taught in the Zoomcamp class notes:
dbt deps– Installs packages declared inpackages.ymlas described in [4_5_3_dbt_packages.md](https://github.com/DataTalksClub/data-engineering-zoomcamp/blob/main/04-analytics-engineering/class_notes/4_5_3_dbt_packages.md)dbt seed– Loads CSV seed files documented in [4_4_2_dbt_seeds_and_macros.md](https://github.com/DataTalksClub/data-engineering-zoomcamp/blob/main/04-analytics-engineering/class_notes/4_4_2_dbt_seeds_and_macros.md)dbt run– Builds analytical models per [4_4_1_dbt_models.md](https://github.com/DataTalksClub/data-engineering-zoomcamp/blob/main/04-analytics-engineering/class_notes/4_4_1_dbt_models.md)dbt test– Executes data quality tests outlined in [4_5_2_dbt_tests.md](https://github.com/DataTalksClub/data-engineering-zoomcamp/blob/main/04-analytics-engineering/class_notes/4_5_2_dbt_tests.md)dbt docs generate– Produces the static documentation site
Each command references the exact CLI syntax found in [4_6_1_dbt_commands.md](https://github.com/DataTalksClub/data-engineering-zoomcamp/blob/main/04-analytics-engineering/class_notes/4_6_1_dbt_commands.md). If any step returns a non-zero exit code, the GitHub Actions job fails immediately, blocking the pull request merge until the issue resolves.
Publishing Artifacts and Documentation
After successful execution, the workflow uploads the target/ directory as a downloadable artifact using actions/upload-artifact@v4. This folder contains compiled SQL, run results, and generated documentation—critical for debugging failed runs or auditing compiled logic.
To deploy documentation automatically, uncomment and configure the deployment step in the workflow:
- name: Deploy docs
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: target/
This pushes the generated docs to the gh-pages branch, making your data catalog accessible via GitHub Pages after every successful merge to main.
Summary
- Create a workflow file at
.github/workflows/dbt.ymlto define your CI/CD pipeline for dbt with GitHub Actions. - Set the
working-directoryto your dbt project folder (e.g.,04-analytics-engineering/taxi_rides_ny) to ensure commands execute in the correct context. - Store warehouse credentials in GitHub Secrets and reference them via environment variables to maintain security.
- Execute the standard dbt command sequence:
deps,seed,run,test, anddocs generateto validate every change. - Upload the
target/directory as an artifact to preserve compiled SQL and results for troubleshooting. - Deploy documentation automatically to keep your data catalog synchronized with the latest model definitions.
Frequently Asked Questions
What triggers the dbt CI/CD pipeline in GitHub Actions?
The pipeline triggers on push events to the main branch and pull_request events targeting main. You can modify the on: section in .github/workflows/dbt.yml to include additional branches, tags, or scheduled cron jobs for nightly runs.
How do I handle different data warehouse adapters in the workflow?
Replace the pip install dbt-bigquery line with your specific adapter such as dbt-snowflake or dbt-redshift. Update the authentication step to set the appropriate environment variables or configuration files that your adapter expects, referencing the corresponding secrets stored in GitHub.
Can I run the workflow only when specific files change?
Yes. Add a paths filter to the on: configuration to trigger the workflow only when files within the dbt project directory change. For example, paths: ['04-analytics-engineering/taxi_rides_ny/**', '.github/workflows/dbt.yml'] ensures the pipeline runs only when relevant code or workflow definitions are modified.
What happens if dbt tests fail during the CI run?
If dbt test returns a non-zero exit code, the GitHub Actions job fails immediately and displays a red checkmark on the pull request. This prevents merging broken changes into main. You can review the detailed logs in the Actions tab to identify which specific test failed, or download the artifacts to inspect the target/ directory for compiled SQL and error details.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →