New to Kestra?
Use blueprints to kickstart your first workflows.
Run incremental Dataform models the moment upstream data lands. A Kestra webhook flow refreshes the tagged SQLX slice on BigQuery and reports to Slack.
Incremental models exist to process only new rows, yet most teams still run them on a timer, so freshly landed data waits hours for the next scheduled window. This blueprint inverts that: the ingestion pipeline calls a Kestra webhook the moment its load finishes, and io.kestra.plugin.dataform.cli.DataformCLI immediately runs dataform run --tags incremental against BigQuery. Dataform's incremental table semantics insert only the new rows, the flow completes in minutes, and Slack confirms the marts caught up with the source.
upstream_load_webhook trigger (io.kestra.plugin.core.trigger.Webhook) starts the flow on demand, secured by a webhook key from a secret. The final step of any ingestion pipeline, a dlt load, a Fivetran sync, a custom loader, calls it with one HTTP request.run_incremental_models (io.kestra.plugin.dataform.cli.DataformCLI) loads the project from namespace files, installs the pinned @dataform/core dependency in beforeCommands, and runs dataform run --tags incremental with credentials from inputFiles and GOOGLE_APPLICATION_CREDENTIALS.type: "incremental" in their SQLX config and tagged incremental merge only rows beyond their WHERE watermark, so the run stays fast no matter how large the tables grow.notify posts the completed refresh to Slack, and the errors block posts a distinct alert, an alert that matters more than most, because failing here means landed data is sitting unprocessed.Chaining transformation to ingestion by timing guesses, run dataform an hour after the load usually finishes, breaks the first time the load runs long. Kestra makes the dependency explicit: the webhook is a stable URL any loader can call, every refresh is an execution with logs tied to the load that caused it, and the same flow can grow gates, notifications, and downstream triggers without touching the ingestion side.
incremental in their config blocks.GCP_SERVICE_ACCOUNT_JSON: the service account key JSON, delivered to the task as sa.json.SLACK_WEBHOOK_URL: Slack incoming webhook URL.WEBHOOK_KEY: shared key that authorizes calls to the webhook trigger.GCP_SERVICE_ACCOUNT_JSON, SLACK_WEBHOOK_URL, and WEBHOOK_KEY secrets to your Kestra namespace.{{ trigger.body }} for per-source refreshes.