Ця сторінка ще не перекладена українською. Показано англійську версію. Переглянути англійською

Pipeline v2 Recipes

RAPS Pipeline v2 introduces retry logic, parallel execution, conditional steps, for-each iteration, and expression evaluation. These features let you build robust, production-grade automation pipelines that handle failures gracefully, process files in bulk, and branch based on runtime conditions.

Feature Overview

🔁
Retry
Auto-recover from transient failures
⏱️
Timeout
Per-step time limits
⚡
Parallel
Run steps concurrently
🔀
Conditionals
Branch on expressions
🔄
For-Each
Iterate over values

Retry

Retry automatically re-executes a failed step up to a configurable number of attempts. This is essential for handling transient network errors, API rate limits, and temporary service unavailability.

Basic Retry

# raps-pipeline.yaml
name: upload-with-retry
steps:
  - name: upload-model
    action: object_upload
    params:
      bucket: project-models
      file: building.rvt
    retry:
      max_attempts: 3
      delay: "5s"

Exponential Backoff

For API rate limiting, use exponential backoff to progressively increase the delay between retries:

steps:
  - name: translate-model
    action: translate_start
    params:
      urn: "${{ steps.upload.outputs.urn }}"
      format: svf2
    retry:
      max_attempts: 5
      delay: "2s"
      backoff: "exponential"

With exponential backoff, the delays are 2s, 4s, 8s, 16s, 32s for the five attempts.

Retry with Timeout

Combine retry with a per-step timeout to cap total execution time:

steps:
  - name: translate-and-wait
    action: translate_start
    params:
      urn: "${{ steps.upload.outputs.urn }}"
      format: svf2
      wait: true
    timeout: "10m"
    retry:
      max_attempts: 3
      delay: "10s"
      backoff: "exponential"

If a single attempt exceeds 10 minutes, it is terminated and the next retry begins (subject to the max_attempts limit).

Run It

# Execute with retry logging visible
raps pipeline run raps-pipeline.yaml --verbose

# Dry run to validate retry configuration
raps pipeline run raps-pipeline.yaml --dry-run

Timeout

Set a maximum duration for any step. If the step does not complete within the timeout window, it is cancelled and marked as failed (which may trigger a retry if configured).

Per-Step Timeouts

steps:
  - name: quick-upload
    action: object_upload
    params:
      bucket: fast-bucket
      file: small-model.dwg
    timeout: "2m"

  - name: long-translation
    action: translate_start
    params:
      urn: "${{ steps.quick-upload.outputs.urn }}"
      format: svf2
      wait: true
    timeout: "30m"

Timeout Format

ValueDuration
"30s"30 seconds
"5m"5 minutes
"1h"1 hour
"1h30m"1 hour 30 minutes

Always include the unit suffix. Bare numbers like "30" are not valid.


Parallel Execution

Run multiple independent steps concurrently to reduce total pipeline duration. Parallel steps start at the same time and the pipeline waits for all of them to complete before proceeding.

Basic Parallel

steps:
  - name: create-bucket
    action: bucket_create
    params:
      key: multi-discipline
      policy: persistent

  - name: upload-all
    parallel:
      - name: upload-arch
        action: object_upload
        params:
          bucket: multi-discipline
          file: architectural.rvt
      - name: upload-struct
        action: object_upload
        params:
          bucket: multi-discipline
          file: structural.rvt
      - name: upload-mep
        action: object_upload
        params:
          bucket: multi-discipline
          file: mep.rvt

Parallel Flow

Step 1
create-bucket
↓
Parallel
upload-arch
Parallel
upload-struct
Parallel
upload-mep
↓
Continue
Next sequential step

Parallel Translations with Retry

Combine parallel execution with retry for resilient batch processing:

steps:
  - name: translate-all
    parallel:
      - name: translate-arch
        action: translate_start
        params:
          urn: "${{ steps.upload-arch.outputs.urn }}"
          format: svf2
          wait: true
        timeout: "15m"
        retry:
          max_attempts: 2
          delay: "10s"
      - name: translate-struct
        action: translate_start
        params:
          urn: "${{ steps.upload-struct.outputs.urn }}"
          format: svf2
          wait: true
        timeout: "15m"
        retry:
          max_attempts: 2
          delay: "10s"
      - name: translate-mep
        action: translate_start
        params:
          urn: "${{ steps.upload-mep.outputs.urn }}"
          format: svf2
          wait: true
        timeout: "15m"
        retry:
          max_attempts: 2
          delay: "10s"

Run It

