Custom actions

Introduction

On top of the default action roster, users can define their own actions in YAML and use them in their pipelines. The actions are run in Docker containers launched from images pulled from the Docker Hub registry. A Docker container acts like a local dev environment with preinstalled operating system, tools, and dependencies. In the container, you can run commands on your repository files, run calls to any publicly available third-party API, and export input data to variables to use them in other actions in the pipeline.

Definition

Custom actions are defined with three elements:

  1. YAML configuration (required). Must be named action.yml.
  2. Icon (optional)
  3. Description (optional)

All three must be uploaded to the default branch of the repository:

  1. The root directory of the repository (single action)
  2. The .buddy/actions directory, with each action in its own subdirectory (multiple actions), for example:
.buddy/actions/myaction-1
.buddy/actions/myaction-2

The folder with the action definition, icon, and description should look like this:

/action.yml
/action.png
/README.md

Once uploaded, Buddy will automatically parse the action and display it at the top of the action list:

Custom actions on action listCustom actions on action list

Added actions become available for all projects in the workspace. However, we do recommend storing your actions in a dedicated repository. This way you can easily track their development history, release updates, and fix issues while keeping them isolated from your source code. You can also share the actions from this repository across several workspaces if required.

Icon

The icon is displayed on the action's tile and configuration screen.

  • name: must be action
  • extension: jpg, jpeg, png, svg
  • size: 40x40 px min., scalable

When no icon is provided, Buddy will use the default system icon for custom actions.

Description

An action can have a description in the form of a README.md file. We recommend uploading such file to your action directory with a description of what the action does and required parameters, commands, and variables. You can also add a changelog with the list of updates to track how your action evolves.

YAML Configuration

Custom actions are defined as code in a similar manner to default Buddy actions. The file with the definition must be named action.yml. In the file, you can configure the following items:

  1. Name
  2. Inputs
  3. Commands to execute (optional)
  4. Filesystem & cache (optional)
  5. Docker image (i.e. run environment)
  6. Outputs (optional)

Example

Here we can see an action with three inputs: user, IP, and password. The inputs are passed as variables to the command. The values are then produced in the action logs with the echo command. The command is run in the Ubuntu environment in the latest version.

name: "My_Action"
inputs:
  user:
    type: TEXT
    required: true
  ip:
    type: TEXT
  password:
    type: PASSWORD
    required: true
execute_commands:
  - echo $user@$ip -p $password
docker_image_name: "ubuntu"
docker_image_tag: "latest"

Name & category

The name of the action must be unique throughout the whole workspace, i.e. cannot be the same as any action name on the default list of actions. If the name is not unique, a parsing error will appear. Underscores are parsed into spacebars by default. For example, an action named "My_Custom_Action" will be displayed as "My Custom Action".

By default, custom actions are added to the Custom / Popular section of the action list. You can define your own categories by adding the category parameter to the YAML file:

name: "My_Custom_Action"
category: "Example Inputs"

Inputs

The inputs let you specify the data that the action requires. You can add single or multi-line text inputs, checkboxes, command fields, selectors, and more.

In this example, we can see two inputs: one is a simple text field for entering the username, the second is a masked input for the password. Both fields are required.

inputs:
  user:
    type: TEXT
    required: true
  password:
    type: PASSWORD
    required: true

Commands

By default, the action runs the commands baked in the Docker image. You can overwrite these commands by adding the execute_commands parameter:

execute_commands:
  - echo $user@$ip -p $password

Filesystem & caching

If your action requires repository files, you need to attach the pipeline filesystem to it, i.e. define the volume_mappings parameter. The filesystem is a directory exclusive to every pipeline. When a pipeline is run, Buddy pulls the repo to the filesystem, allowing you to run commands on the files it contains. The processed files and artifacts stay in the filesystem, available for use by other actions in the pipeline.

volume_mappings:
 - /:/buddy

You can also cache additional directories with the cached_dirs parameter. This feature is useful if your action downloads files on every run – caching them will speed up the execution time.

volume_mappings:
 - /:/buddy
working_directory: "/buddy/example-folder"
cached_dirs:
 - "/cache-local"
 - "/cache-application"

By default:

  1. No filesystem is mounted.
  2. No extra directories (cached_dirs) are cached.
  3. The working directory remains as defined in the Docker image.

Docker image

Custom actions are run in an isolated container launched from an image defined by the user. The Docker image must be stored on the Docker Hub and be publicly available. If your action does not require a specific language and/or framework, we recommend using the official Ubuntu image in the latest version:

