Core Concept
DAG Execution
Shiro uses topological sorting to execute workflows as a Directed Acyclic Graph (DAG), automatically determining the optimal execution order.
How It Works
- 1. Parse Dependencies - Shiro reads the
depends_onarray from each step - 2. Build Graph - Creates a directed graph of step dependencies
- 3. Topological Sort - Orders steps so dependencies execute first
- 4. Execute - Runs steps in order, tracking outputs for dependent steps
Example
json
{
"steps": [
{ "id": "checkout", "type": "git.diff", "config": {} },
{ "id": "lint", "type": "shell", "config": {}, "depends_on": ["checkout"] },
{ "id": "test", "type": "shell", "config": {}, "depends_on": ["lint"] },
{ "id": "build", "type": "shell", "config": {}, "depends_on": ["test"] },
{ "id": "deploy", "type": "shell", "config": {}, "depends_on": ["build"] },
{ "id": "notify", "type": "slack.notify", "config": {}, "depends_on": ["deploy"] }
]
}Execution order: checkout → lint → test → build → deploy → notify
Parallel Execution
Steps with no dependencies between them can execute in parallel:
json
{
"steps": [
{ "id": "checkout", "type": "git.diff", "config": {} },
{ "id": "lint", "type": "shell", "config": {}, "depends_on": ["checkout"] },
{ "id": "test-unit", "type": "shell", "config": {}, "depends_on": ["lint"] },
{ "id": "test-integration", "type": "shell", "config": {}, "depends_on": ["lint"] },
{ "id": "build", "type": "shell", "config": {}, "depends_on": ["test-unit", "test-integration"] }
]
}Execution: checkout → lint → (test-unit ∥ test-integration) → build
Rules
- • Workflows must not contain circular dependencies
- • All dependencies must exist as step IDs
- • Steps with no dependencies execute first
- • A step only executes after all its dependencies succeed