Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ae19637
feat: add action schema v2
yottahmd May 7, 2026
952b39c
refactor: harden action schema v2
yottahmd May 7, 2026
290d0ea
fix: cover remaining action normalizers
yottahmd May 7, 2026
458e397
fix: tighten action edge cases
yottahmd May 7, 2026
f3277df
Merge remote-tracking branch 'origin/main' into codex/action-schema-v2
yottahmd May 7, 2026
37b5f3e
docs: update README for action schema
yottahmd May 7, 2026
808e9ae
fix: apply go fix modernization
yottahmd May 7, 2026
78d1730
fix: avoid duplicate validate file reads
yottahmd May 7, 2026
4781269
fix: address action schema review feedback
yottahmd May 7, 2026
1f8d21b
fix: modernize custom action cycle check
yottahmd May 7, 2026
c874c79
Merge remote-tracking branch 'origin/main' into codex/action-schema-v2
yottahmd May 8, 2026
b690267
fix: align agent prompt with action schema
yottahmd May 8, 2026
ef9c96c
fix: complete action schema editor surfaces
yottahmd May 8, 2026
f4e5732
fix: finish action schema public surfaces
yottahmd May 8, 2026
e6648dc
test: migrate fixtures to action schema
yottahmd May 9, 2026
9e47bf4
docs: update action schema descriptions
yottahmd May 9, 2026
fc2f5be
fix: align editor hints with action schema
yottahmd May 9, 2026
a0a6a41
fix: align action terminology in errors
yottahmd May 9, 2026
2b57897
chore: polish legacy definition wording
yottahmd May 9, 2026
76d66bf
fix: clarify custom action error context
yottahmd May 9, 2026
f804ec1
Merge branch 'main' into codex/action-schema-v2
yottahmd May 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 70 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,23 +145,23 @@ harnesses:

steps:
- id: review_pr
type: harness
command: |
Review the README.md file in ${REPO_URL}.
Write Markdown findings to ${DAG_RUN_ARTIFACTS_DIR}/review.md.
action: harness.run
with:
prompt: |
Review the README.md file in ${REPO_URL}.
Write Markdown findings to ${DAG_RUN_ARTIFACTS_DIR}/review.md.
provider: codex-cli

- id: approval
type: noop
action: noop
approval:
prompt: Review the review.md artifact. Approve to post an issue with the findings, or reject to skip.

