Configuring Workflow Inputs
The frontend of Harness IDP workflows can be customized to accept different input fields based on specific requirements. It acts as the entry point where users provide details to run workflows using predefined input parameters.
A well-structured frontend improves the user experience by ensuring the right input types and validations. There are various input types and validation use cases. Let’s explore them in detail.
Defining Workflow Inputs
You can define workflow inputs using the spec.parameters
property in your workflow.yaml
. Parameters are specified at the beginning of a workflow YAML file and define the inputs required from the user. These inputs allow users to pass values—such as repository names, versions, or other configurable items—that can be referenced throughout the workflow.
YAML Syntax
Example YAML
# Example of defining parameters
parameters:
- title: Project Configuration
properties:
projectName:
title: Project Name
type: string
description: The name of the new project
githubRepo:
title: GitHub Repository
type: string
description: The GitHub repository where the project will be initialized
environment:
title: Deployment Environment
type: string
enum:
- dev
- staging
- production
description: The environment for deployment
YAML Breakdown
-
parameters
: This key holds an array of parameter definitions. Each parameter is defined as an object that specifies its title, type, and additional details, such as whether it is required or has specific options like enums (choices).title
: The title of the input form displayed in the frontend when prompting the user for input.properties
: Defines individual input fields, where each property corresponds to a separate and specific input field.title
: The label or name for the parameter input field, shown in the frontend.type
: The expected data type of the input. Common types include:string
: A free-text input field.number
: Accepts numeric values.boolean
: A true/false checkbox.
description
: A brief explanation of the parameter's purpose.required
: Indicates whether the input is mandatory.enum
: A list of predefined options the user can choose from, useful for fields like deployment environments (e.g., dev, staging, production).ui:widget
: Specifies the UI element used for input (e.g., text field, dropdown).
Input Types
Here are the different ways to design form inputs in IDP workflows:
Static Inputs
Static inputs are fields where users manually enter their details as defined in the frontend. These inputs come in various types:
string
– Single-line text inputtextarea
– Multi-line text inputnumber
– Numeric inputboolean
– Checkbox (true/false)enum
– Dropdown selection from a predefined listarray
– List of values (e.g., strings, numbers)object
– Key-value pair inputspassword
– Masked input for sensitive values
Dynamic Inputs
Dynamic inputs are fields that automatically retrieve data from external sources or runtime context, eliminating the need for manual entry.
-
Entity Picker
– Select an entity from the catalogOwner Picker
– Select a user or groupRepository Picker
– Choose a repository from a version control provider
-
API Based Dynamic Workflow UI Picker
Dynamic API Picker
– Fetch options dynamically via an API requestAutocomplete Fields
– Suggestions based on previous inputs or external data fetched using Dynamic API Picker.
Workflows Playground
The Workflows Playground does not render accurate previews for advanced user inputs and complex use cases such as conditional fields or complex input formats. It is recommended to use the editor only for lightweight input previews. For accurate validation of advanced inputs, test the Workflow Form Inputs in an actual Workflow execution.
Harness IDP also provides a built-in editor to help you build your Workflow's Frontend. It offers a real-time preview of the corresponding UI based on the YAML definition. Here, you can create a new workflow or edit an existing one. '
Note: The editor is for preview purposes only; changes made here cannot be saved. Once you have tested the modifications, you must manually copy the updated YAML and add it to the Workflow definition YAML stored in your Git provider.
For more information on accessing the Workflow Playground, check out the details here.
Input Examples
Simple text input
Basic Input
Basic form inputs allow users to enter structured data while ensuring it meets predefined rules. You can enforce limits such as character counts, patterns, and UI hints to guide users in filling out the form accurately.
Example workflow.yaml
This example demonstrates a simple text input field with:
- A
title
anddescription
for clarity. - A maximum length constraint (
maxLength: 8
). - A regex pattern validation (
pattern
) to enforce naming rules. - UI enhancements like autofocus and helper text.
Example YAML
parameters:
- title: Fill in some steps
properties:
name:
title: Simple text input
type: string
description: Description about input
maxLength: 8
pattern: "^([a-zA-Z][a-zA-Z0-9]*)(-[a-zA-Z0-9]+)*$"
ui:autofocus: true
ui:help: "Hint: additional description..."
Multi-line text input
Multi-line text inputs are useful for capturing larger blocks of text, such as descriptions, configuration snippets, or scripts. This example demonstrates how to use a textarea widget to enable multi-line input, with additional UI options for better usability.
Example workflows.yaml
This configuration includes:
- A textarea widget (
ui:widget: textarea
) for multi-line input. - Custom row height (
ui:options: rows: 10
) for better visibility. - A placeholder example showcasing a shell script.
- Helper text (
ui:help
) to guide users.
Example YAML
parameters:
- title: Fill in some steps
properties:
multiline:
title: Text area input
type: string
description: Insert your multi line string
ui:widget: textarea
ui:options:
rows: 10
ui:help: 'Hint: Make it strong!'
ui:placeholder: |
a=50
b=60
sh << word
> echo "Equation: a + b = 110"
> echo $(($a + $b))
> echo ""
> echo "Inside Here Tag, Assignment c=110"
> c=`expr $a + $b`
> echo $c
> word
Array options
Array inputs allow users to provide multiple values, either as strings, numbers, or complex objects. These can be structured to ensure uniqueness, predefined options, or flexible custom objects.
Array with strings
You can add an array to the workflow with string values, allowing users to select one option when filling out the workflow.
Example workflows.yaml
Array with distinct values
Values mentioned under enum
needs to be distinct, duplicate values aren't allowed under enum
.
Example YAML
parameters:
- title: Fill in some steps
required:
- name
properties:
name:
title: Name
type: string
description: Unique name of the component
volume:
title: Volume Type
type: string
description: The volume type to be used
default: 'Cold HDD'
enum:
- 'Provisioned IOPS'
- 'Cold HDD'
- 'Throughput Optimized HDD'
- 'Magnetic'
Array with duplicate values
Allows multiple values, including duplicates, by using enumNames
to provide user-friendly labels.
Example YAML
parameters:
- title: Fill in some steps
properties:
volume_type:
title: Volume Type
type: string
description: The volume type to be used
default: gp2
enum:
- gp2
- gp3
- io1
- io2
- sc1
- st1
- standard
enumNames:
- 'General Purpose SSD (gp2)'
- 'General Purpose SSD (gp3)'
- 'Provisioned IOPS (io1)'
- 'Provisioned IOPS (io2)'
- 'Cold HDD (sc1)'
- 'Throughput Optimized HDD (st1)'
- 'Magnetic (standard)'
A multiple choices list with checkboxes
Users can select multiple predefined values from checkboxes.
Key Features:
- Supports multiple selections
- Uses checkbox UI for easy selection
- Ensures unique selections with
uniqueItems: true
Example workflows.yaml
Example YAML
parameters:
- title: Fill in some steps
properties:
name:
title: Select environments
type: array
items:
type: string
enum:
- production
- staging
- development
uniqueItems: true
ui:widget: checkboxes
Array with Custom Objects
This allows users to enter an array of complex objects, each containing multiple fields. It supports adding, removing, and reordering objects dynamically.
Example workflows.yaml
A user needs to provide a list of configurations, each containing:
- A dropdown selection (
array
) - A boolean flag (
flag
) - A free-text input (
someInput
)
Example YAML
parameters:
- title: Fill in some steps
properties:
arrayObjects:
title: Array with custom objects
type: array
minItems: 0
ui:options:
addable: true
orderable: true
removable: true
items:
type: object
properties:
array:
title: Array string with default value
type: string
default: value3
enum:
- value1
- value2
- value3
flag:
title: Boolean flag
type: boolean
ui:widget: radio
someInput:
title: Simple text input
type: string
Comparison Table of Array Input Types
The table compares array input types based on key features:
- Distinct Values: Dropdowns ensure unique values, checkboxes allow duplicates.
- Duplicate Values: Checkboxes support duplicates, dropdowns do not.
- Multiple Choice: Checkboxes and custom arrays allow multiple selections, dropdowns do not.
- Custom Objects: Only custom object arrays support complex data.
- User-friendly Labels: Checkboxes and custom arrays can have labels, dropdowns cannot.
Feature | Distinct Values | Duplicate Values | Multiple Choice List | Custom Object Array |
---|---|---|---|---|
Dropdown Selection | ✅ | ✅ | ❌ | ❌ |
Checkbox UI | ❌ | ❌ | ✅ | ❌ |
Allows Multiple Selections | ❌ | ❌ | ✅ | ✅ |
Supports Complex Objects | ❌ | ❌ | ❌ | ✅ |
User-friendly Labels (enumNames ) | ❌ | ✅ | ❌ | ✅ |
Pass an Array of Inputs to a Harness Pipeline
Harness Pipelines only support three variable types:
- String
- Number
- Secret
This means that arrays cannot be directly passed as pipeline inputs. Instead, if you need to pass multiple values, you should convert the array into a comma-separated string using join in Nunjucks.
-
Use Case: You want users to select multiple values from a
enum
list, and then pass those values as a single comma-separated string into the Harness Pipeline’sinputset
. -
How It Works:
- User selects multiple options from an enum list (
Option1
,Option2
,Option3
). - The selected options are joined into a single string using
parameters.exampleVar.join(',')
. - The pipeline receives the values as a single string, ensuring compatibility with Harness’ input format.
- title: Pass Variables Here
properties:
exampleVar:
title: Select an option
type: array
items:
type: string
enum:
- Option1
- Option2
- Option3
default:
- Option1
ui:
exampleVar:
title: Select Options
multi: true
steps:
- id: trigger
name: Call a harness pipeline, and pass the variables from above
action: trigger:harness-custom-pipeline
input:
url: 'https://app.harness.io/ng/account/*********/home/orgs/default/projects/*************/pipelines/*************/pipeline-studio/?storeType=INLINE'
inputset:
exampleVar: ${{ parameters.exampleVar.join(',') }}
owner: ${{ parameters.owner }}
apikey: ${{ parameters.token }}
Boolean options
Boolean inputs allow users to select between true/false or yes/no values in forms. These inputs are useful for enabling/disabling features, selecting configuration options, and making binary choices.
Basic Boolean (Checkbox Input)
A simple checkbox allows users to toggle a setting on/off.
parameters:
- title: Fill in some steps
properties:
name:
title: Checkbox boolean
type: boolean
Boolean Yes or No options (Radio Button)
Instead of a checkbox, you can use radio buttons for a clearer Yes/No selection.
parameters:
- title: Fill in some steps
properties:
name:
title: Yes or No options
type: boolean
ui:widget: radio
Boolean multiple options
For cases where multiple boolean choices are needed, you can use an array of checkboxes.
Example YAML
parameters:
- title: Fill in some steps
properties:
name:
title: Select features
type: array
items:
type: boolean
enum:
- "Enable scraping"
- "Enable HPA"
- "Enable cache"
uniqueItems: true
ui:widget: checkboxes
When to Use Each Boolean Input Type
Input Type | Best Use Case | Example Scenario |
---|---|---|
Checkbox Boolean | Single feature toggle | Enable/Disable Dark Mode |
Radio Button Boolean | Explicit Yes/No choice | Confirming a deletion |
Multi-Select Boolean | Selecting multiple options | Enable multiple monitoring features |
Workflow UI Pickers
User input is a crucial aspect of Workflows. However, built-in components and fields may not always meet specific requirements, and at times, you may want to enhance the form with more intuitive and tailored inputs.
This is where Workflow UI Pickers come in.
Harness Specific UI Pickers
1. EntityFieldPicker
(Fetch values from catalog)
The EntityFieldPicker
can be used to fetch information for workflows that are already defined in the catalog, such as data under metadata.annotations
.
Only string data type
is supported for the EntityPicker
.
The input props that can be specified under ui:options
for the EntityFieldPicker
field extension.
displayField
This is used to fetch the value from catalog dynamically, corresponding to the key mentioned.
jiraprojectID:
title: Jira Project Key
type: string
description: The key for your JIRA project
ui:field: EntityFieldPicker
ui:displayField: metadata.jiraProjectId
ui:options:
catalogFilter:
kind:
- Component
- Service
In the above example it will fetch all the jiraProjectId
for the software components kind
mentioned under catalogFilter
.
allowArbitraryValues
Whether to allow arbitrary user input. Defaults to true.
allowArbitraryValues
provides input validation when selecting an entity as the values you enter will correspond to a valid entity.
- Adding a valid entity with
allowArbitraryValues
asfalse
entity:
title: Entity
type: string
description: Entity of the component
ui:field: EntityFieldPicker
ui:options:
allowArbitraryValues: false
- Adding an arbitrary entity with
allowArbitraryValues
astrue
(default value)
entity:
title: Entity
type: string
description: Entity of the component
ui:field: EntityFieldPicker
ui:options:
allowArbitraryValues: true
catalogFilter
catalogFilter
supports filtering options by any field(s) of an entity.
- Get all entities of kind
Group
entity:
title: Entity
type: string
description: Entity of the component
ui:field: EntityFieldPicker
ui:options:
catalogFilter:
- kind: Group
- Get entities of kind
Group
and spec.typeteam
entity:
title: Entity
type: string
description: Entity of the component
ui:field: EntityFieldPicker
ui:options:
catalogFilter:
- kind: Group
spec.type: team
defaultKind
The default entity kind.
system:
title: System
type: string
description: System of the component
ui:field: EntityFieldPicker
ui:options:
catalogFilter:
kind: System
defaultKind: System
defaultNamespace
The ID of a namespace that the entity belongs to. The default value is default
.
- Listing all entities in the
default
namespace (default value)
entity:
title: Entity
type: string
description: Entity of the component
ui:field: EntityFieldPicker
ui:options:
defaultNamespace: default
2. HarnessOrgPicker
Fetches all the organization, under the account dynamically.
#Example
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: your-workflow
...
spec:
...
parameters:
- title: Details
properties:
projectId:
title: Project Identifier
description: Harness Project Identifier
type: string
ui:field: HarnessProjectPicker
orgId:
title: Org Identifier
type: string
ui:field: HarnessOrgPicker
...
3. HarnessProjectPicker
Fetches all the Harness project ID, available in the account dynamically
# Example workflow.yaml file
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: your-workflow
...
spec:
...
parameters:
- title: Details
properties:
projectId:
title: Project Identifier
description: Harness Project Identifier
type: string
ui:field: HarnessProjectPicker
4. HarnessAutoOrgPicker
It autopopulates org ID on project selection. So now when you select a project ID as an input the org ID gets selected automatically if required as an input.
- For
HarnessAutoOrgPicker
to work, it is suggested to name the Project Identifier under Properties asprojectId
and using theHarnessProjectPicker
.
# Example workflow.yaml file
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: your-workflow
...
spec:
...
parameters:
- title: Details
properties:
projectId:
title: Project Identifier
description: Harness Project Identifier
type: string
ui:field: HarnessProjectPicker
orgId:
title: Org Identifier
description: Harness org Identifier
type: string
ui:field: HarnessAutoOrgPicker
- In case the properties Project Identifier is named something else other than
projectId
in that case for the Workflow action to function as desired we need to add it as a dependency underprojectPickerRef
# Example workflow.yaml file
properties:
<ANY NAME OTHER THAN projectId>:
title: Project Identifier
description: Harness Project Identifier
type: string
ui:field: HarnessProjectPicker
orgId:
title: Org Identifier
description: Harness org Identifier
type: string
ui:field: HarnessAutoOrgPicker
dependencies:
projectPickerRef:
- 'project_name'
Other UI Pickers
1. OwnerPicker
OwnerPicker
is used for developers to pick a User Group from the list of Groups that exist in the account.
allowArbitraryValues
Whether to allow arbitrary user input. Defaults to true.
allowArbitraryValues
provides input validation when selecting an owner as the values you enter will correspond to a valid owner.
- Adding a valid owner with
allowArbitraryValues
asfalse
owner:
title: Owner
type: string
description: Owner of the component
ui:field: OwnerPicker
ui:options:
allowArbitraryValues: false
- Adding an arbitrary owner with
allowArbitraryValues
astrue
(default value)
owner:
title: Owner
type: string
description: Owner of the component
ui:field: OwnerPicker
ui:options:
allowArbitraryValues: true
catalogFilter
catalogFilter
supports filtering options by any field(s) of an entity.
- Get all entities of kind
Group
owner:
title: Owner
type: string
description: Owner of the component
ui:field: OwnerPicker
ui:options:
catalogFilter:
- kind: Group
- Get entities of kind
Group
and spec.typeteam
owner:
title: Owner
type: string
description: Owner of the component
ui:field: OwnerPicker
ui:options:
catalogFilter:
- kind: Group
spec.type: team
defaultNamespace
The ID of a namespace that the owner belongs to. The default value is default
.
- Listing owners in the
default
namespace (default value)
owner:
title: Owner
type: string
description: Owner of the component
ui:field: OwnerPicker
ui:options:
catalogFilter:
- kind: Group
defaultNamespace: default
- Listing owners in the
payment
namespace
owner:
title: Owner
type: string
description: Owner of the component
ui:field: OwnerPicker
ui:options:
catalogFilter:
- kind: Group
defaultNamespace: payment
2. EntityPicker
Only string data type
is supported for the EntityPicker
.
The input props that can be specified under ui:options
for the EntityPicker
field extension.
allowArbitraryValues
Whether to allow arbitrary user input. Defaults to true.
allowArbitraryValues
provides input validation when selecting an entity as the values you enter will correspond to a valid entity.
- Adding a valid entity with
allowArbitraryValues
asfalse
entity:
title: Entity
type: string
description: Entity of the component
ui:field: EntityPicker
ui:options:
allowArbitraryValues: false
- Adding an arbitrary entity with
allowArbitraryValues
astrue
(default value)
entity:
title: Entity
type: string
description: Entity of the component
ui:field: EntityPicker
ui:options:
allowArbitraryValues: true
catalogFilter
catalogFilter
supports filtering options by any field(s) of an entity.
- Get all entities of kind
Group
entity:
title: Entity
type: string
description: Entity of the component
ui:field: EntityPicker
ui:options:
catalogFilter:
- kind: Group
- Get entities of kind
Group
and spec.typeteam
entity:
title: Entity
type: string
description: Entity of the component
ui:field: EntityPicker
ui:options:
catalogFilter:
- kind: Group
spec.type: team
defaultKind
The default entity kind.
system:
title: System
type: string
description: System of the component
ui:field: EntityPicker
ui:options:
catalogFilter:
kind: System
defaultKind: System
defaultNamespace
The ID of a namespace that the entity belongs to. The default value is default
.
- Listing all entities in the
default
namespace (default value)
entity:
title: Entity
type: string
description: Entity of the component
ui:field: EntityPicker
ui:options:
defaultNamespace: default
3. MultiEntityPicker
The input props that can be specified under ui:options
for the MultiEntityPicker
field extension.
allowArbitraryValues
Whether to allow arbitrary user input. Defaults to true.
allowArbitraryValues
provides input validation when selecting an entity as the values you enter will correspond to a valid entity.
- Adding a valid entity with
allowArbitraryValues
asfalse
entity:
title: Entities
type: array
description: Entities of the component
ui:field: MultiEntityPicker
ui:options:
allowArbitraryValues: false
- Adding an arbitrary entity with
allowArbitraryValues
astrue
(default value)
entity:
title: Entities
type: array
description: Entities of the component
ui:field: MultiEntityPicker
ui:options:
allowArbitraryValues: true
catalogFilter
catalogFilter
supports filtering options by any field(s) of an entity.
- Get all entities of kind
Group
entity:
title: Entities
type: array
description: Entities of the component
ui:field: MultiEntityPicker
ui:options:
catalogFilter:
- kind: Group
- Get entities of kind
Group
and spec.typeteam
entity:
title: Entities
type: array
description: Entities of the component
ui:field: MultiEntityPicker
ui:options:
catalogFilter:
- kind: Group
spec.type: team
defaultKind
The default entity kind.
system:
title: System
type: array
description: Systems of the component
ui:field: MultiEntityPicker
ui:options:
catalogFilter:
kind: System
defaultKind: System
defaultNamespace
The ID of a namespace that the entity belongs to. The default value is default
.
- Listing all entities in the
default
namespace (default value)
entity:
title: Entity
type: array
description: Entities of the component
ui:field: MultiEntityPicker
ui:options:
defaultNamespace: default
- Listing all entities in the
payment
namespace
entity:
title: Entity
type: array
description: Entities of the component
ui:field: MultiEntityPicker
ui:options:
defaultNamespace: payment
Repository Picker
To simplify working with repository providers, we’ve built a custom picker that can be used by overriding the ui:field
option in the uiSchema
for a string
field. Instead of displaying a standard text input, this picker renders a custom component that allows users to easily select a repository provider and enter details like project/owner and repository name.
You can see this in the full example , where it appears as a separate step and looks something like this:
- title: Choose a location
required:
- repoUrl
properties:
repoUrl:
title: Repository Location
type: string
ui:field: RepoUrlPicker
ui:options:
allowedHosts:
- github.com
The allowedHosts
part should be set to where you wish to enable this Workflow
to publish to. And it can be any host that is listed in your integrations
config in app-config.yaml
.
Besides specifying allowedHosts
you can also restrict the Workflow to publish to
repositories owned by specific users/groups/namespaces by setting the allowedOwners
option. With the allowedRepos
option you are able to narrow it down further to a
specific set of repository names. A full example could look like this:
- title: Choose a location
required:
- repoUrl
properties:
repoUrl:
title: Repository Location
type: string
ui:field: RepoUrlPicker
ui:options:
allowedHosts:
- github.com
allowedOwners:
- backstage
- someGithubUser
allowedRepos:
- backstage
For a list of all possible ui:options
input props for RepoUrlPicker
, please visit here.
Using the Users oauth
token
There's a little extra magic that you get out of the box when using the
RepoUrlPicker
as a field input. You can provide some additional options under
ui:options
to allow the RepoUrlPicker
to grab a oauth
token for the user
for the required repository
.
This is great for when you are wanting to create a new repository, or wanting to perform operations on top of an existing repository.
A sample Workflow that takes advantage of this is like so:
Example YAML
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: v1beta3-demo
title: Test Action Workflow
description: Workflows Demo
spec:
owner: backstage/techdocs-core
type: service
parameters:
...
- title: Choose a location
required:
- repoUrl
properties:
repoUrl:
title: Repository Location
type: string
ui:field: RepoUrlPicker
ui:options:
# Here's the option you can pass to the RepoUrlPicker
requestUserCredentials:
secretsKey: USER_OAUTH_TOKEN
additionalScopes:
github:
- workflow
allowedHosts:
- github.com
...
steps:
...
- id: publish
name: Publish
action: publish:github
input:
allowedHosts: ['github.com']
description: This is ${{ parameters.name }}
repoUrl: ${{ parameters.repoUrl }}
# here's where the secret can be used
token: ${{ secrets.USER_OAUTH_TOKEN }}
...
You will see from above that there is an additional requestUserCredentials
object that is passed to the RepoUrlPicker
. This object defines what the
returned secret
should be stored as when accessing using
${{ secrets.secretName }}
, in this case it is USER_OAUTH_TOKEN
. And then you
will see that there is an additional input
field into the publish:github
action called token
, in which you can use the secret
like so:
token: ${{ secrets.USER_OAUTH_TOKEN }}
.
There's also the ability to pass additional scopes when requesting the oauth
token from the user, which you can do on a per-provider basis, in case your Workflow can be published to multiple providers.
Note, that you will need to configure a connector for your source code management (SCM) service to make this feature work.
Conditional Inputs
Workflows support dynamic parameter handling using conditional logic. You can control how inputs are assigned based on specific conditions, allowing for greater flexibility in user selections and workflow execution.
Conditionally set parameters
You can use the if
keyword within a parameter to apply conditional logic using Nunjucks templating. Since the not
keyword is unavailable, use JavaScript-style equality instead.
Example: If parameters.branchName
is set, use its value; otherwise, append a timestamp to a default name,${{ parameters.branchName if parameters.branchName else appendTimestamp("default-branch-name-") }}
These conditionals could be used only under steps
Example YAML
spec:
parameters:
- title: Fill in some steps
properties:
path:
title: path
type: string
steps:
- id: fetch
name: Fetch template
action: fetch:template
input:
url: ${{ parameters.path if parameters.path else '/root' }}
Use parameters as conditional for fields
Example YAML
parameters:
- title: Fill in some steps
properties:
includeName:
title: Include Name?
type: boolean
default: true
dependencies:
includeName:
allOf:
- if:
properties:
includeName:
const: true
then:
properties:
lastName:
title: Last Name
type: string
One Of
: Helps you create a dropdown in the Workflow, where only one of all the options available could be selected.
Example workflows.yaml
Example YAML
dependencies:
technology:
oneOf:
- properties:
technology:
enum:
- java
java version:
type: "string"
enum:
- java8
- java11
All Of
: Helps you create a dropdown in the Workflow, where only all the options available could be selected.
Example workflows.yaml
Example YAML
type: object
allOf:
- properties:
lorem:
type:
- string
- boolean
default: true
- properties:
lorem:
type: boolean
ipsum:
type: string
Any Of
: Helps you to select from multiple properties where both can't be selected together at once.
Example workflows.yaml
Example Workflow Explained
-
Parameters Structure The parameters section includes
age
as an integer anditems
as an array. Each item in the array can contain either afoo
orbar
property, utilizinganyOf
. -
Identification Methods The Workflow allows for two methods of identification using
anyOf
. Users can provide either:
- A first name and last name (defaulting
firstName
to "Chuck"), or - An ID code.
-
Required Fields The
age
field is required, while the fields under the two identification methods are optional but must comply with theanyOf
logic. -
Display Step The steps section includes a
debug:log
action to display the collected information based on the provided input.
Example YAML
type: object
properties:
age:
type: integer
title: Age
items:
type: array
items:
type: object
anyOf:
- properties:
foo:
type: string
- properties:
bar:
type: string
anyOf:
- title: First method of identification
properties:
firstName:
type: string
title: First name
default: Chuck
lastName:
type: string
title: Last name
- title: Second method of identification
properties:
idCode:
type: string
title: ID code
Advanced use-cases
Usage of dependencies and reusable references.
Example YAML
spec:
owner: owner@company.com
type: service
parameters:
- title: Infrastructure Provisioning
type: object
required:
- environment_type
- owner
properties:
owner:
title: Choose an Owner for the Service
type: string
ui:field: OwnerPicker
ui:options:
allowedKinds:
- Group
# This field is hidden but needed to authenticate the request to trigger the pipeline
token:
title: Harness Token
type: string
ui:widget: password
ui:field: HarnessAuthToken
environment_type:
title: environment_type
type: string
description: Name of the environment where you want to provision a resource
enum:
- dev
- staging
- prod
infracomponent:
title: infra component
type: object
properties:
resource_type:
title: resource_type
type: string
description: Name of the resource that you want to provision
enum:
- s3
- vpc
- sns
- glue
- sqs
required:
- resource_type
dependencies:
resource_type:
oneOf:
- properties:
resource_type:
enum:
- s3
- vpc
Operationtype:
$ref: "#/myregion/operation"
myregion:
operation:
title: region
type: object
properties:
ChooseRegion:
type: string
enum:
- Region A
- Region B
- Region C
Example workflows.yaml
The workflow defines an Infrastructure Provisioning setup with parameters, within infracomponent
, the resource_type
field is defined. The dependencies
section ensures that, if resource_type
is either s3
or vpc
, an additional field Operationtype
(referenced from myregion/operation
) is required.
dependencies:
resource_type:
oneOf:
- properties:
resource_type:
enum:
- s3
- vpc
Operationtype:
$ref: "#/myregion/operation"
What Happens Here?
- If a user selects
s3
orvpc
, thenOperationtype
must also be provided. - The
dependencies
field ensuresOperationtype
is only required whenresource_type
iss3
orvpc
. - The use of
$ref: "#/myregion/operation"
allows referencing another part of the YAML file, ensuring DRY (Don't Repeat Yourself) principles. - Users only see the relevant fields based on their selections.
Understanding dependencies usage and indentations
The dependencies
keyword specifies conditional relationships between fields. When a field depends on another, its presence or properties change based on the value of the controlling field.
Structure of dependencies:
dependencies:
controlling_field:
oneOf:
- properties:
controlling_field:
enum:
- option1
dependent_field:
type: string
description: Visible when option1 is selected
required:
- dependent_field
- properties:
controlling_field:
enum:
- option2
another_dependent_field:
type: string
description: Visible when option2 is selected
required:
- another_dependent_field
Things to take care of:
-
Ensure
dependencies
is at the same level asproperties
. -
Inside
oneOf
,allOf
, oranyOf
, indentproperties
andrequired
correctly. -
Each field inside
dependencies
should align with itscontrolling
field.
For more such references and validate your conditional steps take a look at the react-json schema project.
Advanced Input Configurations
Upload a file using Workflows
Workflow supports a limited form of file types as input, in the sense that it will parse the file contents to Workflow inputs as data-urls.
There are 3 types of file upload.
- Single File: There are two formats available
data-url
andfile
. - Multiple Files: Multiple files selectors are supported by defining an
array
of strings havingdata-url
as a format. - Single File with Accept Attribute: You can use the
accept
attribute to specify a filter for what file types the user can upload.
Example YAML
#Example
title: Files
type: object
properties:
file:
type: string
format: data-url
title: Single file
files:
type: array
title: Multiple files
items:
type: string
format: data-url
filesAccept:
type: string
format: data-url
title: Single File with Accept attribute
ui:enableMarkdownInDescription: true
ui:description: Provide the Json File
ui:options:
accept: .json
Hide the uploaded file contents in Workflow review page
When you upload a file in Workflows, you can see the base-64 encoded content of the file on the review page, to hide them you can use ui:backstage
.
...
properties:
uploaded_file:
title: Upload File
type: string
format: data-url
description: Upload a file that will be processed in the workflow
ui:backstage:
review:
show: false
mask: true
...
How to use the contents of the file uploaded
Files uploaded to workflows are automatically encoded in base64 format. To use the contents of an uploaded file, the base64-encoded data must first be decoded. This can be achieved using the Run Step in IDP stage.
- Start with a Run Step in IDP stage, write a script in the step to:
- Extract the base64-encoded content from the uploaded file.
- Decode the content back to its original format.
- Process or utilize the decoded content as needed in the steps that follow.
Without decoding, the uploaded file contents cannot be directly used.
Here's an example harness pipeline that uses PowerShell in run step to decode the content of the file uploaded to Workflows.
Using Secrets
You may want to mark things as secret and make sure that these values are protected and not available through REST endpoints. You can do this by using the built-in ui:field: Secret
and ui:widget: password
.
ui:widget: password
needs to be mentioned under the first page
in-case you have multiple pages.
# example workflow.yaml
...
parameters:
- title: <PAGE-1 TITLE>
properties:
property-1:
title: title-1
type: string
property-2:
title: title-2
token:
title: Harness Token
type: string
ui:widget: password
ui:field: HarnessAuthToken
- title: <PAGE-2 TITLE>
properties:
property-1:
title: title-1
type: string
property-2:
title: title-2
- title: <PAGE-n TITLE>
...
You can define this property as any normal parameter, however the consumption of this parameter will not be available through ${{ parameters.myKey }}
you will instead need to use ${{ secrets.myKey }}
in your workflow.yaml
.
Parameters will be automatically masked in the review step.
Example YAML
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: v1beta3-demo
title: Test Action Workflow
description: Workflows Demo
spec:
owner: backstage/techdocs-core
type: service
parameters:
- title: Authentication
description: Provide authentication for the resource
required:
- username
- password
properties:
username:
type: string
# use the built in Secret field extension
ui:field: Secret
password:
type: string
ui:field: Secret
steps:
- id: setupAuthentication
action: auth:create
input:
# make sure to use ${{ secrets.parameterName }} to reference these values
username: ${{ secrets.username }}
password: ${{ secrets.password }}
Pre-fill workflows with URL Params
We can now automatically load IDP Workflow forms pre-filled using the formData
URL query parameter. e.g.: https://app.harness.io/ng/account/account_id/module/idp/create/templates/default/a-python-lambda?formData=%7B%22project_name%22%3A%22auto%20filled%22%7D
The query parameters ?formData=%7B%22project_name%22%3A%22auto%20filled%22%7
in the end of the URL allow you to automatically fill in values of the form. Please see the below table for explanation of individual tokens in the query param.
Item | Example Value | Explanation |
---|---|---|
formData | formData | Key of the query param.formData object is used to fill out IDP Workflow forms. |
{"key"%3A"value"} | {"title"%3A"Title from query params"} | Value of the query param. A JSON object with invalid URL characters encoded.: encodes to %3A |
Add Read only Fields
Using automatically filled out values is handy when wanting to direct users to use IDP Workflows with known good values. This also allows automation to be constructed around the Workflows, where the automation can provide fully constructed IDP URLs to the user. You can also prevent user from modifying the form values inserted from query params by making the form fields readonly
. See below example of a minimal form which would be filled using query params defined in the above explanation.
Example YAML
## Example Workflow
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: test-workflow-pipeline
title: Test pipeline using Workflows
spec:
owner: name.owner
type: service
parameters:
- title: Repository Name
properties:
project_name:
title: Name your project
ui:readonly: true
type: string
token:
title: Harness Token
type: string
ui:widget: password
ui:field: HarnessAuthToken
steps:
- id: trigger
name: Creating your github repository
action: trigger:harness-custom-pipeline
input:
url: PIPELINE_URL
inputset:
github_org: ${{ parameters.project_name }}
apikey: ${{ parameters.token }}
output:
links:
- title: Pipeline Details
url: ${{ steps.trigger.output.PipelineUrl }}
For Use Cases Not Listed Here
For scenarios not covered in this guide, it is recommended to use the react-jsonschema-form playground to design the UI for input fields. Additionally, Nunjucks serves as the templating engine for Self-Service Workflows.