Webhook icon
WorkingDirectory icon
Commands icon
Docker icon
SQLMeshCLI icon
Script icon
Switch icon
SlackIncomingWebhook icon
Fail icon
Log icon

SQLMesh Model Unit Test & Breaking Change Gate

Gate SQLMesh pull requests by running model unit tests, detecting unapproved breaking changes, and building virtual preview environments.

Categories
Data

Automate SQLMesh model unit testing, plan-diff breaking change classification, and virtual preview environment verification with Kestra orchestration. Data transformation pull requests frequently introduce logic regressions, rounding discrepancies, or breaking column mutations that break executive dashboards and downstream machine learning features.

SQLMesh provides native unit testing against fixtures and virtual data environments that update pointers without rebuilding physical data. However, orchestrating these checks within CI/CD requires coordinating test execution, capturing plan diffs, enforcing governance against breaking changes, and notifying data teams with actionable remediation context.

This blueprint extracts the uploaded project, executes sqlmesh test against the project's own fixtures in tests/, builds the target virtual environment with sqlmesh plan, classifies the resulting diff into Direct Breaking, Indirect Breaking, or non-breaking changes, sends formatted Slack alerts, and gates downstream warehouse promotions.

How it works

  1. pull_request_webhook initiates the workflow when a CI system POSTs an uploaded project archive.
  2. run_model_gate (io.kestra.plugin.core.flow.WorkingDirectory) extracts the archive once into ./project so every subsequent task operates on the exact same checkout:
    • run_sqlmesh_unit_tests (io.kestra.plugin.sqlmesh.cli.SQLMeshCLI) runs sqlmesh test, capturing test_results.log and test_status.json.
    • evaluate_plan_changes (io.kestra.plugin.sqlmesh.cli.SQLMeshCLI) runs sqlmesh plan <target_environment> --auto-apply --no-prompts, then parses the plan's stdout for Directly Modified: ... (Breaking) and (Indirect Breaking) markers into plan_classification.json.
  3. parse_gate_verdict (io.kestra.plugin.scripts.python.Script) synthesizes test results and plan classification into gate_summary.json with a tri-state verdict (TESTS_FAILED, UNAPPROVED_BREAKING_CHANGE, or GATE_PASSED).
  4. route_gate_verdict (io.kestra.plugin.core.flow.Switch) routes execution:
    • TESTS_FAILED: alert_test_failure posts a Slack alert and fail_on_test_regression (io.kestra.plugin.core.execution.Fail) halts execution.
    • UNAPPROVED_BREAKING_CHANGE: alert_unapproved_breaking notifies governance channels and fail_on_breaking_schema halts the gate unless allow_breaking_changes is enabled.
    • GATE_PASSED: log_preview_ready logs confirmation that the virtual preview environment is verified.

What you get

  • Regression prevention by running your project's real sqlmesh test suite against its own fixtures, not a synthetic demo.
  • Accurate breaking-change detection parsed from SQLMesh's actual plan output markers ((Breaking) for direct changes, (Indirect Breaking) for downstream ones).
  • Zero warehouse rebuild overhead by leveraging SQLMesh virtual data environments and view pointer swaps.
  • Instant Slack alerts directing analytics engineers to failing test assertions and breaking model definitions.
  • Gated CI/CD validation preventing broken SQL transformations from reaching production data models.

Who it's for

  • Analytics Engineers maintaining SQLMesh data transformation projects.
  • Data Platform Engineers building automated CI/CD deployment gates for Snowflake, BigQuery, Databricks, or DuckDB.
  • Data Governance Leads enforcing schema contract stability and breaking change approval workflows.

Why orchestrate this with Kestra

Running SQLMesh inside standard CI scripts often leads to lost test logs, opaque failure exits, uncoordinated Slack messaging, and difficulties managing warehouse credentials across teams.

Orchestrating with Kestra centralizes warehouse secrets, executes containerized SQLMesh workflows with built-in retries, captures persistent execution artifacts (test_results.log, plan_output.txt), and routes deployment gates through declarative YAML flow control.

Prerequisites

  • A Kestra instance with access to run container tasks via Docker.
  • A SQLMesh project archive (.tar.gz, .tgz, or .zip) containing config.yaml, models/, and tests/.
  • A Slack Incoming Webhook URL for alerting on test failures and breaking changes.
  • (Optional) A target data warehouse (DuckDB, Snowflake, BigQuery, PostgreSQL) configured in SQLMesh.

Secrets

  • SLACK_WEBHOOK_URL: Slack Incoming Webhook URL used to dispatch test regressions and breaking change alerts.
  • SQLMESH_GATE_WEBHOOK_KEY: Secret authentication key securing the incoming CI/CD webhook trigger endpoint.

Quick start

  1. Configure the two required secrets in your Kestra namespace: SLACK_WEBHOOK_URL and SQLMESH_GATE_WEBHOOK_KEY.
  2. Package your SQLMesh project into a .tar.gz or .zip archive, including config.yaml, models/, and tests/.
  3. Execute the workflow manually, uploading the archive to project_bundle.
  4. Verify scan logs, review the generated gate_summary.json, and inspect Slack notifications.
  5. Enable pull_request_webhook and connect your CI/CD repository webhook to POST the project archive on pull request creation or update.

How to extend

  • Automated PR Commenting: Pair with io.kestra.plugin.github.issues.Comment to post the SQLMesh plan diff and test results directly as a markdown comment on GitHub pull requests.
  • Production Promotion Swap: Chain this gate into a downstream production promotion task (sqlmesh plan prod --auto-apply) that triggers only after the unit tests pass and no unapproved breaking changes are present.
  • Data Warehouse Gateway Credentials: Inject database connection credentials for Snowflake, BigQuery, or Postgres via task env mappings and {{ secret('NAME') }}.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.