Running Travis-CI Locally
Travis CI is now a paid only product, even for open source projects.
We have moved our continuous integration to GitHub actions (see .github folder)
The following steps can be followed to run Travis CI on your development machine, as long as you have Docker installed.
This is obviously not an “officially supported” flow, but it works.
Quick history
I found the information that got me started with this on Stackoverflow. I tried to contribute back by adding a couple observations I made, due to the fact that the Travis CI flows have been subtly changing over time!
The Workflow
Creating a local container
As mentioned, I got the idea from Stackoverflow. I modified some aspects of the flow to use a local, uncommitted branch.
This will download and run the container image:
1DTAG=$(curl -s 'https://hub.docker.com/v2/repositories/travisci/ci-sardonyx/tags/?page_size=1&page=1&ordering=last_updated' | jq -r '.results[].name')2INSTANCE="travisci/ci-sardonyx:$DTAG"3docker run --name glauth-travis-work -v "$(pwd)":/home/travis/builds/glauth/ -dit $INSTANCE /sbin/init4docker exec -it glauth-travis-work bash -l
Using the last command, I entered the container to prepare it.
CI preparation
In the container:
1su - travis 2rvm autolibs enable \ 3&& rvm install 2.3.0 \ 4&& rvm use 2.3.0 --default \ 5&& cd $HOME/builds \ 6&& git clone https://github.com/travis-ci/travis-build.git \ 7&& cd travis-build/ \ 8&& mkdir -p /home/travis/.travis \ 9&& ln -s `pwd` ~/.travis/travis-build \10&& gem update --system \11&& gem install bundler \12&& bundle update --bundler \13&& bundle install \14&& bundler binstubs travis \15&& cd $HOME/builds/glauth \16&& ~/.travis/travis-build/bin/travis compile \17| awk '!/^travis_cmd travis_wait_for_network/' \18| awk '/^travis_fold start docker_mtu_and_registry_mirrors/,/travis_time_start/ {next} 1' \19| awk '{sub(/^travis_run_checkout/, "travis_run_local_clone"); print}' > ~/ci.sh
The last command spit out Travis’ execution script with some unwanted stuff removed.
We are now going to modify it to fit our purpose by adding:
1export TRAVIS_HOME=$HOME 2cat <<'EOFUNC_LOCAL_CLONE' >>${TRAVIS_HOME}/.travis/job_stages 3function travis_run_local_clone() { 4travis_time_start 5echo 6 7travis_fold start local.clone 8 travis_cmd rm\ -f\ "$HOME/gopath/src/github.com/glauth/glauth/bin/*" 9 if [[ -d "${TRAVIS_BUILD_DIR}/glauth" ]]; then10 travis_cmd rm\ -rf\ "${TRAVIS_BUILD_DIR}/glauth"11 fi12 travis_cmd mkdir\ -p\ "${TRAVIS_BUILD_DIR}/glauth"13 travis_cmd cp\ -r\ "${TRAVIS_HOME}/builds/glauth"\ "${TRAVIS_BUILD_DIR}/glauth/"14travis_fold end local.clone15 16echo17 18travis_time_finish local_clone19:20}21 22EOFUNC_LOCAL_CLONE
Exit the container, stop it, commit it and finally delete it:
1docker stop glauth-travis-work2docker commit glauth-travis-work glauth-travis
Using our work image
1BUILDID="build-$RANDOM"2docker run --rm --name $BUILDID -v "$(pwd)":/home/travis/builds/glauth/ glauth-travis su - travis -c "cd ~/builds/glauth;bash ~/ci.sh"
Dirty speed-up
Note that, if you wish to bypass the whole container setup phase to run CI multiple times during a work session, you can run it interactively and abuse it until you are satisfied:
1BUILDID="build-$RANDOM" 2docker run --rm --name $BUILDID -v "$(pwd)":/home/travis/builds/glauth/ -dit glauth-travis /sbin/init 3docker exec -it $BUILDID bash -l 4su - travis 5bash ~/ci.sh 6# ... 7bash ~/ci.sh 8# etc. 9exit10exit11docker stop $BUILDID