Build Stages Part 2: Stages Order and Conditions

Back in May we have introduced build stages, a feature that gives you a lot of flexibility and control over your build and delivery process.

We have received a lot, a lot of feedback from you, and we have learned about some issues and limitations in the current design, and about use cases that some of you have, some of which we had not known or thought of. Thank you all for your very valuable input!

After fixing known bugs we are now addressing some of these limitations in a second iteration on this feature:

Define the stage order

If you mix build matrix expansion with build stages defined on jobs.include so far it has not been possible to control the order of these stages: all jobs coming out of the matrix expansion would automatically be assigned the default stage test, and this stages would run first, no matter what you define on jobs.include (because these would be appended to the jobs list).

Build matrix expansion is handy as it does not require you to list all jobs manually. However, sometimes you need to run a stage before these jobs, for example in order to warm up caches, or compile a binary, or prepare a Docker image.

We are now introducing a way for you to define the order of stages separately, in a new config section stages. If this section is present, stages and jobs will be reordered according to the given order. If it is not present, we use the order of stages given in jobs.include, as before.

You can specify this order in the section stages, like so:

  - compile
  - test
  - deploy
  - FOO=one
  - FOO=two
    - stage: compile
      script: ./compile
    - stage: deploy
      script: ./deploy

This will result in the following build. As you can see it will run the compile section first, then run all jobs from the matrix expansion (based on the env section) in the stage test, and only then run the deploy stage.

Conditional builds, stages, and jobs

So far, all jobs that are part of your build stages set up would always run unconditionally. If you wanted to skip a certain job based on a condition, then you’d need to define that condition in your scripts, or skip a deployment using a deploy condition. Unfortunately that means you’ll need to wait for the respective job to start, only for it to be skipped on the VM. While this works, it might add to your overall build time significantly.

You can now filter out, and reject stages by specifying conditions in your build configuration (your .travis.yml file, or via API build requests). These conditions will be evaluated by the part of our system that configures your build, so you do not have to wait for a VM to start in order to skip a stage.

And while we were at it, we have also allowed the same kind of conditions to be specified on builds and jobs, too.

Conditional builds, stages, and jobs can be configured using a custom boolean language. You can find all the details in our documentation, but here are some examples:

type = push
type != cron
type IN (api, cron)
branch = production
tag IS present
tag =~ ^v1
sender !~ bot$
env(FOO) = bar
type = push AND NOT (branch = production OR tag IS present)

Builds can be included or excluded by specifying a condition as follows:

# .travis.yml or API request config payload
if: branch = master

Build requests that are found to be excluded will not generate a build, but will be listed on the “Requests” overview.

Stages can be included or excluded by specifying a condition in the stages section:

# .travis.yml or API request config payload
  - compile
  - test
  - name: deploy
    if: branch = master

At the moment, stages that are found to be excluded will be skipped silently (an improvement to this is on the roadmap).

Jobs can be included or excluded by specifying a condition on the jobs.include listing:

# .travis.yml or API request config payload
    - if: branch = master
      env: FOO=foo

Jobs need to be listed explicitely, i.e. using jobs.include or matrix.include (alias), in order to specify conditions for them. Jobs created via matrix expansion currently cannot have conditions.

At the moment, jobs that are found to be excluded will be skipped silently (an improvement to this is on the roadmap).

We’d love to hear your thoughts

We would love to hear your feedback, thoughts and suggestions for build stages in our beta feature issue.

If you have any questions or need help with your configuration, as always, please do not hesitate to email us at