After

When you specify dependencies using the use keyword, the task inherits the file system contents and environment variables of its dependencies.

If you want to run tasks after other tasks without inheriting the output of the dependencies, you should use the after keyword instead.

A few common scenarios include:

  • Continuous Deployment workflows, where tasks have side effects of modifying external resources and need to run in a specific order
  • ETL workflows where state is stored externally and tasks need to run in a specific order
  • Optimizing build minutes, where you may want to make sure some tasks succeed before running others

Example

tasks:
  - key: one
    run: echo this is task one

  - key: two
    run: echo this is task two

  - key: three
    after: [one, two]
    run: echo task three waits for one and two to finish before running

Running Tasks After Other Tasks Fail

By default, using after means that the task will only run if every task listed in after succeeds. However, you may want to run some tasks after others fail. To do this, you can configure after using an expression instead of an array.

tasks:
  - key: one
    run: exit 1

  - key: if-one-fails
    after: ${{ one.failed }}
    run: echo task one failed!

You can use && and || operators to list multiple tasks within the expression. For more details, see the documentation on expressions.

Status Attributes

To control the after conditions, the following attributes are available on tasks within expressions.

Result status attributes

attributedescription
succeededThe task was successful. It may have executed or been a cache hit.
failedThe task failed. It may have executed or failed for another reason such as being cancelled.

Note that skipped tasks, which you can check via .skipped, will return false for both succeeded and failed.

Execution status attributes

attributedescription
finishedThe task finished running. Notably, .finished is false for tasks that are .aborted or .skipped.
abortedThe task was aborted either before or after it started running.
cancelledThe task was aborted due to being cancelled. Most of the time, you'll want to check .aborted instead of .cancelled.
skippedThe task was skipped. These tasks will return false for both .succeeded and .failed.
cache-hitThe task was a cache hit.
timed-outThe task was aborted due to timing out.

After success or failure

If you want to run a task after another task, regardless of whether that task succeeds or fails, then you currently must check for both states:

${{ (example-task.succeeded || example-task.failed) }}

Failed after running

If you want to run a task after another task fails, but only if that task actually executed (e.g. it finished running and then exited with a non-zero exit status), then you can check:

${{ (example-task.failed && example-task.finished) }}