Step Types
Every step is assumed to be R unless stated otherwise. Exactly one step type field must be set per step.
Core
script: – R script
Runs Rscript --no-save --no-restore <path> [args].
- id: extract
script: etl/extract.R
args: ["--dept", "sales"]r_expr: – Inline R
Writes the expression to a temp .R file in the run directory, runs via Rscript.
- id: summarize
r_expr: |
data <- readRDS("data/clean.rds")
cat(sprintf("Rows: %d\n", nrow(data)))
cat("::daggle-output name=row_count::", nrow(data), "\n")command: – Shell
Runs via sh -c. The escape hatch for non-R tasks.
- id: notify
command: echo "Pipeline complete" | mail -s "Done" team@example.comDocuments
quarto: – Quarto render
Runs quarto render <path> [args]. Requires Quarto installed.
- id: report
quarto: reports/dashboard.qmd
args: ["--to", "html"]rmd: – R Markdown
Renders via rmarkdown::render(). Requires the rmarkdown package.
- id: report
rmd: reports/monthly.RmdR package development
test: – Run tests
Runs devtools::test() with structured output. Emits pass/fail/skip counts and coverage as ::daggle-output:: markers. Requires devtools.
- id: test
test: "."check: – R CMD check
Runs rcmdcheck::rcmdcheck(). Emits error/warning/note counts. Requires rcmdcheck.
- id: check
check: "."
error_on: warning # treat check warnings as failuresdocument: – Generate docs
Runs roxygen2::roxygenize(). Requires roxygen2.
- id: docs
document: "."lint: – Lint code
Runs lintr::lint_package(). Emits issue count. Requires lintr.
- id: lint
lint: "."style: – Format code
Runs styler::style_pkg(). Requires styler.
- id: style
style: "."coverage: – Code coverage
Runs covr::package_coverage(). Emits coverage percentage. Requires covr.
- id: coverage
coverage: "."pkgdown: – Package website
Runs pkgdown::build_site(). Requires pkgdown.
- id: site
pkgdown: "."benchmark: – Benchmarks
Runs bench scripts from a directory.
- id: bench
benchmark: benchmarks/revdepcheck: – Reverse dependency checks
Runs revdepcheck::revdep_check(). Requires revdepcheck.
- id: revdep
revdepcheck: "."Environment
renv_restore: – Restore renv
Runs renv::restore() to install packages from renv.lock. Requires renv.
- id: restore
renv_restore: "."install: – Install packages
Installs packages via pak (preferred) or install.packages().
- id: deps
install: "dplyr, ggplot2, tidyr"Deployment
connect: – Posit Connect
Deploys to Posit Connect. Requires rsconnect. See Posit Connect deployment.
- id: deploy
connect:
type: quarto # shiny, quarto, or plumber
path: reports/dashboard.qmd
name: sales-dashboardpin: – Publish via pins
Publishes data or models via pins::pin_write(). Requires pins.
- id: publish
pin:
board: connect # connect, s3, local, azure
name: sales-data
object: output/data.rds
type: rdsvetiver: – MLOps
Model versioning and deployment via vetiver. Requires vetiver.
- id: version-model
vetiver:
action: pin # pin or deploy
model: models/fit.rds
board: connect
name: sales-modelWorkflow
approve: – Approval gate
Pauses execution until a human approves or rejects. See Approval Gates.
- id: review
approve:
message: "Review model metrics before deploying"
timeout: 24hcall: – Sub-DAG
Executes another DAG as a sub-step. See Sub-DAG Composition.
- id: run-etl
call:
dag: daily-etl
params:
dept: "{{ .Params.department }}"targets: – Targets pipeline
Runs targets::tar_make(). Requires targets.
- id: pipeline
targets: "."shinytest: – Shiny app tests
Runs shinytest2::test_app(). Requires shinytest2.
- id: app-test
shinytest: app/validate: – Data validation
Runs a validation R script via Rscript.
- id: validate
validate: scripts/validate_data.RData sources
database: – SQL query
Runs a SQL query via R DBI and writes the result set to disk. Replaces the common DBI + dbGetQuery + write.csv boilerplate.
- id: pull_orders
database:
driver: postgres # postgres | mysql | mariadb | sqlite | duckdb | odbc
params:
dbname: analytics
host: ${env:PGHOST}
user: ${env:PGUSER}
password: ${env:PGPASSWORD}
query: |
SELECT * FROM orders
WHERE created_at >= now() - interval '7 days'
output: data/orders.csv| Field | Required | Description |
|---|---|---|
driver |
yes | Database driver. Maps to RPostgres, RMariaDB, RSQLite, duckdb, or odbc |
params |
no | Named args passed to DBI::dbConnect() (e.g. dbname, host, user, password) |
query |
either | Inline SQL query. Mutually exclusive with query_file |
query_file |
either | Path to a .sql file, relative to workdir |
output |
yes | Output path. Format inferred from the extension: .csv, .tsv, .rds, .parquet, .feather |
The row count is emitted as ::daggle-output name=row_count::<n>:: for downstream steps.
Notifications
email: – Send email
Sends an email via a named SMTP channel defined in config.yaml. Uses Go’s net/smtp directly — no R required.
- id: send_report
email:
channel: team_smtp # SMTP channel name in config.yaml
subject: "Weekly dashboard — {{.Today}}"
body: |
Hi team,
The weekly dashboard and summary are attached.
attach:
- reports/dashboard.html
- data/summary.csv| Field | Required | Description |
|---|---|---|
channel |
yes | Name of a smtp-type channel in config.yaml |
subject |
yes | Email subject |
body |
either | Inline plain-text body (mutually exclusive with body_file) |
body_file |
either | Path to body file |
from |
no | Sender address (overrides channel’s smtp_from) |
to |
no | List of recipients (overrides channel’s smtp_to) |
cc |
no | CC recipients |
bcc |
no | BCC recipients (not shown in headers) |
attach |
no | Files to attach (paths relative to workdir) |
Attachments are base64-encoded with their MIME type inferred from the file extension. Output recipients holds the total envelope size (to + cc + bcc).
Isolation
docker: – Containerized step
Runs a command inside a Docker container. Useful for isolating different R versions, Bioconductor dependencies, or system libraries (GDAL, PROJ, CUDA).
- id: bio_pipeline
docker:
image: bioconductor/bioconductor_docker:3.18
command: Rscript /work/scripts/analyze.R
volumes:
- ./scripts:/work/scripts:ro
- ./data:/work/data
env:
PROJECT_ID: "{{.Params.project_id}}"
workdir: /work
pull: missing # always | missing | never| Field | Required | Description |
|---|---|---|
image |
yes | Container image to run |
command |
either | Shell command inside the container (run via sh -c). One of command or entrypoint must be set |
entrypoint |
either | Override the image entrypoint |
volumes |
no | Bind mounts in host:container[:ro] form |
env |
no | Environment variables passed via -e |
workdir |
no | Working directory inside the container |
network |
no | Docker network (host, bridge, none, or a named network) |
user |
no | uid[:gid] to run as |
pull |
no | Pull policy: always, missing (default), never |
The docker run --rm ... subprocess is supervised like any other step — timeouts, retries, and signal handling apply uniformly. Logs are captured to the run directory exactly like command: steps.
Missing packages
All R step types check for their required package at runtime. If a package is missing, the step fails with a clear message:
step "test" requires the devtools package. Install with: install.packages("devtools")