In the past I have used Jenkins excessively both professionally as well as for my private / open source projects. For the latter, I run and maintained my own Jenkins instance, running on an HP server in my basement 🙂
I am currently trying to become as „lean“ as possible, reducing maintenance efforts and freeing time to focus on doing what I like most: solving users problems by providing software solutions. Migrating from Jenkins to travis-ci.org is part of this effort. Don’t get me wrong – I am still convinced Jenkins is a great tool and will continue to use it professionally.
Here’s some of the requirements I had:
- builds for mainly Java projects, using a mixture of Ant, Maven and Gradle
- running unit, regression and integration tests
- utilizing MySQL databases in the scope of tests
- providing Javadocs
- providing artefacts
- providing test results
- securely running tests against externally hosted APIs
Builds are described in YAML syntax in a file .travis.yml in the root of your repository. Most common build tools and databases (e.g. MongoDB, MySQL) are preinstalled in the build container (an Amazon EC2 Ubuntu instance, it seems). For now, we’re just specifying we’re building Java projects using Oracle JDK 8, with some optional steps to perform before the builds are run. For the actual builds, I am using a script section.
language: java jdk: - oraclejdk8 before_install: - mkdir /home/travis/j-lawyer-backup script: ant -buildfile j-lawyer-client/build.xml default
Setting up Travis CI
This is self-explanatory – head over to travis-ci.org, sign in with your GitHub account and activate your repositories.
For some of my tests, I need to load database dumps or access databases using MySQL clients. In order to do that, you need to
- enable sudo
- enable MySQL on the build container
- change the MySQL password
- restart the MySQL service
Here are the relevant snippets from .travis.yml:
services: mysql sudo: true language: java jdk: - oraclejdk8 before_install: - sudo mysql -e "use mysql; update user set password=PASSWORD('travisci') where User='root'; update user set plugin='mysql_native_password';commit;FLUSH PRIVILEGES;" - sudo service mysql restart
Strangely, the Travis CI docs had a different SQL command for changing the password which did not work for me, but after some fiddling I got it working.
Pulling external data
For some tests, I am using larger files that I do not check in to SCM because they hardly change and it does not make a lot of sense to store larger binaries in a versioning system. With Jenkins, these files were just sitting on the host in a dedicated folder.
Now, with Travis CI, I have loaded it as tarballs on some public server and get it from there. In order to do that, I use wget and tar. Both must be installed before the builds – so those are just some additional steps in .travis.yml’s before_install section:
before_install: - mkdir /home/travis/j-lawyer-backup - cd /home/travis/j-lawyer-backup - sudo apt-get install wget - sudo apt-get install tar - wget https://www.j-lawyer.org/downloads/travisci/backups/backups.tar.gz - tar -m -xvzf backups.tar.gz - cd /home/travis/build/jlawyerorg/j-lawyer-org
Some things are noteworthy: you can freely create directories using mkdir, and use apt package management with full privileges. TAR gave me errors due to issues with the timestamps of the files (timestamp was in the future). Therefore I added the -m switch to make tar ignore the timestamps.
And: do not forget to „cd“ back into the directory that has the clone of the repository, otherwise your build files will not be found.
Displaying Travis CI build status on GitHub project pages
This could not be easier – in your Travis CI build page, there is a status indicator at the top. Copy the image location and paste it to a README.md in your repository root, e.g. like this:
Secure use of credentials
I need to run a set of tests against externally hosted APIs provided by third party. While this is easy to manage in a private and local Jenkins instance, some adjustments where needed to securely execute the tests without letting the public access e.g. credentials.
Travis CI has functionality to provide environment variables to the build processes. Those environment variables can only be managed by the repository owners. They are stored securely and will be stripped off the output of the builds.
Bottom line: adjust your tests to make use of environment variables and then specify them in Travis CI.
Often times, I am running tests locally before I commit code. This also makes sense because it does not require the code to be committed and Travis CI picking up the changes, which can take a bit of time.
What I did was the following: I have set up an environment variable on Travis CI „runningontravis“ with value „true“. Some of my test classes check for this variable and use a different initialization, e.g. taking parameters from environment variables (in case of running on Travis CI) or from a local properties file (when run locally).
Migrating to Travis CI was really easy and took me around two hours for nine projects. I can get rid of my self-hosted Jenkins and save time and energy, relying on Travis CI infrastructure. .travis.yml has grown in comparison to the snippets above, but is still rather small and manageable. You can check out an example here.
However, there are still some challenges to be solved:
- My build logs are currently > 8000 lines. Jenkins provided a nice navigation pane on the left, allowing me to jump to a specific piece of the build. Very handy. Travis CI lacks this feature.
- Access to test results, Javadocs and artefacts: Jenkins can be configured to show all of these on the build page – you can access all of the workspace, display test results with drill down capabilities and many more. This is not available in Travis CI.
For me, there are more pros than cons, and I will look into finding solutions the the items named above.
Let me know if you have any ideas you could share 🙂