title | layout | permalink |
---|---|---|
Configuring your Travis CI build with .travis.yml |
en |
build-configuration/ |
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 language-specific guides.
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 example 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 after_install scripts (if any)
- 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_script scripts (if any)
The outcome of any of these commands 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.
With the exception of cloning project repository and changing directory to it, all of the above steps can be tweaked with .travis.yml
.
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.
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:
script: ./script/ci/run_build.sh
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, e.g., be used to setup databases or other build setup tasks. For more information about database setup see Database setup.
NOTE: The command(s) in after_script
will only run if the build succeeded (when script
returns 0).
If your project uses non-standard dependency management tools, you can override dependency installation command using install
option:
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.
You can also define scripts to be run before and after the dependency installation script:
before_install: some_command
after_install: another_command
Both settings support multiple scripts, too:
before_install:
- before_command_1
- before_command_2
after_install:
- after_command_1
- after_command_2
These commands are commonly used to update git repository submodules and do similar tasks that need to be performed before dependencies are installed.
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.
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.
If your project uses git submodules, make sure you use public git URLs. For example, for Github instead of
git@github.com:someuser/somelibrary.git
use
git://github.com/someuser/somelibrary.git
Otherwise, Travis CI builders won't be able to clone your project because they don't have your private SSH key.
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 vary between languages. Here are some basic .travis.yml examples for various languages:
Currently Clojure projects can only be tested against JDK 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
key:
otp_release:
- R14B02
- R14B03
- R14B04
Learn more about .travis.yml options for Erlang projects
Currently Groovy projects can only be tested against JDK 6. Support for multiple JDKs will be added eventually.
Learn more in our Groovy guide
Currently Java projects can only be tested against JDK 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
key:
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
key:
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
key:
php:
- 5.3
- 5.4
Learn more about .travis.yml options for PHP projects
Python projects specify Python versions they need to be tested against using python
key:
python:
- "2.6"
- "2.7"
- "3.2"
Learn more about .travis.yml options for Python projects
Ruby projects specify releases they need to be tested against using rvm
key:
rvm:
- 1.8.7
- 1.9.2
- 1.9.3
- jruby
- rbx-18mode
Learn more about .travis.yml options for Ruby projects
Scala projects specify releases they need to be tested against using scala
key:
scala:
- "2.8.2"
- "2.9.1"
Travis CI relies on SBT's support for running tests against multiple Scala versions.
Learn more in our Scala guide
To specify an environment variable:
env: DB=postgres
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 env
array:
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
FOO=foo
andBAR=bar
- Ruby 1.9.3 with
FOO=bar
andBAR=foo
- Rubinius in 1.8 mode with
FOO=foo
andBAR=bar
- Rubinius in 1.8 mode with
FOO=bar
andBAR=foo
If your dependencies need native libraries to be available, you can use passwordless sudo to install them with
before_install:
- sudo apt-get update
- sudo apt-get install [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.
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 11.04 and 11.10.
More on PPAs in this article, search for available PPAs on Launchpad.
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.
Exact timeout values vary between project types but in general are between 10 and 15 minutes for test suite runs and between 5 and 10 minutes for before scripts and so on.
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
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.
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.
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 /
(e.g., i
for case insensitive matching) are not supported at the moment.
Travis CI can notify you about your build results through email, IRC and/or webhooks.
By default it will send emails to
- the commit author and committer
- the owner of the repository (for normal repositories)
- all public members of the organization owning the repository
And it will by default send emails when, on the given branch:
- a build was just broken or still is broken
- a previously broken build was just fixed
You can change this behaviour using the following options:
You can specify recipients that will be notified about build results like so:
notifications:
email:
- one@example.com
- other@example.com
And you can entirely turn off email notifications:
notifications:
email: false
Also, you can specify when you want to get notified:
notifications:
email:
recipients:
- one@example.com
- other@example.com
on_success: [always|never|change] # default: change
on_failure: [always|never|change] # default: always
always
and never
obviously mean that you want email notifications to be sent always or never. change
means that you will get them when the build status changes on the given branch.
You can also specify notifications sent to an IRC channel:
notifications:
irc: "irc.freenode.org#travis"
Or multiple channels:
notifications:
irc:
- "irc.freenode.org#travis"
- "irc.freenode.org#some-other-channel"
Just as with other notification types you can specify when IRC notifications will be sent:
notifications:
irc:
channels:
- "irc.freenode.org#travis"
- "irc.freenode.org#some-other-channel"
on_success: [always|never|change] # default: always
on_failure: [always|never|change] # default: always
You also have the possibility to customize the message that will be sent to the channel(s) with a template:
notifications:
irc:
channels:
- "irc.freenode.org#travis"
- "irc.freenode.org#some-other-channel"
template:
- "%{repository_url} (%{commit}) : %{message} %{foo} "
- "Build details: %{build_url}"
You can interpolate the following variables:
- repository_url: your GitHub repo URL.
- build_number: build number.
- branch: branch build name.
- commit: shorten commit SHA
- author: commit author name.
- message: travis message to the build.
- compare_url: commit change view URL.
- build_url: URL of the build detail.
If you want the bot to use notices instead of regular messages the use_notice
flag can be used:
notifications:
irc:
channels:
- "irc.freenode.org#travis"
- "irc.freenode.org#some-other-channel"
on_success: [always|never|change] # default: always
on_failure: [always|never|change] # default: always
use_notice: true
and if you want the bot to not join before the messages are sent, and part afterwards, use the skip_join
flag:
notifications:
irc:
channels:
- "irc.freenode.org#travis"
- "irc.freenode.org#some-other-channel"
on_success: [always|never|change] # default: always
on_failure: [always|never|change] # default: always
use_notice: true
skip_join: true
If you enable skip_join
, remember to remove the NO_EXTERNAL_MSGS
flag (n) on the IRC channel(s) the bot notifies.
You can define webhooks to be notified about build results the same way:
notifications:
webhooks: http://your-domain.com/notifications
Or multiple channels:
notifications:
webhooks:
- http://your-domain.com/notifications
- http://another-domain.com/notifications
Just as with other notification types you can specify when webhook payloads will be sent:
notifications:
webhooks:
urls:
- http://hooks.mydomain.com/travisci
- http://hooks.mydomain.com/events
on_success: [always|never|change] # default: always
on_failure: [always|never|change] # default: always
Here is an example payload of what will be POST
ed to your webhook URLs: gist.github.com/1225015
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 and allowed failures
Below is an example configuration for a rather big build matrix that expands to 28 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.
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.
You can define allowed failures in the build matrix as follows:
matrix:
allow_failures:
- rvm: 1.9.3