Skip to content

Built-in Actions Reference

Actions are the building blocks of workflow automation. They execute when transitions occur, states are entered/exited, or events are triggered.

Action Syntax

Actions are defined in the actions block and referenced by key:

actions:
  notify_team:
    type: notify
    channel: slack:#engineering
    template: transition_alert

transitions:
  - from: review
    to: done
    actions:
      - run: notify_team

Or inline within transitions:

transitions:
  - from: review
    to: done
    actions:
      - notify: slack:#releases
      - webhook: https://api.example.com/deploy

Core Actions

notify

Send notifications to users, roles, or channels.

- type: notify
  channel: slack:#releases        # slack, teams, email, in-app
  recipients:                     # Optional: specific users/roles
    - role: product_owner
    - user: kim@example.com
  template: release_ready         # Template key from templates/
  level: info                     # info, warning, critical
  message: "Issue {{issue.key}} is ready for launch"

Shorthand:

- notify: slack:#releases
- notify: email:team-leads

assign

Assign issues to users or teams with configurable strategies.

- type: assign
  strategy: round_robin           # round_robin, least_loaded, ai_select, specific
  team: engineering
  fallback: unassigned
- type: assign
  strategy: ai_select
  criteria: "Match skills to issue labels"
  pool:
    - role: developer

Shorthand:

- assign: team:triage
- assign: user:kim@example.com

update_fields

Update issue fields with static or interpolated values.

- type: update_fields
  fields:
    priority: high
    due_date: "{{now | plus: '7 days'}}"
    custom_fields:
      reviewed_by: "{{context.user.email}}"

add_labels / remove_labels

Manage issue labels.

- type: add_labels
  labels:
    - approved
    - "release-{{issue.custom_fields.version}}"

- type: remove_labels
  labels:
    - needs-review

set_field

Set a single field value.

- type: set_field
  field: escalated
  value: true

add_comment

Add a comment to the issue programmatically.

- type: add_comment
  body: |
    ## Transition Summary
    Moved to {{issue.status}} by {{context.user.name}}.

    **Next steps:** Review the changes and proceed.

Parameters: | Parameter | Required | Description | |-----------|----------|-------------| | body | Yes | Comment content with variable interpolation |

add_attachment

Attach a file from a URL to the issue.

- type: add_attachment
  url: "https://api.example.com/reports/{{issue.key}}.pdf"
  filename: "report_{{issue.key}}.pdf"    # Optional: custom filename

Parameters: | Parameter | Required | Description | |-----------|----------|-------------| | url | Yes | URL to download the file from (http/https only) | | filename | No | Custom filename (defaults to URL basename) |

Limits: - Maximum file size: 10 MB - Timeout: 30 seconds

get_latest_comment

Retrieve the most recent comment for use in subsequent actions.

- type: get_latest_comment
  store_in: latest_feedback
  filter: by_user                 # Optional: filter by user
  user_email: "{{issue.assignee}}"

# Use in subsequent action
- type: ai_analyze
  prompt: analyze_feedback
  input:
    feedback: "{{context.latest_feedback.body}}"

Parameters: | Parameter | Required | Description | |-----------|----------|-------------| | store_in | Yes | Context key to store the comment (supports nested paths like data.comment) | | filter | No | Filter type: by_user | | user_email | No | Email of user to filter by (required when filter is by_user) |

Stored comment structure:

{
  "id": 123,
  "body": "Comment content...",
  "author_email": "user@example.com",
  "author_name": "User Name",
  "created_at": "2025-01-15T10:30:00Z"
}

Loop Actions

foreach

Iterate over an array and execute nested actions for each item.

- type: foreach
  items: ["dev", "staging", "production"]
  item_var: environment
  max_iterations: 50              # Optional: limit iterations (default: 50)
  actions:
    - type: webhook
      url: "https://deploy.example.com/{{foreach.environment}}"
      body:
        env: "{{foreach.environment}}"
        index: "{{foreach.index}}"

Parameters: | Parameter | Required | Description | |-----------|----------|-------------| | items | Yes | Array of items, JSON string, or comma-separated string | | item_var | No | Variable name for current item (default: item) | | max_iterations | No | Maximum iterations to execute (default: 50) | | actions | Yes | List of actions to execute for each item |

Context variables available in nested actions: | Variable | Description | |----------|-------------| | {{foreach.<item_var>}} | Current item value | | {{foreach.index}} | Current iteration index (0-based) | | {{foreach.first}} | true if first iteration | | {{foreach.last}} | true if last iteration |

Example with dynamic items:

