Travis CI is a hosted continuous-integration service configured by a single .travis.yml file at the root of a repository. On every push or pull request it spins up a fresh virtual machine or container, runs the lifecycle you declared - install dependencies, run the build, run tests - and reports pass or fail back to the commit. It was the service that popularized free CI for open source and the convention of a YAML build file living in the repo, a pattern nearly every CI tool now copies. Travis still runs build matrices and deploy stages cleanly, though its market position has shrunk as the platform-native runners arrived.
The build lifecycle
A Travis build is an ordered set of phases. The two that matter most are install (set up dependencies) and script (the commands whose exit code decides pass or fail). Optional phases - before_install, before_script, after_success, after_failure - hook the steps around them. The language key picks a sane default toolchain.
language: python
python:
- "3.11"
services:
- postgresql
install:
- pip install -r requirements.txt
- pip install pytest dbt-postgres
before_script:
- psql -c 'CREATE DATABASE analytics;' -U postgres
script:
- pytest -q
- dbt build --target ci --fail-fast
after_failure:
- cat target/dbt.log
If any command in script exits non-zero the build is marked failed. The services key boots a Postgres instance in the build environment so the dbt run has a warehouse to target.
Build matrices and stages
Travis's most-used feature is the build matrix: list several language versions or environment variables and Travis runs the full job once per combination, in parallel. It's the standard way to test a library against every supported runtime. For multi-step delivery, build stages group jobs that run in sequence, so a deploy waits until every test job in the prior stage is green.
jobs:
include:
- stage: test
python: "3.10"
script: pytest -q
- stage: test
python: "3.11"
script: pytest -q
- stage: deploy
python: "3.11"
script: skip
deploy:
provider: script
script: bash scripts/publish_artifacts.sh
on:
branch: main
env:
global:
- secure: "encrypted-string-from-travis-encrypt"
The two test jobs run in parallel; the deploy stage runs only after both pass and only on main. Secrets go in as encrypted environment variables (travis encrypt), never plaintext in the file.
Where Travis CI fits
Travis suits a project that wants hosted CI with no infrastructure to run and a clean matrix story - testing a package across language versions is where it still shines. The trade-off is that platform-native runners now bundle CI with the code host at no extra integration cost, which is why much open source migrated off Travis. If you're choosing today, weigh it against CircleCI and GitLab CI/CD, or a self-hosted option when builds must reach private infrastructure. The infrastructure-as-code and deployment hub lays out the alternatives.
Frequently asked questions
What is a build matrix? A declaration that expands one job into many, one per combination of language version and environment variable. Travis runs them in parallel and the build passes only if every cell passes - the standard way to verify a library against all supported runtimes in a single push.
How does Travis handle secrets? Encrypt them with travis encrypt into a secure value in the YAML, or set them as protected environment variables in the project settings. Travis masks them in logs and withholds secret env vars from builds triggered by pull requests from forks, so a fork can't exfiltrate them.
Difference between the install and script phases? install sets up dependencies and a failure there errors the build; script holds the commands that actually decide pass or fail. Keeping setup in install and assertions in script makes a red build point clearly at broken tests rather than a broken environment.
Why did projects move off Travis? Platform-native CI runners arrived bundled with the code host, removing a separate service to authorize and configure, and offered generous free minutes. Travis still works and its matrix support is strong, but for a new project the bundled runner is usually the lower-friction default.