Workflow

Workflow is the way that individual jobs are wired together to form a pipeline. This is done by using a requires keyword in your job definition with the list of jobs or events that should cause that job to run. Screwdriver defines four events for every pipeline that occur due to SCM events: ~pr, ~commit, ~tag and ~release.

Keyword Description
~pr Event occurs when a pull-request is opened, reopened, or modified.
~commit Event occurs when a commit is made against the pipeline’s branch. When you start a pipeline manually, it runs all the jobs that have the ~commit event trigger.
~tag Event occurs when a tag is created. Now, this trigger is only available for user using GitHub as scm.
~release Event occurs when released. Now, this trigger is only available for user using GitHub as scm.

See the tag and release trigger example repo for reference.

Defining Workflow Order

To denote workflow order, use the requires keyword under a job with the job names as an array. Job names may be prefixed with a tilde to indicate advanced logic.

Example

In the following example, the job, main, will start after any SCM pull-request, or commit event. The job, second, will run after main is successful.

Please note that a job started by a pull-request will not trigger its downstream jobs unless you use the chainPR annotation. For example, if main starts and succeeds as a result of a pull-request being opened, second will not start afterwards.

jobs:
    main:
        image: node:lts
        requires: [~pr, ~commit]
        steps:
            - echo: echo hi

    second:
        image: node:lts
        requires: [main]
        steps:
            - echo: echo bye

To specify a job to run when a pull request is opened or updated, use requires: [~pr]. For jobs that should start after code is merged or pushed to the main branch, use requires: [~commit].

Example repo: https://github.com/screwdriver-cd-test/workflow-sequential-example

Parallel and Join

You can run jobs in parallel by requiring the same job in two or more jobs. To join multiple parallel jobs at a single job you can use the requires syntax to require multiple jobs.

Join Example

In the following example, where A and B requires main. This will cause A and B to execute in parallel after main is successful. Also in this example, job C runs only after both A and B are successful in the same triggering event.

shared:
    image: node:lts

jobs:
    main:
        requires: [~pr, ~commit]
        steps:
            - echo: echo hi
    A:
        requires: [main]
        steps:
            - echo: echo in parallel
    B:
        requires: [main]
        steps:
            - echo: echo in parallel
    C:
        requires: [A, B]
        steps:
            - echo: echo join after A and B

Example repo: https://github.com/screwdriver-cd-test/workflow-parallel-join-example

OR Workflow

Similar to Join, but job will start when any of its requires jobs are successful [OR]. This is achieved by adding a tilde (~) prefix to the jobs it requires.

Example

In the following example, the last job will trigger once after either first OR second completes successfully.

shared:
    image: node:lts
    steps:
        - greet: echo hello
jobs:
    main:
        requires: [~pr, ~commit]
    first:
        requires: [main]
    second:
        requires: [main]
    last:
        requires: [~first, ~second]

Branch filtering

Branch filtering lets you listen to events happening beyond the pipeline’s specified branch. To trigger jobs in your pipeline after a commit is made on a specific branch, you can use requires: [~commit:branchName]. To trigger jobs in your pipeline after a pull request is made against a specific branch, you can use requires: [~pr:branchName]. Branches may also be specified by using a (JavaScript flavor) regular expression (e.g. ~commit:/^feature-/), although note that regex flags are not supported.

Example

In the following example, when a commit is made on branch staging, both staging-commit job and all-commit job are triggered. Also, when a commit is made on branch default, both main job and all-commit job are triggered. When a pull request is opened against branch staging, staging-pr job is triggered.

shared:
    image: node:lts

jobs:
    main:
        requires: [~commit]
        steps:
            - echo: echo commit
    staging-commit:
        requires: [~commit:staging]
        steps:
            - echo: echo staging
    all-commit:
        requires: [~commit:/./]
        # /./ matches any branch name and is used here for illustration only
        # Don't use that regexp in any actual workflow.
        steps:
            - echo: echo all
    staging-pr:
        requires: [~pr:staging]
        steps:
            - echo: echo staging pr

Note: A PR against a branch will follow the workflow pattern indicated by that branch’s screwdriver.yaml.

See the branch filtering example repo for reference. To see how branch filtering works with pull requests, see our example pull request.

Tag/Release filtering

You can use Tag/Release filtering to limit the listening for ~tag/~release events to a specific tag or release name. To trigger a job in your pipeline after a tag with a specific name has been created, you can use requires: [~tag:tagName]. To trigger a job in your pipeline after a release with a specific name has been pushed, you can use requires: [~release:releaseName]. tagName and releaseName may also be specified by using a (JavaScript flavor) regular expression (e.g. ~release:/^feature-/), although note that regex flags are not supported.

Example

In the following example, when stable release is pushed, all-tag-and-release and stable-release are triggered. When v1.0 tag is created, all-tag-and-release and v1-tag are triggered. When v2.0 tag is created, all-tag-and-release is triggered.

shared:
    image: node:lts

