Migrate from Travis to Azure Pipelines - Azure Pipelines (2024)

  • Article

Azure DevOps Services

This purpose of this guide is to help you migrate from Travis to Azure Pipelines. This guide describes shows how to translate from a Travis configuration to an Azure Pipelines configuration.

We need your help to make this guide better! Submit comments or contribute your changes directly.

Key differences

There are many differences between Travis and Azure Pipelines, including:

  • Travis builds have stages, jobs and phases, while Azure Pipelines has steps that can be arranged and executed in an arbitrary order or grouping that you choose.

  • Azure Pipelines allows job definitions and steps to be stored in separate YAML files in the same or a different repository, enabling steps to be shared across multiple pipelines.

  • Azure Pipelines provides full support for building and testing on Microsoft-managed Linux, Windows, and macOS images. For more information about hosted agents, see Microsoft-hosted agents.

Prerequisites

  • A GitHub account where you can create a repository. Create one for free.
  • An Azure DevOps organization. Create one for free.If your team already has one, then make sure you're an administrator of the Azure DevOps project that you want to use.
  • An ability to run pipelines on Microsoft-hosted agents. You can either purchase a parallel job or you can request a free tier.
  • Basic knowledge of Azure Pipelines. If you're new to Azure Pipelines, see the following to learn more about Azure Pipelines and how it works prior to starting your migration:
    • Create your first pipeline
    • Key concepts for new Azure Pipelines users

Language

Travis uses the language keyword to identify the prerequisite buildenvironment to set up for your build. For example, to select Node.JS16.x:

.travis.yml

language: node_jsnode_js: - 16

Microsoft-hosted agents contain the SDKs for many languages by default. To use a specific language version, you may need to use a language selection taskto set up the environment.

For example, to select Node.JS 16.x:

azure-pipelines.yml

steps:- task: UseNode@1 inputs: version: '16.x'

Language mappings

The language keyword in Travis implies both that versionof language tools be used and that many build steps be implicitlyperformed. In Azure Pipelines, you need to specify the commands that you want to run.

Here's a translation guide from the language keyword to the commandsthat are executed automatically for the most commonly used languages:

LanguageCommands
c
cpp
./configure
make
make install
csharpnuget restore [solution.sln]
msbuild /p:Configuration=Release [solution.sln]
clojurelein deps
lein test
gogo get -t -v ./...
make or go test
java
groovy
Gradle:
gradle assemble
gradle check

Maven:
mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V
mvn test -B

Ant:
ant test

node_jsnpm install or npm ci or yarn
npm test
objective-c
swift
pod install or bundle exec pod install
xcodebuild -scheme [scheme] build test \| xcpretty
perlcpanm --quiet --installdeps --notest .

Build.PL:
perl ./Build.pl
./Build test

Makefile.PL:
perl Makefile.PL
make test

Makefile:
make test

phpphpunit
pythonpip install -r requirements.txt
rubybundle install --jobs=3 --retry=3
rake

In addition, less common languages can be enabled but require anotherdependency installation step or execution inside a docker container:

LanguageCommands
crystaldocker run -v $(pwd):/src -w /src crystallang/crystal shards install
docker run -v $(pwd):/src -w /src crystallang/crystal crystal spec
dsudo wget http://master.dl.sourceforge.net/project/d-apt/files/d-apt.list -O /etc/apt/sources.list.d/d-apt.list
sudo apt-get update
sudo apt-get -y --allow-unauthenticated install --reinstall d-apt-keyring
sudo apt-get update
sudo apt-get install dmd-compiler dub
dub test --compiler=dmd
dartwget https://dl-ssl.google.com/linux/linux_signing_key.pub -O - \| sudo apt-key add -
wget https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list -O /etc/apt/sources.list.d/dart_stable.list
sudo apt-get update
sudo apt-get install dart
/usr/lib/dart/bin/pub get
/usr/lib/dart/bin/pub run test
erlangsudo apt-get install rebar
rebar get-deps
rebar compile
rebar skip_deps=true eunit
elixirsudo apt-get install elixir
mix local.rebar --force
mix local.hex --force
mix deps.get
mix test
haskellsudo apt-get install cabal-install
cabal install --only-dependencies --enable-tests
cabal configure --enable-tests
cabal build
cabal test
haxesudo apt-get install haxe
yes \| haxelib install [hxml]
haxe [hxml]
juliasudo apt-get install julia
julia -e "using Pkg; Pkg.build(); end"
julia --check-bounds=yes -e "Pkg; Pkg.test(coverage=true); end"
nixdocker run -v $(pwd):/src -w /src nixos/nix nix-build
perl6sudo apt-get install rakudo
PERL6LIB=lib prove -v -r --exec=perl6 t/
rustcurl -sSf https://sh.rustup.rs | sh -s -- -y
cargo build --verbose
cargo test --verbose
scalaecho "deb https://repo.scala-sbt.org/scalasbt/debian /" | /etc/apt/sources.list.d/sbt.list
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2EE0EA64E40A89B84B2DF73499E82A75642AC823
sudo apt-get update
sudo apt-get install sbt
sbt ++2.11.6 test
smalltalkdocker run -v $(pwd):/src -w /src hpiswa/smalltalkci smalltalkci