docker_image_name: "ubuntu" 
docker_image_tag: "latest"

The image must not have an entrypoint defined, or it will not work. You can clear the entrypoint by adding reset_entrypoint: true to the configuration.

Outputs

When the action is run, the values of the inputs are passed to the container as non-settable environment variables. These variables can be generated in the action with the output parameter:

inputs:
  first_input:
output:
  variables:
    first_input:
      example: "The description of the variable."
      info: "The contents of the tooltip"
      masked: true

A variable can be described with three parameters:

  • masked: hides the value of the variable in the logs
  • example: adds an example/description
  • info: displays a tooltip on mouse hover

The variables can also be exported and used by other actions in the pipeline for the duration of the pipeline run using the export INPUT_NAME command:

execute_commands:
  - export first_input
  - export second_input

Example

Here we have an action with two inputs reproduced into variables. The third variable is created by the action's commands:

name: "Output_Example"
inputs:
  first_input:
    default: "Example text"
  second_input:
    required: true
execute_commands:
  - export first_input
  - export second_input
  - export maskedVar="hidden_value"
docker_image_name: "ubuntu"
docker_image_tag: "latest"
output:
  variables:
    first_input:
      example: "This variable has a default value."
      info: "Tooltip #1"
    second_input:
      example: "This variable is required."
    maskedVar:
      example: "This variable is created by the action and masked."
      info: "Tooltip #3"
      masked: true

Custom action with generated variablesCustom action with generated variables

The output of the action closely follows the descriptions from the screenshot:

Action outputAction output

Tabs

If your custom action has inputs defined, they are displayed in the Setup tab of the action. You can add extra tabs to keep your action clear and organized:

name: "custom_TABS"
execute_commands:
- echo $path_app
- echo $path_docs
tabs:
 AWS:
   aws_integration:
     type: AWS_INTEGRATION
     required: true
 GitHub:
   gh_integration:
     type: GITHUB_INTEGRATION
     required: true
 Filesystem:
   path_app:
     name: "App Path"
     type: FILESYSTEM_PATH
     required: true
   path_docs:
     name: "Documentation Path"
     type: FILESYSTEM_PATH
     required: true
docker_image_name: "node"
docker_image_tag: "latest"
volume_mappings:
 - /:/buddy

In this example, the Setup is not generated as there are no inputs defined. Instead, the parameters are described in three tabs: AWS, GitHub, and Filesystem.

Custom action with tabs definedCustom action with tabs defined

Action tab order

Tab order in custom actionsTab order in custom actions

  • Setup tab (displayed if inputs are defined)
  • Custom tabs (displayed if tabs are defined)
  • Variables (toggled on/off in the Options tab)
  • Trigger conditions (always displayed)
  • Options (always displayed)

To enable variable support, tick the Variables checkbox in the Options tab.

Versioning & parsing

Actions should be created and updated in the default branch of the repository and versioned with Git tags. An action can have as many versions as created tags, with the latest version of the action always stored in the HEAD of the default branch. You can select the version of the action from the dropdown button:

Selecting action versionSelecting action version

Once you push your action, it should appear at the top of the action list. If you don't see it on the list, you can check what the problem is in the push details on the Activity tab:

Activity screen with push eventsActivity screen with push events

Clicking the event will expand push details where you can check what the error is exactly:

Parsing details in push eventParsing details in push event

Deletion & renaming

Once an action is successfully parsed, it becomes permanent in the workspace. When an action is removed, it changes it state to deprecated, but can still be added from the action list and continues to work in its host pipelines. This is a security measure to prevent pipelines from failing in case the action repository is unwillingly removed. Changing the name of the action in action.yml creates a new action in the workspace, leaving the old as it was.

Custom actions in YAML configuration

To add your action to the pipeline via YAML, follow the pattern below:

- action: "Pipeline_action_name"
  type: "CUSTOM"
  custom_type: "name:tag"

where action is the name the action is labeled with in the pipeline, and custom_type is the name of the custom action that you want to use.

For example:

- action: "Worker scaling"
  type: "CUSTOM"
  custom_type: "workers_custom:latest"

Custom actions can also be used in remote pipeline configuration, just like every other action.

YAML paramaters for Custom Actions