jobs:
    all-tag-and-release:
        requires: [~tag, ~release]
        steps:
            - echo: echo all
    v1-tag:
        requires: [~tag:/^v1\.*/]
        steps:
            - echo: echo v1 tag
    stable-release:
        requires: [~release:stable]
        steps:
            - echo: echo stable release

Remote Triggers

To trigger a job in your pipeline after a job in another pipeline is finished, you can use remote requires. The format is ~sd@pipelineID:jobName. ~pr, ~commit, and jobs with ~sd@pipelineID:jobName format follow OR logic.

Example

In the following example, this pipeline will start the main job after any pull-request, commit, or successful completion of the publish job in pipeline 456.

jobs:
    main:
        image: node:lts
        requires: [~pr, ~commit, ~sd@456:publish]
        steps:
            - echo: echo hi

Example repo: https://github.com/screwdriver-cd-test/workflow-remote-requires-example

Remote Join

You can also have remote join jobs. Please double check with your cluster admin whether it is supported.

Example

In the following example, this pipeline 3 will start the join_job job after successful completion of: internal_fork, external_fork in pipeline 2, and external_fork in pipeline 4.

Remote join

Pipeline 3 screwdriver.yaml:

shared:
  image: node:lts
  steps:
    - echo: echo hi
jobs:
  main:
    requires: [~commit, ~pr]
  internal_fork:
    requires: [main]
  join_job:
    requires: [internal_fork, sd@2:external_fork, sd@4:external_fork]

Pipeline 2 screwdriver.yaml:

shared:
  image: node:lts
  steps:
    - echo: echo hi
jobs:
  external_fork:
    requires: [~sd@3:main]

Pipeline 4 screwdriver.yaml:

shared:
  image: node:lts
  steps:
    - echo: echo hi
jobs:
  external_fork:
    requires: [~sd@3:main]

Caveats

Blocked By

To have your job blocked by another job, you can use blockedBy. It has the same format as requires, except it does not accept values like ~commit or ~pr.

Note:

Example

In the following example, job2 is blocked by job1 or sd@456:publish. If job1 or sd@456:publish is running and job2 is triggered, job2 will be put back into the queue. Screwdriver will check the queue periodically to see if job2 is no longer blocked and will run it as soon as that is true. Note: blockedBy only blocks the job that the configuration is under; the following configuration won’t block job1 if job2 is running.

shared:
    image: node:lts
jobs:
    job1:
        requires: [~commit, ~pr]
        steps:
            - echo: echo hello
    job2:
        blockedBy: [~job1, ~sd@456:publish]
        steps:
            - echo: echo bye

Example repo: https://github.com/screwdriver-cd-test/workflow-blockedby-example

Freeze Windows

You can freeze your jobs and prevent them from running during specific time windows using freezeWindows. The setting takes a cron expression or a list of them as the value. Timezone is in UTC.

Before the job is started, it will check if the start time falls under any of the provided cron windows, and freezes the job if so. The job will be unfrozen and run as soon as the current cron window ends.

Note:

Example

In the following example, job1 will be frozen during the month of March, job2 will be frozen on weekends, and job3 will be frozen from 10:00 PM to 10:59 AM.

shared:
    image: node:lts

jobs:
  job1:
    freezeWindows: ['* * ? 3 *']
    requires: [~commit]
    steps:
      - build: echo "build"
  job2:
    freezeWindows: ['* * ? * 0,6,7']
    requires: [job1]
    steps:
      - build: echo "build"
  job3:
    freezeWindows: ['* 0-10,22-23 ? * *']
    requires: [job2]
    steps:
      - build: echo "build"

Detached Jobs and Pipelines

It is possible to define workflows that do not have any external trigger. These workflows are “detached” from the normal flow of the pipeline. Some example use cases of this would be to define a rollback flow for your pipeline that could be manually triggered. Invoking a detached pipeline involves the same steps as doing a rollback.

Example

In the following example detached job is detached.

shared:
    image: node:lts

jobs:
    detached:
        steps:
            - echo: echo im-a-detached-job

Example repo: https://github.com/screwdriver-cd-test/workflow-detached-example

Subscribed SCM Notifications

You can subscribe to external repositories so builds are triggered in your pipeline whenever there are changes in those external repositories. You can configure your pipeline to subscribe to webhook notifications for events such as ~pr, ~commit, ~tag and ~release. Each job needs to be independently configured to respond to the subscribed event(s).

Example

In the following example, we can add repositories to subscribe to in the scmUrls sections of the subscribe object. Then we need to specify the events to subscribe to, which are ~commit and ~pr in this example. Note that webhooks are automatically registered to the repositories at the time of pipeline creation.

shared:
    image: node:lts

subscribe:
    scmUrls:
        - git@github.com:supra08/functional-workflow.git: ['~commit', '~pr']

Now to configure specific jobs to respond to subscribed events:

jobs:
    A:
        steps:
            - echo: echo test
        requires: [~pr, ~commit, ~subscribe]

Here the ~subscribe event tells the job to respond to external notifications.