Multiple language selections

You can also configure an environment that supports buildingdifferent applications in multiple languages. For example, to ensure thebuild environment targets both Node.JS 16.x and Ruby 3.2 or better:

azure-pipelines.yml

steps:- task: UseNode@1 inputs: version: '8.x'- task: UseRubyVersion@0 inputs: versionSpec: '>= 3.2'

Phases

In Travis, steps are defined in a fixed set of named phases such asbefore_install or before_script. Azure Pipelines doesn't have named phases and steps can be grouped, named, and organized in whatever way makes sense for the pipeline.

For example:

.travis.yml

before_install: - npm install -g bowerinstall: - npm install - bower installscript: - npm run build - npm test

azure-pipelines.yml

steps:- script: npm install -g bower- script: npm install- script: bower install- script: npm run build- script: npm test

Alternatively, steps can be grouped together and optionally named:

azure-pipelines.yml

steps:- script: | npm install -g bower npm install bower install displayName: 'Install dependencies'- script: npm run build- script: npm test

Parallel jobs

Travis provides parallelism by letting you define a stage, whichis a group of jobs that are executed in parallel. A Travis build canhave multiple stages; once all jobs in a stage have completed, the next stage starts.

With Azure Pipelines, you can makeeach step or stage dependent on any other step. In this way, you specify whichsteps run serially, and which can run in parallel.So you can fan out with multiple steps run in parallel afterthe completion of one step, and then fan back in with a single step that runs afterward.This model gives you options to define complex workflows if necessary. For now, here'sa simple example:

Migrate from Travis to Azure Pipelines - Azure Pipelines (1)

For example, to run a build script, then upon its completion run both theunit tests and the integration tests in parallel, and once all tests havefinished, package the artifacts and then run the deploy to pre-production:

.travis.yml

jobs: include: - stage: build script: ./build.sh - stage: test script: ./test.sh unit_tests - script: ./test.sh integration_tests - stage: package script: ./package.sh - stage: deploy script: ./deploy.sh pre_prod

azure-pipelines.yml

jobs:- job: build steps: - script: ./build.sh- job: test1 dependsOn: build steps: - script: ./test.sh unit_tests- job: test2 dependsOn: build steps: - script: ./test.sh integration_tests- job: package dependsOn: - test1 - test2 script: ./package.sh- job: deploy dependsOn: package steps: - script: ./deploy.sh pre_prod

Advanced parallel execution

In Azure Pipelines you have more options and control over how you orchestrate your pipeline.

For example, a team has a set of fast-running unit tests, and another set of and slower integration tests. The team wants to begin creating the .ZIP file for a release as soon as the unit are completed because they provide high confidencethat the build provides a good package. But before they deploy to pre-production, they want to wait until all tests have passed:

Migrate from Travis to Azure Pipelines - Azure Pipelines (2)

In Azure Pipelines they can do it this way:

azure-pipelines.yml

jobs:- job: build steps: - script: ./build.sh- job: test1 dependsOn: build steps: - script: ./test.sh unit_tests- job: test2 dependsOn: build steps: - script: ./test.sh integration_tests- job: package dependsOn: test1 script: ./package.sh- job: deploy dependsOn: - test1 - test2 - package steps: - script: ./deploy.sh pre_prod

Step reuse

In Travis you can use matrices to run multiple executions across a singleconfiguration. In Azure Pipelines you can use matrices in the same way, but you can also implement configuration reuse with templates.

Example: Environment variable in a matrix

One of the most common ways to run several builds with a slight variationis to change the execution using environment variables. For example, yourbuild script can look for the presence of an environment variable and changethe way your software is built, or the way it's tested.

You can use a matrix to have run a build configuration severaltimes, once for each value in the environment variable. For example,to run a given script three times, each time with a different setting foran environment variable:

.travis.yml

os: osxenv: matrix: - MY_ENVIRONMENT_VARIABLE: 'one' - MY_ENVIRONMENT_VARIABLE: 'two' - MY_ENVIRONMENT_VARIABLE: 'three'script: echo $MY_ENVIRONMENT_VARIABLE

azure-pipelines.yml