NameTypeDescription
name
Required
StringThe ID of the action in the YAML definition. 40 chars max (a-zA-Z0-9_)
docker_image_name
Required
StringThe Docker image from which the container is launched.
docker_image_tag
Required
StringThe tag of the Docker image from which the container is launched.
reset_entrypointBooleanIf set to True, unsets the default entrypoint set by the image.
execute_commandsString[]The list of commands run in the container.
shellStringThe type of the command shell. Default: bash
titleStringThe title of the action displayed on the action tile and the action adding screen. 40 chars max.
categoryStringThe category of the action. 100 chars max.
inputsStringThe list of inputs displayed on the action view.
tabsStringThe list of tabs displayed on the action view.
outputString []Defines the tables of environment variables generated by the action for the duration of the pipeline run.
volume_mappingsStringThe path preceding the colon is the filesystem path (the folder from the filesystem to be mounted in the container). The path after the colon is the container path (the path in the container, where this filesystem will be located).
cached_dirsString []The additional container’s directories that will be cached between executions.

List of input parameters

NameTypeDescription
id
Required
StringThe ID of the input. Used to create the environment variable in the container. 40 chars max (a-zA-Z0-9_). Must be unique. Must not start with buddy. Case sensitive, i.e. user and User act as two separate inputs.
nameStringThe name displayed on the label of the input. 100 chars max. If not provided, fetches the value from the ID and replaces underscores _ with spacebars.
typeStringThe type of the input. Default: TEXT
infoStringAdds a description with additional information below the input. 200 chars max.
optionsString []The options of the input. Required by AUTOSUGGEST and SELECT types.
requiredBooleanDefault: false.
maskedBooleanDefault: false.
defaultStringThe optional default value injected to the input.

List of input types

NameDescription
TEXTA one-line text input. Supports masking.
TEXTAREAA multi-line text input. Supports masking.
PASSWORDUsed to enter password credentials. Always masked.
SELECTA selector list. Requires Options.
AUTOCOMPLETESupports autocompletion. Requires Options.
CHECKBOXA box that can be ticked on and off.
COMMANDA multi-line text area styled after build actions. Supports masking.
FILESYSTEM_PATHUsed to select paths in the pipeline filesystem. Supports masking.
GITHUB_INTEGRATIONEnables selecting the GitHub integration in the project. Uses the integration ID as the input variable. Generates GITHUB_TOKEN.
AWS_INTEGRATIONEnables selecting the AWS integration in the project. Uses the integration ID as the input variable. Generates AWS_ACCESS KEY and AWS_SECRET_KEY.

Examples of inputs

TEXT

name: "input_TEXT"
inputs:
 first_field:
   name: "Text field #1"
   required: true
 second_field:
   name: "Text field #2"
   default: "Second text field"
 third_field:
   name: "Text field #3"
   info: "This is an example description for the text field above."
execute_commands:
 - echo $first_field
 - echo $second_field
 - echo $third_field
docker_image_name: "ubuntu"
docker_image_tag: "latest"

Here we can see three text inputs:

  • the first is mandatory (required: true)
  • the second has a default value entered
  • the third has an info box with a description

Custom action with TEXT inputsCustom action with TEXT inputs

This is default input if no type is defined.

TEXTAREA

name: "input_TEXTAREA"
inputs:
 textarea_1:
   type: TEXTAREA
   name: "Textarea #1"
   default: |-
     First line of multi-line text input.
     Second line of multi-line text input.
     Third line of multi-line text input.
     Fourth line of multi-line text input.
 textarea_2:
   type: TEXTAREA
   name: "Textarea #2"
   info: "This is an example description for the textarea field above."
execute_commands:
 - echo $textarea_1
 - echo $textarea_2
docker_image_name: "ubuntu"
docker_image_tag: "latest"

This action has two text areas:

  • the first has four lines of default text
  • the second one has an infobox with an explanation of what it does

Custom action with TEXTAREA inputsCustom action with TEXTAREA inputs

PASSWORD

name: "input_PASSWORD"
inputs:
 password_1:
   type: PASSWORD
   name: "First password"
   required: true
 password_2:
   type: PASSWORD
   name: "Second Password"
execute_commands:
 - echo $password_1
 - echo $password_2
docker_image_name: "ubuntu"
docker_image_tag: "latest"

In this example, the first password input is mandatory (required: true), and the second is optional.

Custom action with PASSWORD inputsCustom action with PASSWORD inputs

You can see the field with the password is masked by default:

SELECT

