の /CD で重要なのは 「PR で変更した model だけ」を 「本番と隔離されたスキーマで」ビルド・テストすること。これが Slim CI と呼ばれる仕組みです。本記事では GitHub Actions で構築する手順を中心に。
理想の CI フロー
- 1PR 作成 → Slim CI が自動起動
- 2変更されたモデル + その下流のみをビルド (`state:modified+`)
- 3PR 専用の隔離スキーマ (`pr_42_*` 等) にビルド
- 4テスト実行 → 失敗があれば PR を Block
- 5lint / yamllint / sqlfluff も pass チェック
- 6merge 後、prod に本番ビルド
- 7PR スキーマは 7 日後に自動削除
Slim CI の核:state:modified
manifest.json の差分から「変更model」を特定
Bash
# main ブランチの manifest を artifact として保存しておくdbt run --select state:modified+ --state ./prod-manifest
# state:modified+ = 変更されたモデルとその下流# state:modified = 変更されたモデルだけ# state:modified.body = SQL 本体が変わったもの# state:modified.configs = config 変更GitHub Actions: Slim CI 実装
.github/workflows/dbt-ci.yml
YAML
name: dbt CI
on: pull_request: paths: - 'models/**' - 'macros/**' - 'tests/**' - 'seeds/**' - 'snapshots/**' - 'dbt_project.yml' - 'packages.yml'
jobs: dbt-ci: runs-on: ubuntu-latest env: DBT_PROFILES_DIR: ./.dbt # PR 専用スキーマ名 (PR 番号で隔離) DBT_TARGET_SCHEMA: pr_${{ github.event.pull_request.number }}
steps: - uses: actions/checkout@v4
- name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11'
- name: Install dbt run: pip install dbt-bigquery==1.8.*
- name: Auth to BigQuery uses: google-github-actions/auth@v2 with: credentials_json: ${{ secrets.GCP_SA_KEY }}
- name: dbt deps run: dbt deps
- name: Get prod manifest run: | # 本番ビルド時に保存している manifest を取得 gsutil cp gs://my-bucket/dbt/prod/manifest.json ./prod-manifest/manifest.json
- name: dbt build (Slim CI) run: | dbt build \ --select state:modified+ \ --state ./prod-manifest \ --defer \ --favor-state \ --fail-fast
- name: Cleanup PR schema (always run) if: always() run: | # PR が close したら別の workflow で削除 echo "PR schema: $DBT_TARGET_SCHEMA"--defer の魔法
--defer + --favor-state
`--defer`: 上流モデル(変更してないもの)を 本番テーブルから参照する。これにより PR では「変更モデルだけ」をビルドすればよく、上流フルビルドは不要に。`--favor-state` はそれを更に最適化、状態が変わってない model は本番優先。
本番ビルド (merge 後)
.github/workflows/dbt-prod.yml
YAML
name: dbt prod build
on: push: branches: [main] schedule: - cron: '0 * * * *' # 毎時
jobs: dbt-prod: runs-on: ubuntu-latest env: DBT_TARGET: prod steps: - uses: actions/checkout@v4 - run: pip install dbt-bigquery==1.8.* - run: dbt deps - run: dbt source freshness - run: dbt build --target prod - name: Save manifest for next CI run: | gsutil cp target/manifest.json gs://my-bucket/dbt/prod/manifest.json - name: dbt docs run: | dbt docs generate gsutil -m rsync -d -r target gs://my-docs-bucket/dbtLint / フォーマット
pre-commit + sqlfluff
YAML
# .pre-commit-config.yamlrepos: - repo: https://github.com/sqlfluff/sqlfluff rev: 3.0.0 hooks: - id: sqlfluff-lint args: ['--dialect', 'bigquery', '--config', '.sqlfluff']
- repo: https://github.com/dbt-checkpoint/dbt-checkpoint rev: v2.0.0 hooks: - id: check-model-has-description - id: check-model-has-tests - id: check-source-has-freshnessPR スキーマの自動掃除
PR close 時にクリーンアップ
YAML
name: cleanup-pr-schemaon: pull_request: types: [closed]
jobs: cleanup: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Drop PR schema run: | bq query --use_legacy_sql=false \ "DROP SCHEMA IF EXISTS \`my-project.pr_${{ github.event.number }}\` CASCADE"dbt Cloud の Slim CI
dbt Cloud Team プラン以上には Slim CI が組込み。GitHub/GitLab 連携で PR 作成 → 自動 CI → 結果コメントまで全自動。Cost: $100/seat/月〜。 で楽に設定できるのが強み。
次の話
EP.13 では大規模組織での dbt Mesh によるプロジェクト分割を扱います。
この記事の感想を教えてください
あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。