pool: vmImage: 'macOS-latest'strategy: matrix: set_env_to_one: MY_ENVIRONMENT_VARIABLE: 'one' set_env_to_two: MY_ENVIRONMENT_VARIABLE: 'two' set_env_to_three: MY_ENVIRONMENT_VARIABLE: 'three'steps:- script: echo $(MY_ENVIRONMENT_VARIABLE)

Example: Language versions in a matrix

Another common scenario is to run against severaldifferent language environments. Travis supports an implicit definitionusing the language keyword, while Azure Pipelines expects an explicittask to define how to configure that language version.

You can use the environment variable matrix options in Azure Pipelinesto enable a matrix for different language versions. For example, you canset an environment variable in each matrix variable that corresponds to thelanguage version that you want to use, then in the first step, use thatenvironment variable to run the language configuration task:

.travis.yml

os: linuxmatrix: include: - rvm: 2.3.7 - rvm: 2.4.4 - rvm: 2.5.1script: ruby --version

azure-pipelines.yml

vmImage: 'ubuntu-latest'strategy: matrix: ruby 2.3: ruby_version: '2.3.7' ruby 2.4: ruby_version: '2.4.4' ruby 2.5: ruby_version: '2.5.1'steps:- task: UseRubyVersion@0 inputs: versionSpec: $(ruby_version)- script: ruby --version

Example: Operating systems within a matrix

It's also common to run builds in multiple operating systems. Travissupports this definition using the os keyword, while Azure Pipelineslets you configure the operating system by selecting the pool to run inusing the vmImage keyword.

For example, you can set an environment variable in each matrix variablethat corresponds to the operating system image that you want to use. Thenyou can set the machine pool to the variable you've set:

.travis.yml

matrix: include: - os: linux - os: windows - os: osxscript: echo Hello, world!

azure-pipelines.yml

strategy: matrix: linux: imageName: 'ubuntu-latest' mac: imageName: 'macOS-latest' windows: imageName: 'windows-latest'pool: vmImage: $(imageName)steps:- script: echo Hello, world!

Success and failure handling

Travis allows you to specify steps that run when the build succeeds,using the after_success phase, or when the build fails, using theafter_failure phase. With Azure Pipelines you can define success and failureconditions based on the result of any step, which enables more flexibleand powerful pipelines.

.travis.yml

build: ./build.shafter_success: echo Success after_failure: echo Failed 

azure-pipelines.yml

steps:- script: ./build.sh- script: echo Success condition: succeeded()- script: echo Failed condition: failed()

Advanced success and failure handling

In Azure Pipelines you can program a flexible set of dependencies andconditions for flow control between jobs.
You can configure jobs to run based on the success orfailure of previous jobs or based on environment variables.You can even configure jobs to always run,regardless of the success of other jobs.

For example, if you want to run a script when the build fails, but onlyif it's running as a build on the main branch:

azure-pipelines.yml

jobs:- job: build steps: - script: ./build.sh- job: alert dependsOn: build condition: and(failed(), eq(variables['Build.SourceBranch'], 'refs/heads/main')) steps: - script: ./sound_the_alarms.sh

Predefined variables

Both Travis and Azure Pipelines set multiple environment variablesto allow you to inspect and interact with the execution environment of theCI system.

In most cases, there's an Azure Pipelines variable to matchthe environment variable in Travis. Here's a list of commonly usedenvironment variables in Travis and their analog in Azure Pipelines:

TravisAzure PipelinesDescription
CI=true or TRAVIS=trueTF_BUILD=TrueIndicates that your build is running in the CI system; useful for scripts that are also intended to be run locally during development.
TRAVIS_BRANCHCI builds:
BUILD_SOURCEBRANCH

Pull request builds:
SYSTEM_PULLREQUEST_TARGETBRANCH

The name of the branch the build was queued for, or the name of the branch the pull request is targeting.
TRAVIS_BUILD_DIRBUILD_SOURCESDIRECTORYThe location of your checked out source and the default working directory.
TRAVIS_BUILD_NUMBERBUILD_BUILDIDA unique numeric identifier for the current build invocation.
TRAVIS_COMMITCI builds:
BUILD_SOURCEVERSION
The commit ID currently being built.
TRAVIS_COMMITPull request builds:
git rev-parse HEAD^2
For pull request validation builds, Azure Pipelines sets BUILD_SOURCEVERSION to the resulting merge commit of the pull request into main; this command identifies the pull request commit itself.
TRAVIS_COMMIT_MESSAGEBUILD_SOURCEVERSIONMESSAGEThe log message of the commit being built.
TRAVIS_EVENT_TYPEBUILD_REASONThe reason the build was queued; a map of values is in the "build reasons" table below.
TRAVIS_JOB_NAMEAGENT_JOBNAMEThe name of the current job, if specified.
TRAVIS_OS_NAMEAGENT_OSThe operating system that the job is running on; a map of values is in the "operating systems" table below.
TRAVIS_PULL_REQUESTAzure Repos:
SYSTEM_PULLREQUEST_PULLREQUESTID