- id: post_issue
command: gh issue create --title "Review Findings" --body-file "${DAG_RUN_ARTIFACTS_DIR}/review.md"
run: gh issue create --title "Review Findings" --body-file "${DAG_RUN_ARTIFACTS_DIR}/review.md"
```

This workflow uses the [`harness` step type](https://docs.dagu.sh/step-types/harness#harness) and assumes you have the `codex` CLI installed and configured. It reviews a GitHub repository's README file, generates findings with Codex, and then prompts for manual [approval](https://docs.dagu.sh/writing-workflows/yaml-specification#approval) before posting an issue with the findings. GitHub CLI (`gh`) is used in the final step to create the issue.
This workflow uses the [`harness.run` action](https://docs.dagu.sh/step-types/harness#harness) and assumes you have the `codex` CLI installed and configured. It reviews a GitHub repository's README file, generates findings with Codex, and then prompts for manual [approval](https://docs.dagu.sh/writing-workflows/yaml-specification#approval) before posting an issue with the findings. GitHub CLI (`gh`) is used in the final step to create the issue.

Run the workflow with:

Expand Down Expand Up @@ -304,7 +304,7 @@ params:
- MESSAGE
steps:
- name: hello
command: echo "${MESSAGE}"
run: echo "${MESSAGE}"
`), dagu.WithParams(map[string]string{
"MESSAGE": "hello from the host app",
}))
Expand All @@ -330,8 +330,8 @@ See the [embedded API documentation](https://docs.dagu.sh/embedding/go-api) and
```yaml
type: chain
steps:
- command: echo "Step 1"
- command: echo "Step 2"
- run: echo "Step 1"
- run: echo "Step 2"
```

### Parallel execution with dependencies
Expand All @@ -340,15 +340,15 @@ steps:
type: graph
steps:
- id: extract
command: ./extract.sh
run: ./extract.sh
- id: transform_a
command: ./transform_a.sh
run: ./transform_a.sh
depends: [extract]
- id: transform_b
command: ./transform_b.sh
run: ./transform_b.sh
depends: [extract]
- id: load
command: ./load.sh
run: ./load.sh
depends: [transform_a, transform_b]
```

Expand All @@ -372,52 +372,61 @@ steps:
- name: build
container:
image: node:20-alpine
command: npm run build
run: npm run build
```

### Kubernetes Pod execution

```yaml
steps:
- name: batch-job
type: kubernetes
action: kubernetes.run
with:
namespace: production
image: my-registry/batch-processor:latest
resources:
requests:
cpu: "2"
memory: "4Gi"
command: ./process.sh
command: ./process.sh
```

### SSH remote execution

```yaml
steps:
- name: deploy
type: ssh
action: ssh.run
with:
host: prod-server.example.com
user: deploy
key: ~/.ssh/id_rsa
command: cd /var/www && git pull && systemctl restart app
command: cd /var/www && git pull && systemctl restart app
```

### Sub-DAG composition

```yaml
steps:
- name: extract
call: etl/extract
params: "SOURCE=s3://bucket/data.csv"
action: dag.run
with:
dag: etl/extract
params:
SOURCE: s3://bucket/data.csv
- name: transform
call: etl/transform
params: "INPUT=${extract.outputs.result}"
action: dag.run
with:
dag: etl/transform
params:
INPUT: ${extract.outputs.result}
depends: [extract]
- name: load
call: etl/load
params: "DATA=${transform.outputs.result}"
action: dag.run
with:
dag: etl/load
params:
DATA: ${transform.outputs.result}
depends: [transform]
```

Expand All @@ -426,7 +435,7 @@ steps:
```yaml
steps:
- name: flaky-api-call
command: curl -f https://api.example.com/data
run: curl -f https://api.example.com/data
retry_policy:
limit: 3
interval_sec: 10
Expand All @@ -445,9 +454,9 @@ catchup_window: "5h" # Catch up missed runs when scheduler is down for up
timeout_sec: 3600
handler_on:
failure:
command: notify-team.sh
run: notify-team.sh
exit:
command: cleanup.sh
run: cleanup.sh
```

### Harness step with manual approval
Expand All @@ -465,52 +474,51 @@ harnesses:

steps:
- name: review
type: harness
command: Review the README.md file and write findings to review.md.
action: harness.run
with:
prompt: Review the README.md file and write findings to review.md.
provider: codex-cli

- name: approval
type: noop
action: noop
approval:
prompt: Review the review.md artifact. Approve to post an issue with the findings, or reject to skip.

- name: post_issue
command: gh issue create --title "Review Findings" --body-file "${DAG_RUN_ARTIFACTS_DIR}/review.md"
run: gh issue create --title "Review Findings" --body-file "${DAG_RUN_ARTIFACTS_DIR}/review.md"
```

For more examples, see the [Examples documentation](https://docs.dagu.sh/writing-workflows/examples).

## Built-in and Custom Step Types
## Built-in and Custom Actions

Dagu includes built-in step types that run within the Dagu process (or worker).
Dagu includes built-in actions that run within the Dagu process (or worker). Local shell commands use `run`.

| Step type | Purpose |
| Field / Action | Purpose |
|----------|---------|
| [`shell` / `command`](https://docs.dagu.sh/step-types/shell) | Shell commands and scripts (bash, sh, PowerShell, custom shells) |
| [`docker`](https://docs.dagu.sh/step-types/docker) | Run containers with registry auth, volume mounts, and resource limits |
| [`kubernetes` / `k8s`](https://docs.dagu.sh/step-types/kubernetes) | Execute Kubernetes Jobs with namespace, image, and resource settings |
| [`ssh`](https://docs.dagu.sh/step-types/ssh) | Remote command execution over SSH |
| [`sftp`](https://docs.dagu.sh/step-types/sftp) | File transfer over SFTP |
| [`http`](https://docs.dagu.sh/step-types/http) | HTTP requests with headers, auth, and request bodies |
| [`postgres`](https://docs.dagu.sh/step-types/sql/postgresql) / [`sqlite`](https://docs.dagu.sh/step-types/sql/sqlite) | SQL queries, imports, and exports for PostgreSQL and SQLite |
| [`redis`](https://docs.dagu.sh/step-types/redis) | Redis commands, pipelines, and Lua scripts |
| [`s3`](https://docs.dagu.sh/step-types/s3) | Upload, download, list, and delete S3 objects |
| [`jq`](https://docs.dagu.sh/step-types/jq) | JSON transformation using jq expressions |
| [`archive`](https://docs.dagu.sh/step-types/archive) | Create and extract zip/tar archives |
| [`mail`](https://docs.dagu.sh/step-types/mail) | Send email via SMTP |
| [`template`](https://docs.dagu.sh/step-types/template) | Text generation with template rendering |
| [`router`](https://docs.dagu.sh/step-types/router) | Conditional step routing based on values and patterns |
| [`dag` / `subworkflow` / `call:`](https://docs.dagu.sh/writing-workflows/control-flow) | Invoke another DAG as a sub-workflow with params and dependencies |
| [`harness`](https://docs.dagu.sh/step-types/harness) | Run coding agent CLIs such as Claude Code, Codex, Copilot, OpenCode, and Pi |
| [`agent`](https://docs.dagu.sh/features/agent/step) | Built-in agent step type with tool use |

You can also define your own reusable step types with the top-level `step_types` field. Custom step types expand to built-in step types during DAG load, so you can wrap a common shell, HTTP, SQL, or other step pattern behind a typed interface with validated input.
| [`run:` field](https://docs.dagu.sh/step-types/shell) | Local shell commands and scripts (bash, sh, PowerShell, custom shells) |
| [`docker.run`](https://docs.dagu.sh/step-types/docker) | Run containers with registry auth, volume mounts, and resource limits |
| [`kubernetes.run` / `k8s.run`](https://docs.dagu.sh/step-types/kubernetes) | Execute Kubernetes Jobs with namespace, image, and resource settings |
| [`ssh.run`](https://docs.dagu.sh/step-types/ssh) | Remote command execution over SSH |
| [`sftp.upload` / `sftp.download`](https://docs.dagu.sh/step-types/sftp) | File transfer over SFTP |
| [`http.request`](https://docs.dagu.sh/step-types/http) | HTTP requests with headers, auth, and request bodies |
| [`postgres.query`](https://docs.dagu.sh/step-types/sql/postgresql) / [`sqlite.query`](https://docs.dagu.sh/step-types/sql/sqlite) | SQL queries, imports, and exports for PostgreSQL and SQLite |
| [`redis.<operation>`](https://docs.dagu.sh/step-types/redis) | Redis commands, pipelines, and Lua scripts |
| [`s3.upload` / `s3.download` / `s3.list` / `s3.delete`](https://docs.dagu.sh/step-types/s3) | Upload, download, list, and delete S3 objects |
| [`jq.filter`](https://docs.dagu.sh/step-types/jq) | JSON transformation using jq expressions |
| [`archive.create` / `archive.extract` / `archive.list`](https://docs.dagu.sh/step-types/archive) | Create and extract zip/tar archives |
| [`mail.send`](https://docs.dagu.sh/step-types/mail) | Send email via SMTP |
| [`template.render`](https://docs.dagu.sh/step-types/template) | Text generation with template rendering |
| [`router.route`](https://docs.dagu.sh/step-types/router) | Conditional step routing based on values and patterns |
| [`dag.run`](https://docs.dagu.sh/writing-workflows/control-flow) | Invoke another DAG as a sub-workflow with params and dependencies |
| [`harness.run`](https://docs.dagu.sh/step-types/harness) | Run coding agent CLIs such as Claude Code, Codex, Copilot, OpenCode, and Pi |
| [`agent.run`](https://docs.dagu.sh/features/agent/step) | Built-in agent action with tool use |

You can also define reusable actions with the top-level `actions` field. Custom actions expand to built-in actions during DAG load, so you can wrap a common shell, HTTP, SQL, or other pattern behind a typed interface with validated input.

```yaml
step_types:
actions:
webhook:
type: http
input_schema:
type: object
additionalProperties: false
Expand All @@ -521,21 +529,23 @@ step_types:
text:
type: string
template:
command: POST {{ .input.url }}
action: http.request
with:
method: POST
url: {{ .input.url }}
headers:
Content-Type: application/json
body: |
{"text": {{ json .input.text }}}

steps:
- type: webhook
- action: webhook
with:
url: https://hooks.example.com/ops
text: deploy complete
```

See [Custom Step Types](https://docs.dagu.sh/writing-workflows/custom-step-types) for the feature guide and [YAML Specification](https://docs.dagu.sh/writing-workflows/yaml-specification) for the exact `step_types` and `type` field behavior.
See [Custom Actions](https://docs.dagu.sh/writing-workflows/custom-step-types) for the feature guide and [YAML Specification](https://docs.dagu.sh/writing-workflows/yaml-specification) for the exact `actions`, `action`, and `run` field behavior.

## Security and Access Control

Expand Down Expand Up @@ -760,7 +770,7 @@ Full configuration reference: [docs.dagu.sh/server-admin/reference](https://docs

- [Getting Started](https://docs.dagu.sh/getting-started/installation) — Installation and first workflow
- [Writing Workflows](https://docs.dagu.sh/writing-workflows/examples) — YAML syntax, scheduling, execution control
- [Step Types](https://docs.dagu.sh/step-types/shell) — [Shell](https://docs.dagu.sh/step-types/shell), [Docker](https://docs.dagu.sh/step-types/docker), [Kubernetes](https://docs.dagu.sh/step-types/kubernetes), [HTTP](https://docs.dagu.sh/step-types/http), [SQL](https://docs.dagu.sh/step-types/sql/), [Harness](https://docs.dagu.sh/step-types/harness), [Agent Step](https://docs.dagu.sh/features/agent/step), and [Custom Step Types](https://docs.dagu.sh/writing-workflows/custom-step-types)
- [Actions](https://docs.dagu.sh/step-types/shell) — [Shell](https://docs.dagu.sh/step-types/shell), [Docker](https://docs.dagu.sh/step-types/docker), [Kubernetes](https://docs.dagu.sh/step-types/kubernetes), [HTTP](https://docs.dagu.sh/step-types/http), [SQL](https://docs.dagu.sh/step-types/sql/), [Harness](https://docs.dagu.sh/step-types/harness), [Agent Step](https://docs.dagu.sh/features/agent/step), and [Custom Actions](https://docs.dagu.sh/writing-workflows/custom-step-types)
- [Distributed Execution](https://docs.dagu.sh/server-admin/distributed/) — Coordinator/worker setup
- [Authentication](https://docs.dagu.sh/server-admin/authentication/) — RBAC, OIDC, API keys
- [Git Sync](https://docs.dagu.sh/server-admin/git-sync) — Version-controlled DAG definitions
Expand Down
Loading
Loading