# Parallel steps show interleaved output
raps pipeline run raps-pipeline.yaml --verbose

# Check which parallel step is slowest
raps pipeline run raps-pipeline.yaml --timing

Conditionals

Execute steps only when a condition evaluates to true. Conditions can reference environment variables, step outputs, and step statuses.

Branch-Based Conditions

Deploy only on the main branch:

steps:
  - name: upload-model
    action: object_upload
    params:
      bucket: staging-models
      file: building.rvt

  - name: promote-to-production
    action: object_copy
    params:
      source_bucket: staging-models
      target_bucket: production-models
      key: building.rvt
    when: "env.BRANCH == 'main'"

Status-Based Conditions

Run a cleanup step only after a successful upload:

steps:
  - name: upload
    action: object_upload
    params:
      bucket: project-models
      file: building.rvt

  - name: translate
    action: translate_start
    params:
      urn: "${{ steps.upload.outputs.urn }}"
      format: svf2
    when: "steps.upload.status == 'success'"

  - name: notify-failure
    action: webhook_send
    params:
      url: "${{ env.SLACK_WEBHOOK }}"
      message: "Upload failed for building.rvt"
    when: "steps.upload.status == 'failed'"

Conditional Flow

upload
↓
Condition
upload.status?
success
↓
translate
failed
↓
notify-failure

Output-Based Conditions

Use outputs from a previous step to decide what to do next:

steps:
  - name: check-bucket
    action: bucket_details
    params:
      key: project-models

  - name: create-bucket
    action: bucket_create
    params:
      key: project-models
      policy: persistent
    when: "steps.check-bucket.status == 'failed'"

For-Each

Iterate over a list of values to execute a step multiple times. The for_each field accepts a comma-separated string or a reference to an environment variable containing one.

Iterate Over Files

env:
  FILES: "arch.rvt,struct.rvt,mep.rvt,site.dwg"

steps:
  - name: upload-files
    action: object_upload
    params:
      bucket: project-models
      file: "${{ each.value }}"
    for_each: "env.FILES"
    retry:
      max_attempts: 2
      delay: "3s"

This expands to four upload operations, one per file. Each iteration has access to each.value (the current item) and each.index (the zero-based position).

For-Each with Translation

Upload and translate a dynamic list of models:

env:
  MODELS: "building-a.rvt,building-b.rvt,building-c.rvt"

steps:
  - name: upload-models
    action: object_upload
    params:
      bucket: batch-project
      file: "./models/${{ each.value }}"
    for_each: "env.MODELS"

  - name: translate-models
    action: translate_start
    params:
      urn: "${{ steps.upload-models.outputs[each.index].urn }}"
      format: svf2
      wait: true
    for_each: "env.MODELS"
    timeout: "20m"
    retry:
      max_attempts: 2
      delay: "5s"
      backoff: "exponential"

For-Each with Conditionals

Process files but only translate Revit formats:

env:
  FILES: "model.rvt,drawing.dwg,spec.pdf,layout.rvt"

steps:
  - name: upload-all
    action: object_upload
    params:
      bucket: mixed-assets
      file: "${{ each.value }}"
    for_each: "env.FILES"

  - name: translate-revit
    action: translate_start
    params:
      urn: "${{ steps.upload-all.outputs[each.index].urn }}"
      format: svf2
    for_each: "env.FILES"
    when: "each.value ends_with '.rvt'"

Run It

# For-each iterations show per-item progress
raps pipeline run raps-pipeline.yaml --verbose

# Override the file list at runtime
raps pipeline run raps-pipeline.yaml --set FILES="new-a.rvt,new-b.rvt"

Expressions

Expressions use the ${{ }} syntax to reference environment variables, step outputs, and built-in functions within pipeline YAML files.

Environment Variables

env:
  BUCKET_PREFIX: "myproject"
  REGION: "US"

steps:
  - name: create-bucket
    action: bucket_create
    params:
      key: "${{ env.BUCKET_PREFIX }}-models"
      policy: persistent
      region: "${{ env.REGION }}"

Step Outputs

Reference outputs from previous steps:

steps:
  - name: upload
    action: object_upload
    params:
      bucket: project-models
      file: building.rvt

  - name: translate
    action: translate_start
    params:
      urn: "${{ steps.upload.outputs.urn }}"
      format: svf2

  - name: get-metadata
    action: derivative_metadata
    params:
      urn: "${{ steps.upload.outputs.urn }}"
    when: "steps.translate.status == 'success'"

Built-In Variables