GitHub:
SYSTEM_PULLREQUEST_PULLREQUESTNUMBER

The pull request number that triggered this build. (For GitHub builds, this is a unique identifier that is not the pull request number.)
TRAVIS_PULL_REQUEST_BRANCHSYSTEM_PULLREQUEST_SOURCEBRANCHThe name of the branch where the pull request originated.
TRAVIS_PULL_REQUEST_SHAPull request builds:
git rev-parse HEAD^2
For pull request validation builds, Azure Pipelines sets BUILD_SOURCEVERSION to the resulting merge commit of the pull request into main; this command identifies the pull request commit itself.
TRAVIS_PULL_REQUEST_SLUGThe name of the forked repository, if the pull request originated in a fork. There's no analog to this in Azure Pipelines.
TRAVIS_REPO_SLUGBUILD_REPOSITORY_NAMEThe name of the repository that this build is configured for.
TRAVIS_TEST_RESULTAGENT_JOBSTATUSTravis sets this value to 0 if all previous steps have succeeded (returned 0). For Azure Pipelines, check that AGENT_JOBSTATUS=Succeeded.
TRAVIS_TAGBUILD_SOURCEBRANCHIf this build was queued by the creation of a tag then this is the name of that tag. For Azure Pipelines, the BUILD_SOURCEBRANCH is set to the full Git reference name, for example, refs/tags/tag_name.
TRAVIS_BUILD_STAGE_NAMEThe name of the stage in Travis. As we saw earlier, Azure Pipelines handles flow control using jobs. You can reference AGENT_JOBNAME.

Build Reasons:

The TRAVIS_EVENT_TYPE variable contains values that map to values provided by the Azure Pipelines BUILD_REASON variable:

TravisAzure PipelinesDescription
pushIndividualCIThe build is a continuous integration build from a push.
pull_requestPullRequestThe build was queued to validate a pull request.
apiManualThe build was queued by the REST API or a manual request on the web page.
cronScheduleThe build was scheduled.

Operating Systems:

The TRAVIS_OS_NAME variable contains values that map to values provided by the Azure Pipelines AGENT_OS variable:

TravisAzure PipelinesDescription
linuxLinuxThe build is running on Linux.
osxDarwinThe build is running on macOS.
windowsWindows_NTThe build is running on Windows.

To learn more, see Predefined environment variables.

If there isn't a variable for the data you need, then you can use a shellcommand to get it. For example, a good substitute of an environmentvariable containing the commit ID of the pull request being built is torun a git command: git rev-parse HEAD^2.

Building specific branches

By default, both Travis and Azure Pipelines perform CI builds on allbranches. Similarly, both systems allow you to limit these builds tospecific branches. In Azure Pipelines, the list of branches to buildshould be listed in the include list and the branches not to buildshould be listed in the `exclude list. Wildcards are supported.

For example, to build only the main branch and those that begin withthe word "releases":

.travis.yml

branches: only: - main - /^releases.*/

azure-pipelines.yml

trigger: branches: include: - main - releases*

Output caching

Travis supports caching dependencies and intermediate build output to improvebuild times. Azure Pipelines doesn't support caching intermediate buildoutput, but does offer integration withAzure Artifactsfor dependency storage.

Git submodules

Travis and Azure Pipelines both clone git repos "recursively" bydefault. This means that submodules are cloned by the agent, whichis useful since submodules usually contain dependencies.However, the extra cloning takes time, so if you don't need the dependenciesthen you can disable cloning submodules:

.travis.yml

git: submodules: false

azure-pipelines.yml

checkout: submodules: false
Migrate from Travis to Azure Pipelines - Azure Pipelines (2024)
Top Articles
Latest Posts
Article information

Author: Edwin Metz

Last Updated:

Views: 5706

Rating: 4.8 / 5 (78 voted)

Reviews: 85% of readers found this page helpful

Author information

Name: Edwin Metz

Birthday: 1997-04-16

Address: 51593 Leanne Light, Kuphalmouth, DE 50012-5183

Phone: +639107620957

Job: Corporate Banking Technician

Hobby: Reading, scrapbook, role-playing games, Fishing, Fishing, Scuba diving, Beekeeping

Introduction: My name is Edwin Metz, I am a fair, energetic, helpful, brave, outstanding, nice, helpful person who loves writing and wants to share my knowledge and understanding with you.