Files
python_example/actions/workflows/timeline_demo.yaml
2026-03-04 13:49:14 -06:00

294 lines
9.3 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Timeline Demo Workflow
# Demonstrates various workflow features and exercises the Timeline DAG visualizer.
#
# This is an action-linked workflow file — action-level metadata (ref, label,
# description, parameters, output, tags) is defined in the companion action
# YAML at actions/timeline_demo.yaml. This file contains only the execution
# graph: version, vars, tasks, and output_map.
#
# Features exercised:
# - Sequential task chains
# - Parallel fan-out (3 branches) and fan-in (merge)
# - with_items expansion with concurrency limiting
# - Failure/error handling paths (succeeded/failed/timed_out transitions)
# - Variable-duration tasks for interesting Gantt chart shapes
# - Publish directives passing data between tasks
# - Custom transition labels and colors via __chart_meta__
# - Retry configuration
# - Timeout handling
#
# Expected timeline shape (approximate):
#
# initialize ─┬─► build_artifacts ──────────────────────┐
# ├─► run_linter ──────────┐ ├─► merge_results ─► process_items(×5) ─► validate ─┬─► finalize_success
# └─► security_scan ───────┘ │ └─► handle_failure ─► finalize_failure
# └────────────────┘
version: "1.0.0"
vars:
build_result: null
lint_result: null
scan_result: null
merged_summary: null
items_processed: 0
validation_passed: false
tasks:
# ── Stage 1: Initialize ──────────────────────────────────────────────
- name: initialize
action: python_example.simulate_work
input:
duration_seconds: 1.0
label: "initialize"
output_data:
item_count: "{{ parameters.item_count }}"
started: true
next:
- when: "{{ succeeded() }}"
publish:
- item_count: "{{ parameters.item_count }}"
do:
- build_artifacts
- run_linter
- security_scan
__chart_meta__:
label: "fan-out"
color: "#6366f1"
- when: "{{ failed() }}"
do:
- finalize_failure
__chart_meta__:
label: "init failed"
color: "#ef4444"
# ── Stage 2a: Build artifacts (longest parallel branch) ──────────────
- name: build_artifacts
action: python_example.simulate_work
input:
duration_seconds: "{{ parameters.build_duration }}"
label: "build"
output_data:
artifact: "app-v1.2.3.tar.gz"
size_mb: 48
retry:
count: 2
delay: 1
backoff: constant
next:
- when: "{{ succeeded() }}"
publish:
- build_result: "{{ result() }}"
do:
- merge_results
__chart_meta__:
label: "build ok"
color: "#22c55e"
- when: "{{ failed() }}"
do:
- handle_failure
__chart_meta__:
label: "build failed"
color: "#ef4444"
# ── Stage 2b: Run linter (medium parallel branch) ────────────────────
- name: run_linter
action: python_example.simulate_work
input:
duration_seconds: "{{ parameters.lint_duration }}"
label: "lint"
output_data:
warnings: 3
errors: 0
files_checked: 42
next:
- when: "{{ succeeded() }}"
publish:
- lint_result: "{{ result() }}"
do:
- merge_results
__chart_meta__:
label: "lint clean"
color: "#22c55e"
- when: "{{ failed() }}"
do:
- handle_failure
__chart_meta__:
label: "lint errors"
color: "#ef4444"
# ── Stage 2c: Security scan (short parallel branch) ──────────────────
- name: security_scan
action: python_example.simulate_work
input:
duration_seconds: "{{ parameters.scan_duration }}"
label: "security-scan"
output_data:
vulnerabilities: 0
packages_scanned: 128
timeout: 30
next:
- when: "{{ succeeded() }}"
publish:
- scan_result: "{{ result() }}"
do:
- merge_results
__chart_meta__:
label: "scan clear"
color: "#22c55e"
- when: "{{ failed() }}"
do:
- handle_failure
__chart_meta__:
label: "scan failed"
color: "#ef4444"
- when: "{{ timed_out() }}"
do:
- handle_failure
__chart_meta__:
label: "scan timed out"
color: "#f97316"
# ── Stage 3: Merge results (join from 3 parallel branches) ──────────
- name: merge_results
action: python_example.simulate_work
join: 3
input:
duration_seconds: 1.5
label: "merge"
output_data:
build: "{{ workflow.build_result }}"
lint: "{{ workflow.lint_result }}"
scan: "{{ workflow.scan_result }}"
next:
- when: "{{ succeeded() }}"
publish:
- merged_summary: "{{ result() }}"
do:
- generate_item_list
__chart_meta__:
label: "merged"
color: "#6366f1"
# ── Stage 4a: Generate the item list for with_items ──────────────────
- name: generate_item_list
action: python_example.list_numbers
input:
n: "{{ parameters.item_count }}"
start: 1
next:
- when: "{{ succeeded() }}"
publish:
- number_list: "{{ result().data.items }}"
do:
- process_items
__chart_meta__:
label: "items ready"
color: "#6366f1"
# ── Stage 4b: Process each item (with_items + concurrency) ──────────
- name: process_items
action: python_example.simulate_work
with_items: "{{ workflow.number_list }}"
concurrency: 3
input:
duration_seconds: "{{ parameters.item_duration }}"
label: "item-{{ item }}"
output_data:
item_number: "{{ item }}"
index: "{{ index }}"
next:
- when: "{{ succeeded() }}"
publish:
- items_processed: "{{ parameters.item_count }}"
do:
- validate
__chart_meta__:
label: "all items done"
color: "#22c55e"
- when: "{{ failed() }}"
do:
- handle_failure
__chart_meta__:
label: "item failed"
color: "#ef4444"
# ── Stage 5: Validate everything ─────────────────────────────────────
- name: validate
action: python_example.simulate_work
input:
duration_seconds: 2.0
label: "validate"
fail: "{{ parameters.fail_validation }}"
fail_after: 1.0
output_data:
checks_passed: 12
checks_total: 12
retry:
count: 1
delay: 2
backoff: constant
next:
- when: "{{ succeeded() }}"
publish:
- validation_passed: true
do:
- finalize_success
__chart_meta__:
label: "valid ✓"
color: "#22c55e"
- when: "{{ failed() }}"
publish:
- validation_passed: false
do:
- handle_failure
__chart_meta__:
label: "invalid ✗"
color: "#ef4444"
# ── Terminal: Success ────────────────────────────────────────────────
- name: finalize_success
action: python_example.simulate_work
input:
duration_seconds: 1.0
label: "finalize-success"
output_data:
status: "success"
items_processed: "{{ workflow.items_processed }}"
validation: "{{ workflow.validation_passed }}"
# ── Error path: Handle failure ───────────────────────────────────────
- name: handle_failure
action: python_example.simulate_work
input:
duration_seconds: 1.5
label: "handle-failure"
output_data:
status: "handling_error"
build: "{{ workflow.build_result }}"
lint: "{{ workflow.lint_result }}"
scan: "{{ workflow.scan_result }}"
next:
- when: "{{ succeeded() }}"
do:
- finalize_failure
__chart_meta__:
label: "error handled"
color: "#f97316"
# ── Terminal: Failure ────────────────────────────────────────────────
- name: finalize_failure
action: python_example.simulate_work
input:
duration_seconds: 0.5
label: "finalize-failure"
output_data:
status: "failed"
items_processed: "{{ workflow.items_processed }}"
validation: "{{ workflow.validation_passed }}"
output_map:
status: "{{ 'success' if workflow.validation_passed else 'failed' }}"
items_processed: "{{ workflow.items_processed }}"
total_duration: "{{ task.finalize_success.result.duration_seconds if workflow.validation_passed else task.finalize_failure.result.duration_seconds }}"