ExpressionDescription
${{ env.VAR }}Environment variable
${{ steps.NAME.outputs.KEY }}Output from a named step
${{ steps.NAME.status }}Step status (success, failed, skipped)
${{ each.value }}Current for-each item
${{ each.index }}Current for-each index (zero-based)
${{ pipeline.name }}Pipeline name
${{ pipeline.run_id }}Unique run identifier

Full Example: Production Pipeline

A complete pipeline that combines all v2 features into a real-world multi-model processing workflow:

name: multi-model-processing
env:
  BUCKET: "prod-models-2026"
  MODELS: "arch.rvt,struct.rvt,mep-hvac.rvt,mep-elec.rvt"
  SLACK_WEBHOOK: "${{ env.SLACK_WEBHOOK_URL }}"

steps:
  # Step 1: Ensure the bucket exists
  - name: ensure-bucket
    action: bucket_create
    params:
      key: "${{ env.BUCKET }}"
      policy: persistent
      region: US
    retry:
      max_attempts: 2
      delay: "3s"

  # Step 2: Upload all models in parallel via for-each
  - name: upload-models
    action: object_upload
    params:
      bucket: "${{ env.BUCKET }}"
      file: "./models/${{ each.value }}"
    for_each: "env.MODELS"
    retry:
      max_attempts: 3
      delay: "5s"
      backoff: "exponential"
    timeout: "5m"

  # Step 3: Translate all models in parallel
  - name: translate-models
    parallel:
      - name: translate-arch
        action: translate_start
        params:
          urn: "${{ steps.upload-models.outputs[0].urn }}"
          format: svf2
          wait: true
        timeout: "20m"
        retry:
          max_attempts: 2
          delay: "10s"
      - name: translate-struct
        action: translate_start
        params:
          urn: "${{ steps.upload-models.outputs[1].urn }}"
          format: svf2
          wait: true
        timeout: "20m"
        retry:
          max_attempts: 2
          delay: "10s"
      - name: translate-mep-hvac
        action: translate_start
        params:
          urn: "${{ steps.upload-models.outputs[2].urn }}"
          format: svf2
          wait: true
        timeout: "20m"
        retry:
          max_attempts: 2
          delay: "10s"
      - name: translate-mep-elec
        action: translate_start
        params:
          urn: "${{ steps.upload-models.outputs[3].urn }}"
          format: svf2
          wait: true
        timeout: "20m"
        retry:
          max_attempts: 2
          delay: "10s"

  # Step 4: Verify all translations (conditional)
  - name: verify-translations
    action: translate_manifest
    params:
      urn: "${{ steps.upload-models.outputs[each.index].urn }}"
    for_each: "env.MODELS"
    when: "steps.translate-models.status == 'success'"

  # Step 5: Notify on failure
  - name: notify-failure
    action: webhook_send
    params:
      url: "${{ env.SLACK_WEBHOOK }}"
      message: "Pipeline failed at step: ${{ pipeline.name }}"
    when: "steps.translate-models.status == 'failed'"

Run the Full Pipeline

# Production run
raps pipeline run multi-model-pipeline.yaml

# Dry run first
raps pipeline run multi-model-pipeline.yaml --dry-run

# Override models list
raps pipeline run multi-model-pipeline.yaml \
  --set MODELS="custom-a.rvt,custom-b.rvt"

# With verbose logging to see retry attempts and parallel progress
raps pipeline run multi-model-pipeline.yaml --verbose

Troubleshooting

Retry exhaustion

If all retry attempts fail, the step is marked as failed and subsequent conditional steps that depend on its success are skipped. Check the verbose output to see individual attempt errors:

raps pipeline run raps-pipeline.yaml --verbose 2>&1 | grep "retry"

Parallel step failures

By default, if one parallel step fails, the other parallel steps continue to completion. The overall parallel group is marked as failed if any member fails. To fail fast (cancel siblings on first failure), add fail_fast: true:

  - name: upload-all
    parallel:
      fail_fast: true
      steps:
        - name: upload-a
          action: object_upload
          params:
            bucket: project
            file: a.rvt
        - name: upload-b
          action: object_upload
          params:
            bucket: project
            file: b.rvt

Expression syntax errors

Expressions must be wrapped in double quotes in YAML. A common mistake is forgetting the quotes:

# Wrong - YAML will parse this as a mapping
urn: ${{ steps.upload.outputs.urn }}

# Correct
urn: "${{ steps.upload.outputs.urn }}"

For-each with empty list

If the for_each value resolves to an empty string, the step is skipped entirely and marked as skipped. This is not an error.


Next Steps