> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/tektoncd/pipeline/llms.txt
> Use this file to discover all available pages before exploring further.

# StepActions

> Reusable and scriptable units of work performed by Steps

A StepAction is a reusable and scriptable unit of work that is performed by a Step. StepActions enable you to share common Step logic across multiple Tasks.

<Note>
  StepActions is a stable feature.
</Note>

## Overview

A Step is not reusable on its own, but the work it performs can be extracted into a StepAction and referenced by multiple Steps. Key concepts:

* Steps are inlined in Task definitions and either perform work directly or reference a StepAction
* A StepAction cannot run standalone (unlike TaskRuns or PipelineRuns)
* A Step has the ability to reference a StepAction for its work
* The Step provides orchestration and context to the StepAction

## Configuring a StepAction

### Required Fields

* `apiVersion` - Specifies the API version (e.g., `tekton.dev/v1alpha1`)
* `kind` - Must be `StepAction`
* `metadata` - Uniquely identifies the StepAction (e.g., `name`)
* `spec` - Configuration for the StepAction
* `image` - Container image to use for the Step

### Optional Fields

* `command` - Cannot be used with `script`
* `args` - Command arguments
* `script` - Cannot be used with `command`
* `env` - Environment variables
* `params` - Parameter declarations
* `results` - Result declarations
* `workingDir` - Working directory
* `securityContext` - Security context
* `volumeMounts` - Volume mounts
* `description` - User-facing description

### Basic Example

```yaml theme={null}
apiVersion: tekton.dev/v1beta1
kind: StepAction
metadata:
  name: example-stepaction-name
spec:
  env:
    - name: HOME
      value: /home
  image: ubuntu
  command: ["ls"]
  args: ["-lh"]
```

## Parameters

StepActions declare parameters just like Tasks, supporting string, array, and object types.

### Declaring Parameters

```yaml theme={null}
apiVersion: tekton.dev/v1beta1
kind: StepAction
metadata:
  name: stepaction-using-params
spec:
  params:
    - name: gitrepo
      type: object
      properties:
        url:
          type: string
        commit:
          type: string
    - name: flags
      type: array
    - name: outputPath
      type: string
      default: "/workspace"
  image: some-git-image
  args: [
    "-url=$(params.gitrepo.url)",
    "-revision=$(params.gitrepo.commit)",
    "-output=$(params.outputPath)",
    "$(params.flags[*])",
  ]
```

<Warning>
  Parameters cannot be directly used in `script` in StepActions. This prevents shell injection attacks. Instead, pass params to environment variables and reference them in scripts.
</Warning>

### Passing Parameters to StepActions

Steps provide parameter values to StepActions:

```yaml theme={null}
apiVersion: tekton.dev/v1
kind: Task
metadata:
  name: step-action
spec:
  params:
    - name: param-for-step-action
      description: "this is a param that the step action needs."
  steps:
    - name: action-runner
      ref:
        name: step-action
      params:
        - name: step-action-param
          value: $(params.param-for-step-action)
```

<Note>
  If a Step declares params for an inlined Step (not referencing a StepAction), it will cause a validation error.
</Note>

### Parameter Substitution Order

When applying parameters to a StepAction, substitutions occur in this order:

1. TaskRun parameter values in step parameters
2. Step-provided parameter values
3. Default values that reference other parameters
4. Simple default values
5. Step result references

## Results

StepActions can declare and emit results.

### Declaring Results

```yaml theme={null}
apiVersion: tekton.dev/v1alpha1
kind: StepAction
metadata:
  name: stepaction-declaring-results
spec:
  results:
    - name: current-date-unix-timestamp
      description: The current date in unix timestamp format
    - name: current-date-human-readable
      description: The current date in human readable format
  image: bash:latest
  script: |
    #!/usr/bin/env bash
    date +%s | tee $(step.results.current-date-unix-timestamp.path)
    date | tee $(step.results.current-date-human-readable.path)
```

<Note>
  StepActions should emit results to `$(step.results.<resultName>.path)` rather than `$(results.<resultName>.path)` to avoid name collisions when multiple StepActions are used in the same Task.
</Note>

### Fetching Results from StepActions

Tasks fetch StepAction results using the `value` field in Task results:

```yaml theme={null}
apiVersion: tekton.dev/v1
kind: Task
metadata:
  name: task-fetching-results
spec:
  results:
    - name: git-url
      description: "url of git repo"
      value: $(steps.git-clone.results.url)
    - name: registry-url
      description: "url of docker registry"
      value: $(steps.kaniko.results.url)
    - name: digest
      description: "digest of the image"
      value: $(steps.kaniko.results.digest)
  steps:
    - name: git-clone
      ref:
        name: clone-step-action
    - name: kaniko
      ref:
        name: kaniko-step-action
```

<Warning>
  Results emitted to `$(step.results.<resultName>.path)` are not automatically available as TaskRun results. The Task must explicitly fetch them.
</Warning>

### Passing Results Between Steps

Steps can consume results from previous Steps:

```yaml theme={null}
apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
  name: step-action-run
spec:
  TaskSpec:
    steps:
      - name: inline-step
        results:
          - name: result1
            type: array
          - name: result2
            type: string
          - name: result3
            type: object
            properties:
              IMAGE_URL:
                type: string
              IMAGE_DIGEST:
                type: string
        image: alpine
        script: |
          echo -n "[\"image1\", \"image2\", \"image3\"]" | tee $(step.results.result1.path)
          echo -n "foo" | tee $(step.results.result2.path)
          echo -n "{\"IMAGE_URL\":\"ar.com\", \"IMAGE_DIGEST\":\"sha234\"}" | tee $(step.results.result3.path)
      - name: action-runner
        ref:
          name: step-action
        params:
          - name: param1
            value: $(steps.inline-step.results.result1[*])
          - name: param2
            value: $(steps.inline-step.results.result2)
          - name: param3
            value: $(steps.inline-step.results.result3[*])
```

### Result Reference Syntax

| Result Type | Parameter Type | Syntax                                           | API Fields Required |
| ----------- | -------------- | ------------------------------------------------ | ------------------- |
| string      | string         | `$(steps.<step-name>.results.<result-name>)`     | stable              |
| array       | array          | `$(steps.<step-name>.results.<result-name>[*])`  | alpha or beta       |
| array       | string         | `$(steps.<step-name>.results.<result-name>[i])`  | alpha or beta       |
| object      | string         | `$(tasks.<task-name>.results.<result-name>.key)` | alpha or beta       |

<Note>
  Whole array results (using star notation) cannot be referenced in `script` and `env`. Step results can only be referenced in a Step's/StepAction's `env`, `command`, and `args`.
</Note>

## Working Directory

Declare a working directory for the StepAction:

```yaml theme={null}
apiVersion: tekton.dev/v1alpha1
kind: StepAction
metadata:
  name: example-stepaction-name
spec:
  image: gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:latest
  workingDir: /workspace
  script: |
    # clone the repo
```

### Parameterizing Working Directory

Make the working directory configurable:

```yaml theme={null}
apiVersion: tekton.dev/v1alpha1
kind: StepAction
metadata:
  name: example-stepaction-name
spec:
  image: ubuntu
  params:
    - name: source
      description: "The path to the source code."
  workingDir: $(params.source)
```

## Security Context

Specify a security context for the StepAction:

```yaml theme={null}
apiVersion: tekton.dev/v1alpha1
kind: StepAction
metadata:
  name: example-stepaction-name
spec:
  image: gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:latest
  securityContext:
      runAsUser: 0
  script: |
    # clone the repo
```

<Warning>
  The `securityContext` from StepAction will overwrite the `securityContext` from TaskRun.
</Warning>

## Volume Mounts

Define volume mounts in StepActions. The volume mount `name` MUST be a single parameter reference:

```yaml theme={null}
apiVersion: tekton.dev/v1alpha1
kind: StepAction
metadata:
  name: myStep
spec:
  params:
    - name: registryConfig
    - name: otherConfig
  volumeMounts:
    - name: $(params.registryConfig)
      mountPath: /registry-config
    - name: $(params.otherConfig)
      mountPath: /other-config
  image: ...
  script: ...
```

<Note>
  Valid: `$(params.registryConfig)`
  Invalid: `$(params.registryConfig)-foo` or `"unparametrized-name"`
</Note>

## Description

Add a user-facing description:

```yaml theme={null}
apiVersion: tekton.dev/v1
kind: StepAction
metadata:
  name: myStep
spec:
  description: my step
  params: ...
  volumeMounts: ...
  image: ...
  script: ...
```

## Referencing StepActions

Reference StepActions from Steps using the `ref` field:

```yaml theme={null}
apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
  name: step-action-run
spec:
  taskSpec:
    steps:
      - name: action-runner
        ref:
          name: step-action
```

### Field Restrictions

When a Step references a StepAction, it CANNOT contain:

* `image`
* `command`
* `args`
* `script`
* `env`
* `volumeMounts`

```yaml theme={null}
# This will cause a validation error
apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
  name: step-action-run
spec:
  taskSpec:
    steps:
      - name: action-runner
        ref:
          name: step-action
        image: ubuntu  # ERROR: cannot use image with ref
```

### Allowed Fields with Ref

When referencing a StepAction, a Step CAN contain:

* `computeResources`
* `workspaces` (Isolated workspaces)
* `volumeDevices`
* `imagePullPolicy`
* `onError`
* `stdoutConfig`
* `stderrConfig`
* `securityContext`
* `envFrom`
* `timeout`
* `ref`
* `params`

```yaml theme={null}
apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
  name: step-action-run
spec:
  taskSpec:
    steps:
      - name: action-runner
        ref:
          name: step-action
        params:
          - name: step-action-param
            value: hello
        computeResources:
          requests:
            memory: 1Gi
            cpu: 500m
        timeout: 1h
        onError: continue
```

## Remote StepActions

Reference StepActions from remote locations like Git repositories:

```yaml theme={null}
apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
  generateName: step-action-run-
spec:
  taskSpec:
    steps:
      - name: action-runner
        ref:
          resolver: git
          params:
            - name: url
              value: https://github.com/repo/repo.git
            - name: revision
              value: main
            - name: pathInRepo
              value: remote_step.yaml
```

<Note>
  Support for remote resolvers depends on what Resolvers your cluster operator has installed. The default resolver type can be configured using the `default-resolver-type` field in the `config-defaults` ConfigMap (alpha feature).
</Note>
