workflow example
This commit is contained in:
293
actions/workflows/timeline_demo.yaml
Normal file
293
actions/workflows/timeline_demo.yaml
Normal file
@@ -0,0 +1,293 @@
|
||||
# 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 }}"
|
||||
Reference in New Issue
Block a user