Configuring your build
What This Guide Covers
This guide covers build environment and configuration topics that are common to all projects hosted on travis-ci.org, regardless of the technology. We recommend you start with the Getting Started guide and read this guide top to bottom before moving on to build notifications and language-specific guides.
.travis.yml file: what it is and how it is used
Travis CI uses
.travis.yml file in the root of your repository to learn about
your project and how you want your builds to be executed.
.travis.yml can be
very minimalistic or have a lot of customization in it. A few examples of what
kind of information your
.travis.yml file may have:
- What programming language your project uses
- What commands or scripts you want to be executed before each build (for example, to install or clone your project's dependencies)
- What command is used to run your test suite
- Emails, Campfire and IRC rooms to notify about build failures
and so on.
At the very minimum, Travis CI needs to know what builder it should use for your project: Ruby, Clojure, PHP or something else. For everything else, there are reasonable defaults.
By default, the worker performs the build as following:
- Switch language runtime (for example, to Ruby 1.9.3 or PHP 5.4)
- Clone project repository from GitHub
- Run before_install scripts (if any)
- cd to the clone directory, run dependencies installation command (default specific to project language)
- Run before_script scripts (if any)
- Run test script command (default is specific to project language). It must use exit code 0 on success and any code on failure.
- Run after_success/after_failure scripts (if any)
- Run after_script scripts (if any)
The outcome of any of these commands (except after_success, after_failure or after_scripts) indicates whether or not this build has failed or passed. The standard Unix exit code of "0" means the build passed; everything else is treated as failure.
Test result is exported to
TRAVIS_TEST_RESULT, which you can use in commands run in
With the exception of cloning project repository and changing directory to it, all of the above steps can be tweaked with
Travis CI Preserves No State Between Builds
Travis CI uses virtual machine snapshotting to make sure no state is left between builds. If you modify CI environment by writing something to a data store, creating files or installing a package via apt, it won't affect subsequent builds.
Define custom build lifecycle commands
Travis CI runs all commands over SSH in isolated virtual machines. Commands that modify SSH session state are "sticky" and persist throughout the build.
For example, if you
cd into a particular directory, all the following commands will be executed from it. This may be used for good (e.g. building subprojects one
after another) or affect tools like
mvn that may be looking for files in the current directory.
You can specify the main build command to run instead of the default
script: "make it-rain"
The script can be any executable; it doesn't have to be
make. As a matter of fact the only requirement for the script is that it should use an exit code 0 on success, any thing else is considered a build failure. Also practically it should output any important information to the console so that the results can be reviewed (in real time!) on the website.
If you want to run a script local to your repository, do it like this:
In this case, the script should be made executable (for example, using
chmod +x) and contain a valid shebang line
/usr/bin/env python and so on).
You can also define scripts to be run before and after the main script:
before_script: some_command after_script: another_command
Both settings support multiple scripts, too:
before_script: - before_command_1 - before_command_2 after_script: - after_command_1 - after_command_2
These scripts can, for example, be used to setup databases or other build setup tasks. For more information about database setup see Database setup.
If your project uses non-standard dependency management tools, you can override dependency installation command using
install: ant install-deps
As with other scripts,
install command can be anything but has to exit with the 0 status in order to be considered successful.
If you'd like to skip the
install stage entirely, just set it to
true and nothing will be run.
true is a Unix command which returns (you guessed it) 0.
You can also define scripts to be run before and after the dependency installation script:
Both settings support multiple scripts, too:
before_install: - before_command_1 - before_command_2
before_install is commonly used to update git repository submodules and do similar tasks that need to be performed before dependencies are installed.
On Native Dependencies
If your project has native dependencies (for example, libxml or libffi) or needs tools Travis CI Environment does not provide, you can install packages via apt and even use 3rd-party apt repositories and PPAs. For more see dedicated sections later in this guide.
Updating Git Submodules
If your project uses Git submodules, use the following technique to clone them before dependencies installation:
before_install: - git submodule update --init --recursive
This will include nested submodules (submodules of submodules), in case there are any.
Use Public URLs For Submodules
If your project uses Git submodules, make sure you use public Git URLs. For example, on GitHub, instead of
Otherwise, Travis CI builders won't be able to clone your project because they don't have your private SSH key.
Choose runtime (Ruby, PHP, Node.js, etc) versions
One of the key features of Travis is the ease of running your test suite against multiple runtimes and versions. Since Travis does not know what runtimes and versions your projects supports, they need to be specified in the
.travis.yml file. The option you use for that varies between languages. Here are some basic .travis.yml examples for various languages:
Currently Clojure projects can be tested against Oracle JDK 7, OpenJDK 7 and OpenJDK 6. Clojure flagship build tool, Leiningen, supports testing against multiple Clojure versions:
- In Leiningen 1.x, via lein-multi plugin
- In upcoming Leiningen 2.0, via Leiningen Profiles
If you are interested in testing against multiple Clojure releases, just use these Leiningen features and it will work without special support on the Travis side.
Learn more in our Clojure guide.
Erlang projects specify releases they need to be tested against using
otp_release: - R14B03 - R14B04 - R15B01
Learn more about .travis.yml options for Erlang projects.
Groovy projects can be currently tested against Oracle JDK 7, OpenJDK 7 and OpenJDK 6. Support for multiple JDKs will be added eventually.
Learn more in our Groovy guide.
Java projects can be currently tested against Oracle JDK 7, OpenJDK 7 and OpenJDK 6. Support for multiple JDKs will be added eventually.
Learn more in our Java guide.
Node.js projects specify releases they need to be tested against using
node_js: - "0.4" - "0.6"
Learn more about .travis.yml options for Node.js projects.
Perl projects specify Perls they need to be tested against using
perl: - "5.14" - "5.12"
Learn more about .travis.yml options for Perl projects.
PHP projects specify releases they need to be tested against using
php: - "5.4" - "5.3"
Learn more about .travis.yml options for PHP projects.
Python projects specify Python versions they need to be tested against using
python: - "2.7" - "2.6" - "3.2"
Learn more about .travis.yml options for Python projects.
Ruby projects specify releases they need to be tested against using
rvm: - "1.9.3" - "1.9.2" - jruby-19mode - rbx-19mode - jruby-18mode - "1.8.7"
Learn more about .travis.yml options for Ruby projects.
Scala projects specify releases they need to be tested against using
scala: - "2.9.2" - "2.8.2"
Travis CI relies on SBT's support for running tests against multiple Scala versions.
Learn more in our Scala guide.
Set environment variables
To specify an environment variable:
Environment variables are useful for configuring build scripts. See the example in Database setup. One ENV variable is always set during your builds,
TRAVIS. Use it to detect whether your test suite is running during CI.
You can specify more than one environment variable per item in the
rvm: - 1.9.3 - rbx-18mode env: - FOO=foo BAR=bar - FOO=bar BAR=foo
With this configuration, 4 individual builds will be triggered:
- Ruby 1.9.3 with
- Ruby 1.9.3 with
- Rubinius in 1.8 mode with
- Rubinius in 1.8 mode with
Note that environment variable values may need quoting. For example, if they have asterisks (
*) in them:
env: - PACKAGE_VERSION="1.0.*"
Installing Packages Using apt
If your dependencies need native libraries to be available, you can use passwordless sudo to install them with
before_install: - sudo apt-get update -qq - sudo apt-get install -qq [packages list]
The reason why travis-ci.org can afford to provide passwordless sudo is that virtual machines your test suite is executed in are snapshotted and rolled back to their pristine state after each build.
Please note that passwordless sudo availability does not mean that you need to use sudo for (most of) other operations. It also does not mean that Travis CI builders execute operations as root.
Using 3rd-party PPAs
If you need a native dependency that is not available from the official Ubuntu repositories, possibly there are 3rd-party PPAs (personal package archives) that you can use: they need to provide packages for 32-bit Ubuntu 12.04.
Because it is very common to see test suites or before scripts to hang up, Travis CI has hard time limits. If a script or test suite takes longer to run, the build will be forcefully terminated and you will see a message about this in your build log.
With our current timeouts, a build will be terminated if it's still running after 50 minutes, or if there hasn't been any log output in 10 minutes.
Some common reasons why test suites may hang up:
- Waiting for keyboard input or other kind of human interaction
- Concurrency issues (deadlocks, livelocks and so on)
- Installation of native extensions that take very long time to compile
Specify branches to build
.travis.yml and multiple branches
Travis will always look for the
.travis.yml file that is contained in the branch specified by the git commit that GitHub has passed to us. This configuration in one branch will not affect the build of another, separate branch. Also, Travis CI will build after any git push to your GitHub project unless you instruct it to skip a build. You can limit this behavior with configuration options.
White- or blacklisting branches
You can either white- or blacklist branches that you want to be built:
# blacklist branches: except: - legacy - experimental # whitelist branches: only: - master - stable
If you specify both, "except" will be ignored. Please note that currently (for historical reasons),
.travis.yml needs to be present on all active branches of your project.
Note that the
gh-pages branch will not be built unless you add it to the whitelist (
Using regular expressions
You can use regular expressions to white- or blacklist branches:
branches: only: - master - /^deploy-.*$/
Any name surrounded with
/ in the list of branches is treated as a regular expression and can contain all kinds of quantifiers, anchors, and character classes supported by Ruby.
Options that are usually specified after the last
i for case insensitive matching) are not supported at the moment.
The Build Matrix
When you combine the three main configuration options above, Travis CI will run your tests against a matrix of all possible combinations. Three key matrix dimensions are:
- Runtime to test against
- Environment variables with which you can configure your build scripts
- Exclusions, inclusions and allowed failures
Below is an example configuration for a rather big build matrix that expands to 56 individual builds.
Please take into account that Travis CI is an open source service and we rely on worker boxes provided by the community. So please only specify an as big matrix as you actually need.
rvm: - 1.8.7 # (current default) - 1.9.2 - 1.9.3 - rbx-18mode - jruby - ruby-head - ree gemfile: - gemfiles/Gemfile.rails-2.3.x - gemfiles/Gemfile.rails-3.0.x - gemfiles/Gemfile.rails-3.1.x - gemfiles/Gemfile.rails-edge env: - ISOLATED=true - ISOLATED=false
You can also define exclusions to the build matrix:
matrix: exclude: - rvm: 1.8.7 gemfile: gemfiles/Gemfile.rails-2.3.x env: ISOLATED=true - rvm: jruby gemfile: gemfiles/Gemfile.rails-2.3.x env: ISOLATED=true
Only exact matches will be excluded.
It is also possible to include entries into the matrix:
matrix: include: - rvm: ruby-head gemfile: gemfiles/Gemfile.rails-3.2.x env: ISOLATED=false
This is useful if you want to, say, only test the latest version of a dependency together with the latest version of the runtime.
Sometimes you may want to use env variables that are global to the matrix, i.e. they're inserted into each matrix row. That may include keys, tokens, URIs or other data that is needed for every build. In such cases, instead of manually adding such keys to each env line in matrix, you can use
matrix keys to differentiate between those two cases. For example:
env: global: - CAMPFIRE_TOKEN=abc123 - TIMEOUT=1000 matrix: - USE_NETWORK=true - USE_NETWORK=false
Such configuration will generate matrix with 2 following env rows:
USE_NETWORK=true CAMPFIRE_TOKEN=abc123 TIMEOUT=1000 USE_NETWORK=false CAMPFIRE_TOKEN=abc123 TIMEOUT=1000
Secure environment variables
In the last example I used a token as one of the environment variables. However, it's not very wise to put your private tokens in the publicly available file. Travis supports environment variables encryption to handle this case and allows you to keep configuration public, while keeping parts of it private. Example configuration with secure environment variables looks something like:
env: global: - secure: <encrypted string here> - TIMEOUT=1000 matrix: - USE_NETWORK=true - USE_NETWORK=false - secure: <you can also put encrypted vars inside matrix>
You can encrypt environment variables using public key attached to your repository. The simplest way to do that is to use travis gem:
gem install travis cd my_project travis encrypt MY_SECRET_ENV=super_secret
Please note that secure env variables are not available for pull requests. This is done due to the security risk of exposing such information in submitted code. Everyone can submit a pull request and if an unencrypted variable is available there, it could be easily displayed.
You can also automatically add it to your
travis encrypt MY_SECRET_ENV=super_secret --add env.matrix
To make the usage of secure environment variables easier, we expose info on their availability and info about the type of this build:
TRAVIS_SECURE_ENV_VARSis set to "true" or "false" depending on the availability of environment variables
TRAVIS_PULL_REQUEST: The pull request number if the current job is a pull request, "false" if it's not a pull request.
Please also note that keys used for encryption and decryption are tied to the repository. If you fork a project and add it to travis, it will have different pair of keys than the original.
Rows That are Allowed To Fail
You can also define rows that are allowed to fail in the build matrix. Allowed failures are items in your build matrix that are allowed to fail without causing the entire build to be shown as failed. This lets you add in experimental and preparatory builds to test against versions or configurations that you are not ready to officially support.
Allowed failures must be a list of key/value pairs representing entries in your build matrix.
You can define allowed failures in the build matrix as follows:
matrix: allow_failures: - rvm: 1.9.3