Skip to main content

Workflows

Workflows form the framework for orchestrating your jobs. Effective use of workflows reduces development time and allows for efficient use of resources. This document describes workflow features and provides examples.

Overview

A workflow is a selection of jobs that are to be run autonomously. A pipeline consists of one or more workflows that define the entire build and test process. Workflows allow users to:

  • Run designs in clean environments to quickly locate bugs.
  • Reuse jobs in different workflows.
  • Run multiple jobs in parallel.

The workflows for a particular pipeline may be found by clicking on the particular pipeline on the pipelines page.

workflowsexample-1

Configuration Examples

Example 1

The following example shows a single workflow that will run two jobs in parallel. To create a workflow, you need a workflow: section in bbx./config.yaml. The workflow requires a unique name, in the provided example the workflow has been named workflow-example. Once the workflow has been declared, you need to allocate jobs to the workflow. This is performed with the jobs key followed a list of jobs to be performed by the workflow. In this example, there are two jobs example-job1 and example-job2. Once the workflow is triggered, these two jobs will run concurrently.

runners:
example-runner:
image: work1-virtualbox:5000/ubuntu-generic

jobs:
example-job1:
runner: example-runner
steps:
- run:
name: Say Hello World 1
command: |
echo "Hello World 1"

example-job2:
runner: example-runner
steps:
- run:
name: Say Hello World 2
command: |
echo "Hello World 2"

workflows:
workflow-example:
jobs:
- example-job1
- example-job2

Example 2

The following example shows a two workflows that will run two separate jobs. In this example, there are two jobs example-job1 and example-job2. The first job, example-job1 belongs to workflow-example1 and the second job, example-job2 belongs to workflow-example2. The two workflows can run independently of each other. It is recommended to specify triggers for the workflows if you want them to run on separate occasions under different circumstances. More information about triggers can be found in the Triggers page.

runners:
example-runner:
image: work1-virtualbox:5000/ubuntu-generic

jobs:
example-job1:
runner: example-runner
steps:
- run:
name: Say Hello World 1
command: |
echo "Hello World 1"

example-job2:
runner: example-runner
steps:
- run:
name: Say Hello World 2
command: |
echo "Hello World 2"

workflows:
workflow-example1:
jobs:
- example-job1
workflow-example2:
jobs:
- example-job2

Example 3

The following example shows a single workflow that will run two jobs sequentially. The first job example-build, synthesises and builds a Vitis project, and the second job jobs, takes the output of the first job and performs a software emulation. As you will notice, there are a number of differences from the previous examples.

This one uses a different image for the runner — this image contains Vitis, while the previous example used a plain Ubuntu image.

The first job (build) takes in a number of input artifacts — these are necessary for Vitis to perform the build. The artifacts specified here include: a platform file xilinx_zcu104_base_202010_1.zip to represent the FPGA board for which we are compiling; a copy of the Arch Linux file system aarch64-xilinx-linux2020_1.zip for the ARM processor to use; a Linux kernel xilinx-zynqmp-common-v2020.1.tar.gz for the ARM processor on the FPGA. More information about these artifacts can be found in the artifacts page. It outputs a single artifact as a compressed file, containing all the files and folders listed under the output artifact field. There is one step which runs a shell script Emulation-SW/build.sh that contains a series of commands to build a project using Vitis.

The second job takes in two artifacts, which include: a platform file xilinx_zcu104_base_202010_1.zip to represent the FPGA board where we are running the simulation; the output of the previous build job. There is one step which runs a shell script ./sw_emu.sh containing the relevant commands to run the simulation. The depends field specifies that the first job, example-build must successfully complete before the second job, example-test can run. The second job will fail if the first job, which it depends on fails.

runners:
example-runner:
image: work1-virtualbox:5000/ubuntu-vitis-2020-1

jobs:
example-build:
runner: example-runner
input:
artifact:
- xilinx_zcu104_base_202010_1.zip
- aarch64-xilinx-linux2020_1.zip
- xilinx-zynqmp-common-v2020.1.tar.gz
output:
artifact:
- Emulation-SW/build.sh
- Emulation-SW/package
- sw_emu.sh
- Emulation-SW/launch.sh
- Emulation-SW/launch.expect
steps:
- run:
name: Run Software Emulation Build
command: Emulation-SW/build.sh

example-test:
runner: example-runner
depends:
- example-build
input:
artifact:
- example-build
- xilinx_zcu104_base_202010_1.zip
steps:
- run:
name: Run Software Emulation
command: ./sw_emu.sh

workflows:
workflow-example:
jobs:
- example-build
- example-test

Post hooks

A post hook is a task that can be set up to run at the end of a workflow to perform various cleanup operations. Internally, a post hook runs in a container, just as a job does, though it runs under different conditions from a conventional job. A workflow can have at most two post hooks.

Example

This example defines a workflow called hello-world-workflow which contains two jobs, first-job and second-job. The workflow also contains two post hooks hello-world-pass-hook and hello-world-fail-hook. The post hooks have a when condition, which determines what would cause each of these two hooks to run. Acceptable values for the when condition are on-workflow-pass and on-workflow-fail. If all the jobs defined in the workflow pass, then any hook which has the on-workflow-pass condition will run, as the workflow is deemed to have passed. If any of the jobs defined in the workflow fail, then any hook which has the on-workflow-fail condition will run, as the workflow is deemed to have failed.

runners:
ubuntu-runner:
image: public.ecr.aws/y2s4f3y9/ubuntu-generic

# Define a job to be performed during a workflow
jobs:
first-job:
# Specify the runner used to perform this job
runner: ubuntu-runner

# Define one or more steps to execute commands as part of the job
steps:
- run:
name: Say Hello World
command: echo "Hello World"

second-job:
# Specify the runner used to perform this job
runner: ubuntu-runner
depends:
- hello-world:
when: on-completion

# Define one or more steps to execute commands as part of the job
steps:
- run:
name: Say Hello World
command: echo "Hello World"

post-hooks:
hello-world-pass-hook:
# Specify the runner used to perform this job
runner: ubuntu-runner

# Define one or more steps to execute commands as part of the job
steps:
- run:
name: Say Hello World
command: echo "Hello World"

hello-world-fail-hook:
# Specify the runner used to perform this job
runner: ubuntu-runner

# Define one or more steps to execute commands as part of the job
steps:
- run:
name: Say Hello World
command: echo "Hello World"

# Define a workflow to orchestrate a job
workflows:
hello-world-workflow:
jobs:
- first-job
- second-job
post-hooks:
- hello-world-pass-hook:
when: on-workflow-pass
- hello-world-fail-hook:
when: on-workflow-fail