- type: foreach
  items: "{{issue.custom_fields.deploy_targets}}"
  item_var: target
  actions:
    - type: add_comment
      body: "Deploying to {{foreach.target}}..."
    - type: webhook
      url: "https://api.example.com/deploy"
      body:
        target: "{{foreach.target}}"
        issue_key: "{{issue.key}}"

Workflow Actions

workflow_call

Invoke another workflow for orchestration patterns.

- type: workflow_call
  target_workflow: deployment
  target_project: INFRA           # Optional: cross-project
  target_state: pending
  mode: async                     # sync, async
  input:
    approved_by: "{{context.user.email}}"
  on_success:
    transition_to: deployed
  on_failure:
    action: notify
    recipients: [ops-team@example.com]

See Workflow Orchestration for details.

transition

Trigger a state transition programmatically.

- type: transition
  to: blocked
  reason: "Dependency {{issue.links.blocks.first.key}} is unresolved"

Integration Actions

webhook

Make HTTP requests to external services.

- type: webhook
  url: https://api.example.com/deploy
  method: POST
  headers:
    Authorization: "Bearer {{secrets.DEPLOY_TOKEN}}"
    Content-Type: application/json
  body:
    issue_key: "{{issue.key}}"
    version: "{{issue.custom_fields.version}}"
  retry:
    attempts: 3
    backoff: exponential
  on_success:
    - set_field: { field: deployed, value: true }
  on_failure:
    - notify: slack:#ops-alerts

Shorthand:

- webhook: https://api.example.com/hook

extension

Invoke an installed extension action.

- type: extension
  extension: github
  action: create_release
  params:
    tag: "v{{issue.custom_fields.version}}"
    draft: false

Shorthand:

- extension: pagerduty.create_incident
- extension: slack.post_message

AI Actions

ai_generate

Generate content using AI prompts.

- type: ai_generate
  prompt: release_notes           # Prompt key from prompts/
  output_field: custom_fields.release_notes
  model: gemini-2.5-flash         # Optional: override default

ai_analyze

Analyze issues for insights, risks, or categorization.

- type: ai_analyze
  prompt: risk_assessment
  output_field: custom_fields.risk_score
  context:
    include_comments: true
    include_linked_issues: true

ai_suggest

Get AI-powered suggestions for next steps.

- type: ai_suggest
  prompt: next_actions
  present_as: comment             # comment, field, notification

Approval Actions

request_approval

Request approval from specified roles or users.

- type: request_approval
  approvers:
    - role: security_lead
    - role: product_owner
  required: all                   # all, any, count:2
  timeout: 24h
  on_timeout:
    - escalate_approval: { add_approvers: [role: director] }

escalate_approval

Add approvers or escalate pending approvals.

- type: escalate_approval
  add_approvers:
    - role: engineering_manager
  reason: "Escalated due to SLA breach"
  notify: true

SLA Actions

start_sla / pause_sla / resume_sla

Control SLA timers.

- type: start_sla
  sla: response_time

- type: pause_sla
  sla: resolution_time
  reason: "Waiting on customer"

- type: resume_sla
  sla: resolution_time

breach_sla

Manually trigger SLA breach handling.

- type: breach_sla
  sla: response_time
  reason: "No response within SLA window"

Audit Actions

audit_log

Create an explicit audit entry (beyond automatic tracking).

- type: audit_log
  action: manual_override
  details:
    reason: "{{context.user.name}} bypassed approval"
    justification: "{{input.justification}}"

All audit entries are automatically anchored to the blockchain when enabled at the workflow or organization level.

Variable Interpolation

Use {{...}} syntax to interpolate values:

Variable Description
{{issue.id}} Issue ID
{{issue.key}} Issue key (e.g., PROJ-123)
{{issue.title}} Issue title
{{issue.status}} Current status
{{issue.priority}} Priority level
{{issue.assignee}} Assignee email
{{issue.custom_fields.X}} Custom field value
{{context.user.email}} Current user's email
{{context.user.name}} Current user's name
{{context.timestamp}} Action execution time
{{workflow.key}} Workflow key
{{secrets.KEY}} Secret value from vault
{{now}} Current timestamp

Filters

Apply Liquid-style filters:

message: "Due in {{issue.due_date | time_until}}"
title: "{{issue.title | truncate: 50}}"
date: "{{now | plus: '7 days' | date: '%Y-%m-%d'}}"

Conditional Execution

Use when to conditionally execute actions:

actions:
  - type: notify
    channel: slack:#urgent
    when:
      - field: priority
        operator: equals
        value: critical

Error Handling

Configure error handling per action:

- type: webhook
  url: https://api.example.com/deploy
  on_error: continue              # continue, fail, retry
  retry:
    attempts: 3
    backoff: exponential
    max_delay: 60s

See Also