name: "input_SELECT"
inputs:
 select_1:
   type: SELECT
   name: "First select"
   required: true
   options:
     - "option 1"
     - "option 2"
     - "option 3"
 select_2:
   type: SELECT
   name: "Second select"
   info: "This is an example description for the selector above."
   default: "option 2"
   options:
     - "option 1"
     - "option 2"                                                                                                                                                                   
     - "option 3"
execute_commands:
 - echo $select_1
 - echo $select_2
docker_image_name: "ubuntu"
docker_image_tag: "latest"

Here we have two selectors:

  • the first one is required
  • the second has default value of 2 and an infobox with a description

Custom action with SELECT inputsCustom action with SELECT inputs

AUTOCOMPLETE

name: "input_AUTOCOMPLETE"
inputs:
 autocomplete_1:
   type: AUTOCOMPLETE
   name: "Example input"
   options:
     - "suggestion 1"
     - "suggestion 2"
     - "suggestion 3"
execute_commands:
 - echo $autocomplete_1
docker_image_name: "ubuntu"
docker_image_tag: "latest"

This type of input supports suggestions. You can enter your own value there, or select one of the suggestions from the list.

Custom action with AUTOCOMPLETE inputsCustom action with AUTOCOMPLETE inputs

CHECKBOX

name: "input_CHECKBOXES"
inputs:
 first_checkbox:
   type: CHECKBOX
   name: "Checkbox #1"
   default: "true"
 second_checkbox:
   type: CHECKBOX
   name: "Checkbox #2"
   info: "This is an example description for the checkbox above."
execute_commands:
 - echo $first_checkbox
 - echo $second_checkbox
docker_image_name: "ubuntu"
docker_image_tag: "latest"

Setting default: "true" in the first input ticks the first checkbox by default. The info parameter in the second checkbox input adds a line of explanation.

Custom action with CHECKBOX inputsCustom action with CHECKBOX inputs

COMMAND

name: "input_COMMAND"
inputs:
 command_field:
   name: CMD
   type: COMMAND
   default: "ls -al"
execute_commands:
- bash -c "$command_field"
docker_image_name: "ubuntu"
docker_image_tag: "latest"
volume_mappings:
 - /:/buddy

Custom action with COMMAND inputCustom action with COMMAND input

In this case, the container has a filesystem attached so that the commands can be run on repository files.

We recommend using bash -c “$INPUT_NAME" as the execution command for the CMD input. This way the command will always be run properly, regardless of the number of lines.

FILESYSTEM_PATH

name: "input_FILESYSTEM"
inputs:
 Filesystem_Path:
   type: FILESYSTEM_PATH
   default: "/buddy"
docker_image_name: "ubuntu"
docker_image_tag: "latest"
volume_mappings:
 - /:/buddy

Custom action with filesystem attachedCustom action with filesystem attached

This type of input lets you select the path in the pipeline filesystem. You can see it attached in volume_mappings.

GITHUB_INTEGRATION

name: "input_GitHub"
inputs:
 github_field:
   type: GITHUB_INTEGRATION
   name: "GitHub Integration"
   default: "github_integration_hash"
execute_commands:
 - gh auth status
docker_image_name: "buddy/github-cli"
docker_image_tag: "latest"

The GITHUB_INTEGRATION parameter adds an input that lets you select the GitHub integration and use it in the action. The action also generates $GITHUB_TOKEN that can be used in the pipeline.

This action uses a Docker image with the GitHub CLI installed. The executed command retrieves the primary contact information of the account associated with the selected AWS integration:

Custom action logsCustom action logs

Adding default with the integration hash will automatically set the integration in the input.

AWS_INTEGRATION

name: "input_AWS"
inputs:
 aws_field:
   type: AWS_INTEGRATION
   name: "AWS Integration"
   default: "aws_integration_hash"
execute_commands:
 - aws account get-contact-information
docker_image_name: "buddy/aws-cli-2"
docker_image_tag: "latest"

The AWS_INTEGRATION parameter adds an input that lets you select the AWS integration and use it in the action. The action also generates $AWS_ACCESS_KEY_ID and $AWS_SECRET_ACCESS_KEY that can be used in the pipeline.

This action uses a Docker image with the AWS CLI installed. The executed command verifies and displays information about the authentication state of the selected GitHub integration:

Custom action logsCustom action logs

Adding default with the integration hash will automatically set the integration in the input.

Last modified on January 20, 2023

Get Started

Sign up for free and deploy your project in less than 10 minutes.