Skip to content

Commit 75bee78

Browse files
committed
Add workflow triggers for downstream orchestration
1 parent 5266e7b commit 75bee78

9 files changed

Lines changed: 653 additions & 34 deletions

File tree

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,23 @@ Repeated setup can be factored into helper workflows and reused with
194194
`run_workflow`, for example a `publish_post_url` workflow that waits for
195195
the tunnel and then writes the derived URL.
196196

197+
Downstream orchestration should usually be declared with workflow
198+
`triggers`, so users can read directly what a successful workflow
199+
causes next:
200+
201+
```toml
202+
[workflow.css]
203+
steps = [
204+
{ action = "run_hook", hook = "build_css" },
205+
]
206+
triggers = ["browser_reload"]
207+
208+
[workflow.browser_reload]
209+
steps = [
210+
{ action = "notify_reload" },
211+
]
212+
```
213+
197214
Workflows can also trigger a generic browser refresh after successful
198215
rebuild/restart steps:
199216

docs/behavior.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Workflows run step by step, in order.
6666

6767
- A step must finish successfully before the next one begins.
6868
- `run_workflow` executes another named workflow inline.
69+
- `triggers` run downstream workflows after the workflow succeeds.
6970
- Recursive workflow graphs are rejected at config-validation time.
7071
- `write_state` renders `{{state_key}}` templates against the current
7172
in-memory session state.
@@ -233,6 +234,7 @@ output-derived updates.
233234
workflow runs triggered by watches or startup execution.
234235
- Nested `run_workflow` calls reuse the same session state without
235236
overwriting the top-level change context.
237+
- Triggered workflows inherit that same top-level change context.
236238

237239
## Shutdown
238240

docs/configuration.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,36 @@ steps = [
293293
]
294294
```
295295

296+
### Workflow triggers
297+
298+
`triggers` declares downstream workflows to run after the workflow's own
299+
`steps` complete successfully.
300+
301+
```toml
302+
[workflow.css]
303+
steps = [
304+
{ action = "run_hook", hook = "build_css" },
305+
]
306+
triggers = ["browser_reload"]
307+
308+
[workflow.browser_reload]
309+
steps = [
310+
{ action = "notify_reload" },
311+
]
312+
```
313+
314+
Use `triggers` for orchestration that should happen after a workflow
315+
finishes. Keep `run_workflow` for inline control flow inside a workflow's
316+
own steps.
317+
318+
Triggered workflows are deduplicated across a single execution. If the
319+
same workflow is reached through two trigger paths, `devloop` runs it
320+
once, from the first path that reaches it.
321+
322+
`devloop` rejects configs where a direct trigger target is also reachable
323+
through a `run_workflow` path in the same execution tree, because that
324+
would make ordering and duplication ambiguous.
325+
296326
### Workflow actions
297327

298328
- `start_process`
@@ -306,6 +336,11 @@ steps = [
306336
- `log`
307337
- `notify_reload`
308338

339+
### Workflow fields
340+
341+
- `steps`: ordered actions to execute for the workflow itself
342+
- `triggers`: downstream workflows to run after `steps` succeed
343+
309344
### `write_state`
310345

311346
```toml
@@ -374,6 +409,11 @@ steps = [
374409
steps = [
375410
{ action = "restart_process", process = "server" },
376411
{ action = "wait_for_process", process = "server" },
412+
]
413+
triggers = ["browser_reload"]
414+
415+
[workflow.browser_reload]
416+
steps = [
377417
{ action = "notify_reload" },
378418
]
379419
```

examples/blog/devloop.toml

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@ workflow = "rust"
1414
paths = ["content/**/*.md", "content/**/*.html"]
1515
workflow = "content"
1616

17-
[process.css_watch]
18-
command = ["tailwindcss", "-i", "tailwind.css", "-o", "content/static/tailwind.css", "--watch=always"]
19-
cwd = "."
20-
autostart = false
17+
[watch.css]
18+
paths = ["tailwind.css"]
19+
workflow = "css"
2120

2221
[process.server]
2322
command = ["cargo", "run"]
@@ -70,10 +69,9 @@ steps = [
7069

7170
[workflow.startup]
7271
steps = [
73-
{ action = "start_process", process = "css_watch" },
72+
{ action = "run_hook", hook = "build_css" },
7473
{ action = "start_process", process = "server" },
7574
{ action = "wait_for_process", process = "server" },
76-
{ action = "run_hook", hook = "build_css" },
7775
{ action = "run_hook", hook = "current_browser_path" },
7876
{ action = "start_process", process = "tunnel" },
7977
{ action = "run_workflow", workflow = "publish_post_url" },
@@ -87,13 +85,24 @@ steps = [
8785
{ action = "run_hook", hook = "current_browser_path" },
8886
{ action = "restart_process", process = "tunnel" },
8987
{ action = "run_workflow", workflow = "publish_post_url" },
90-
{ action = "notify_reload" },
9188
]
89+
triggers = ["browser_reload"]
9290

9391
[workflow.content]
9492
steps = [
9593
{ action = "run_hook", hook = "current_browser_path" },
9694
{ action = "restart_process", process = "tunnel" },
9795
{ action = "run_workflow", workflow = "publish_post_url" },
96+
]
97+
triggers = ["browser_reload"]
98+
99+
[workflow.css]
100+
steps = [
101+
{ action = "run_hook", hook = "build_css" },
102+
]
103+
triggers = ["browser_reload"]
104+
105+
[workflow.browser_reload]
106+
steps = [
98107
{ action = "notify_reload" },
99108
]

src/browser_reload.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ mod tests {
169169
"rust".into(),
170170
WorkflowSpec {
171171
steps: vec![WorkflowStep::NotifyReload],
172+
triggers: vec![],
172173
},
173174
);
174175

0 commit comments

Comments
 (0)