> For the complete documentation index, see [llms.txt](https://docs.cortex.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.cortex.io/streamline/workflows/workflows-as-code.md).

# Workflows as code

Workflows allow you to run sequential actions and increase efficiency across development workflows. With Workflows as code, you can treat Workflows like other production asset; this feature allows you to manage Workflows through [GitOps](/configure/gitops.md). Each Workflow has its own YAML file.

When GitOps is enabled, changes made to Workflows will appear in [GitOps logs](/configure/gitops/gitops-logs.md).

## Managing Workflows in both GitOps and the Cortex UI

When you enable GitOps editing for Workflows, it only affects Workflows that are backed by a YAML file. You can still create and delete Workflows via the Cortex UI, and you can still edit a Workflow via the UI if it's not managed via GitOps.

### Step 1: Configuring GitOps editing for Workflows

Users with the `Edit Workflows` permission can configure GitOps editing in Cortex.

{% hint style="warning" %}
Enabling GitOps editing for Workflows only affects Workflows backed by a YAML file. You can still create and delete Workflows via the Cortex UI.
{% endhint %}

1. From the main sidebar, click your avatar in the bottom-left corner.
2. Click **Settings**.
3. From the **Settings** menu, locate the **Workspace** section, then click **GitOps**.
4. Select the **Workflows** tab.
5. Toggle on **Enable GitOps for Workflows editing**.
6. Optionally, under **Workflow GitOps repository allowlist**, specify which repositories to import Workflows from. See [configuring an allowlist](/configure/settings/gitops-settings.md#gitops-workflow-settings) for more information.
7. Select the the **Entities** tab.
8. Under **Processing**, toggle on **Cortex YAML processing**.

### Step 2: Creating a YAML file for the Workflow

**Prerequisites**

1. You must have the `Edit Workflows` permission.
2. An existing Workflow. If you haven't yet created a Workflow, refer to [Creating a Workflow](/streamline/workflows/create.md) and [Configuring Workflow settings](/streamline/workflows/configuring-workflow-settings.md).

Workflow YAML files must be stored in their own repository, separate from catalog entities, at the repository's root directly within `.cortex/workflows`.

The Workflow YAML uses the same data structure as [Cortex's Workflow API](/api/readme/workflows.md).

You can create a Workflow configuration from scratch, or you can start in the Cortex UI and export the Workflow to a YAML file.

**To export a Workflow to a YAML file in Cortex**:

1. From the main sidebar, select **Workflows**.
2. Locate the Workflow, then click the **Overflow menu** next to it.<br>

   <div align="left" data-with-frame="true"><figure><img src="/files/j7DJECnmRCQEoHuSGdW1" alt="The &#x27;Overflow menu&#x27; icon next to a Workflow." width="375"><figcaption></figcaption></figure></div>
3. Select **Edit Workflow**.
4. At the top of the Workflow, click the **Overflow menu.**
5. Select **Export Workflow YAML**.<br>

   <div align="left" data-with-frame="true"><figure><img src="/files/NQCHTg7iGD0OIiqHpor2" alt="The &#x27;Export Workflow YAML&#x27; option." width="375"><figcaption></figcaption></figure></div>
6. The YAML is downloaded and saved to your computer.
7. Add the YAML file to your Git repository within `.cortex/workflows`.

#### Example Workflow YAML&#x20;

A **nested form** input is a `NESTED_FORM_FIELD` on a `USER_INPUT` action under `schema.inputs`. When the data type is a single value, the item is described by a nested `element` object: set its `type` (for example, `NUMBER_FIELD`) and, for numbers, a `format` of `INTEGER` or `DECIMAL`, along with optional per-item `min`, `max`, `placeholder`, and `defaultValue`. The field's top-level `itemType` summarizes the item type. The outer `min` and `max` set the number of items the runner can enter ( `min` defaults to 1 and also serves as the default count) while `element.min` and `element.max` bound each individual value.

Other item types use the same structure with a different `element.type` and `itemType`.

**Example YAML (single value, number / integer)**

```yaml
name: Provision replicas
tag: provision-replicas
description: null
isDraft: true
filter:
  type: GLOBAL
isRunnableViaApi: false
actions:
- name: Get deployments
  slug: get-deployments
  schema:
    inputs:
    - name: Replica counts
      description: null
      key: replica-counts
      required: false
      disabled: false
      element:                 # describes each item (present for "Single value")
        name: Replica counts
        description: null
        key: replica-counts
        required: false
        disabled: false
        defaultValue: null
        placeholder: null
        format: INTEGER        # INTEGER or DECIMAL (NUMBER_FIELD only)
        min: null              # per-item minimum value
        max: null              # per-item maximum value
        type: NUMBER_FIELD     # item value type
      min: 1                   # min number of items (element count); also the default count
      max: null                # max number of items (element count)
      itemType: INTEGER        # summary of the item type
      type: NESTED_FORM_FIELD
    inputOverrides: []
    jsValidatorScript: ""
    type: USER_INPUT
  outgoingActions: []
  isRootAction: true
runRestrictionPolicies: []
iconTag: null
variables: []
```

**A note about the example Workflow YAML**

* `itemType` sets the item type. It defaults to `OBJECT`; other values (for example `STRING` or `INTEGER`) make each item a single value.
* With `itemType: OBJECT`, the nested form is a sub-form. Define one or more sub-inputs per row.
* With a single-value `itemType`, the item is described by the nested `element` object—its `type` and type-specific options such as `format` for numbers or `validationRegex` for text. There is no separate `inputs` list on the field.
* `min` and `max` are optional element-count limits and apply to every `itemType`. `min` defaults to 1 and also acts as the default number of rows.
* `name`, `description`, `key`, and `required` apply to the field for every `itemType`. `inputOverrides` and `jsValidatorScript` are set at the `schema` level, not on the field.

**Item type reference**

<table><thead><tr><th width="164.953125">Value type</th><th width="283.5703125">element.type</th><th>itemType</th></tr></thead><tbody><tr><td>Text</td><td><code>INPUT_FIELD</code></td><td><code>STRING</code></td></tr><tr><td>Paragraph</td><td><code>PARAGRAPH_FIELD</code></td><td><code>STRING</code></td></tr><tr><td>Number (Integer)</td><td><code>NUMBER_FIELD</code> + <code>format: INTEGER</code></td><td><code>INTEGER</code></td></tr><tr><td>Number (Decimal)</td><td><code>NUMBER_FIELD</code> + <code>format: DECIMAL</code></td><td><code>DECIMAL</code></td></tr><tr><td>Toggle</td><td><code>TOGGLE_FIELD</code></td><td><code>BOOLEAN</code></td></tr><tr><td>Date</td><td><code>DATE_FIELD</code></td><td><code>STRING</code></td></tr></tbody></table>

`element` also carries type-specific keys, i.e. `NUMBER_FIELD` adds format (`INTEGER`/`DECIMAL`) plus min/max; text types add `validationRegex`. For the default Object data type, the field uses a list of sub-field definitions instead of a single element.

## Editing GitOps-managed Workflows in Cortex

Users with the `Edit Workflows` permission can duplicate and edit Workflows in Cortex.

GitOps-managed Workflows are read-only in the Cortex UI. To modify one, create a duplicate, edit the copy, and use it as your primary Workflow going forward.

The UI displays a link to the Workflow's YAML file in your repository:

<div align="left" data-with-frame="true"><figure><img src="/files/B7afHsf26ch8PWEPiT3O" alt="The &#x27;Repo&#x27; icon in the upper-right corner of a Workflow." width="563"><figcaption></figcaption></figure></div>

1. From the main sidebar, select **Workflows**.
2. Locate the Workflow, then click the **Overflow menu** next to it.
3. Select **Duplicate Workflow**.
4. Click **Duplicate workflow**.\
   The Workflow is duplicated and a copy is added to the main Workflows page.
5. To edit the new Workflow, do one of the following:
   1. Click **Edit Workflow** in the toast notification that appears in the bottom-right corner.
   2. Locate the Workflow, click the **Overflow menu** next to it, then select **Edit Workflow**.
6. Make any necessary changes.
7. Save the Workflow.

A **Git icon** next to a Workflow's name indicates that it's managed via GitOps:

<div align="left" data-with-frame="true"><figure><img src="/files/SRsjuuJ1qYTnEVaaWFoe" alt="The &#x27;Git&#x27; icon next to a Workflow&#x27;s name." width="275"><figcaption></figcaption></figure></div>
