travis-ci, or how continuous integration will become fun again

First of all, I need to say that I definitely will not compare tools in this post. This usually leads to nothing but flame wars and too much blog moderation effort. What I want is to show my view at an emerging tool / approach / idea. That clarified, let’s move on.

So, I think that with travis-ci, continuous integration will become fun again. If that’s enough information for you, please let me know, and I’ll tweet it out since this statement fits into 140 characters. If you want to know more about my opinion, read on.

Let’s start like this: when you want your Java project to be continously integrated and your infrastructure is all set up, you just add a YAML file called .travis.yml to your project. The file contains only this:

language: java

Then, you push your repo changes upstream and enjoy your project getting built / integrated / tested or whatever you like it to get by looking at the build dashboard of your own repos on http://travis-ci.org. That’s it.

Now you will of course say: huh? Are you kidding me?

Actualy, I’m not. But I said something like “…and if your infrastructure is all set up…”. That’s what you miss here. Let me explain this part for a minimal possible Java project.

My minimal project will consist of one single class:

package org.pbit.ci.travis.java;
public class Main {
 
    public static void main(String [] args) {
        System.out.println("hey, travis");
    }
}

And one single unit test, that, for simplicity reasons, has nothing to do with my class and will always succeed:

package org.pbit.ci.travis.java;
 
import org.junit.Test;
import static org.junit.Assert.assertTrue;
 
public class TestTest {
 
    @Test
    public void testTest() {
        assertTrue(1 == 1);
    }
}

Now you need to decide how you build your project: with Ant, Maven or Gradle. Or whatever tool wants to own the market in the future. I did it with Ant – for nostalgia reasons:

<project name="travis playground" default="dist" basedir=".">
    <description>
        travis stuff
    </description>
 
  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist"  location="dist"/>
  <property name="test"  location="test"/>
  <property name="junit" location="lib/junit.jar"/>
 
  <path id="classpath.test">
    <pathelement location="${junit}" />
    <pathelement location="${test}" />
    <pathelement location="${build}/main"/>
    <pathelement location="${build}/test"/>
  </path>
 
  <target name="init">
    <tstamp/>
    <mkdir dir="${build}"/>
    <mkdir dir="${build}/test"/>
    <mkdir dir="${build}/main"/>
  </target>
 
  <target name="compile" depends="init" description="compile">
    <javac srcdir="${src}" destdir="${build}/main"/>
    <javac srcdir="${test}" destdir="${build}/test">
      <classpath>
        <pathelement location="${junit}"/>
      </classpath>
    </javac>
  </target>
 
  <target name="dist" depends="compile">
    <mkdir dir="${dist}/lib"/>
    <jar jarfile="${dist}/lib/travis-playground-${DSTAMP}.jar" basedir="${build}"/>
  </target>
 
  <target name="test" depends="compile">
    <junit fork="yes" haltonfailure="true">
      <classpath refid="classpath.test" />
      <batchtest fork="yes" todir="tres">
        <formatter type="brief" usefile="false"/>
        <fileset dir="${test}">
          <include name="**/*Test*.java"/>
        </fileset>
      </batchtest>
    </junit>
  </target>
 
  <target name="clean" description="clean up" >
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>

As much as this. But this project can be built, and tests can be executed. The sources or the build process as well as tests could depend on different operating systems, existing software and so on and so forth. And, it also could be something different than Java (indeed, there is software around which is not written in Java, so don’t panic). It could be written in Clojure or Scala or JRuby or even not run on the JVM at all (before you panic again: there is indeed software which doesn’t need the JVM to run). It can be written in Erlang, Ruby or whatnot. You get the picture – you can run plenty of projects on travis-ci.

But you still don’t know how yet. So, back to the infrastructure. I have this tiny little project on GitHub. And that’s the main thing: GitHub is the center of your travis-ci infrastructure. Right now, you can only have your repositories on GitHub and use it actively.

How? You need to allow travis-ci to have access to your GitHub repositories. Go to travis-ci.org and register there with your GitHub account. Thus you allow travis-ci to “link” with your GitHub account as application.

Next, you need to have a project in a repo like mine that you will build with travis-ci. Create or use one or just clone mine (don’t forget the minimal YAML file) and go to your profile page under travis-ci.org. There, you can set the travis-ci hooks to On. This will say GitHub that whenever a considerable change in this repo happens, such as a commit pushed upstream, it should propagate (push) this event to travis-ci.org.

When you have linked travis and GitHub through a repo, just push this repo to GitHub. What happens then, is travis-magic. It will check out your repo, assign a worker to your build, which is basically a baseline based VM, configured for your needs (actually preconfigured), fire it up, provision your stuff there and run your tests.

Look at the build.xml up there. The target test is what will by default run by Ant on the worker VM. You can change it through YAML configuration, but let’s skip it here. What you do with travis-ci is a lot of convention over configuration for typical CI cases, and you should change these things only if you leave the zone of typical cases. Of course, every project is different, but travis’ abstractions are abstract enough to fit in most cases.

Anyway, you switch over to the dashboard on travis-ci.org, go to the tab My Repositories and look how your project gets built and how your tests get executed. If it runs locally and you have provided everything with your GitHub repo (like me, I also pushed libraries upstream. You can lynch me for that I didn’t use Ivy, but I’m fine with it), travis will be also able to do what you did locally.

Here is what I see with my huge project:

As you can see, everything ran successful. Now you can abstract and imagine that you can build and test and integrate, well, everything this way. And you have the infrastructure behind the tiny YAML file I’ve shown you at the beginning.

The next question I already hear is: so what? Jenkins is around, it works just fine.

Let me tell you a little about travis. It’s been created as hosted CI environment for Ruby projects and then has been continuously improved and extended to build any sort of open source project in a hosted environment. In the list of currently running projects you can find prominent names from the Ruby, Erlang, Scala and now more and more Java world.

What is really cool about travis, is that you keep your CI configuration with the project, versioned in the repo, instead of having it in one central place without possibility to reuse it. The next thing that is cool is that travis can seemlessly fire up VMs to build your stuff. You tell it what to do, and it does.

Next cool thing is the auto-inspection of your project. You can seemlessly switch from Ant to Gradle, and it will do. You only name a platform and maybe some version constraints, and it will do. You can check out whatever weird software constellation you like, and it will fire up the right worker for you and do.

You don’t need a sysop to set up your CI environment(s), you can as dev just manage your travis with its VMs and the way it provisions stuff to them. You can script around its lifecycle for more flexibility. And so on and so forth – check out this piece of online documentation for what you can do with your build configuration.

But. At the moment of writing, it’s not a trivial task to have travis-ci running in your local environment, but I managed this. How I did it, is worth a separate blog post and a couple of beers. The project is right now a moving target, and its devs name it as it is: alpha.

But the way for travis leads through the hosted solution for open source projects to an enterprise edition for sure, that you can run together with enterprise GitHub in your enterprise environment. Now you surely can imagine what you can achieve through it later.

So yes, travis is still alpha, but emerging like hell and anytime worth being observed and tested from time to time. It’s a pretty complex technical solution. Guys working on it are very smart and well known hackers. And now more and more hackers, open source projects and sponsors go to travis. That’s really a fact, so expect a lot of movement and noise there.

So when you’re into CI somehow, you don’t want to miss this name, its idea and its approach to do CI for you. Even if Jenkins is around and works just fine.

Enjoy.

  • Facebook
  • Delicious
  • Digg
  • StumbleUpon
  • Reddit
  • Blogger
  • LinkedIn
Pavlo Baron

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>