18
votes

We use Jenkins as our CI system and Maven as our build tool. We have a SVN repository for our code and Artifactory for our artefacts.

The source code is organized as a multi-module maven project. Most modules contribute to the actual application, but some modules are applications thT we need during the build and test process.

We have currently multiple jobs for:

  • a quick set of commit tests
  • more extensive integration tests
  • code coverage and static code analysis
  • deployment to an test environment
  • smoke tests for that test environment

One weakness of our build process is that we compile different parts of the project in different jobs, some of the parts over and over again. Instead I would prefer to build everything once deploy it to artifactory and just use these artifacts for everything else.

But I don't know how to make sure that:

  • The size of artifactory doesn't explode, because we dump hundreds of jars every day in it
  • downstream builds use the exact set of artifacts produced by the last upstream build job an not some weird mixture of version, because it runs concurrently to the next build job, which might have deployed a new version of artifact a but not of artifact b.

Any help, pointers or ideas appreciated.

1
In response to your second concern: you can configure Jenkins quite easily so that there is only one build executor so that builds aren't executed concurrently.Caps
@Caps I know about that option, but it makes everything sequential which would slow things down tremendously.Jens Schauder
We have a 400+ multi-module project built with Jenkins. We use the incremental build option to build only the modules that changed - that brought the compilation times down a lot. There's also the Maven 3 parallel build option which we haven't tried yet.tdrury
I never noticed that feature. Gonna check it out.Jens Schauder
@JensSchauder Also try the locks & latches plugin. That will prevent jobs from executing concurrently when you need it.Joshua Davis

1 Answers

15
votes

There are many ways to answer this question. I am currently using the same set up in my development environment.

  • You can use the locks and latches plugin to make sure that things don't execute concurrently when you need it. https://wiki.jenkins-ci.org/display/JENKINS/Locks+and+Latches+plugin
  • Mix this with Maven incremental and parallel builds to speed up the individual builds.
  • Add some Jenkins slaves to get more 'executors'.
  • To avoid Artifactory bloat in your snapshot repository - Artifactory can be configured to keep a certain number of snapshots.
  • NOTE: Avoid using 'non-unique' snapshot repositories in Artifactory and Maven 3. See http://wiki.jfrog.org/confluence/display/RTF/Local+Repositories.
  • For your less frequently changed modules, make release versions. Keep those in artifactory. Use the Maven release plugin to deploy everything to Artifactory and to make all the proper version control tags (except if you are using Git, which doesn't play nice with the release plugin).
  • Use Jenkins "Disable automatic artifact archiving" for snapshot artifacts that you want to propagate via the local repository in Jenkins.
  • Use the '-U' option on your Maven builds to make sure the latest snapshots are used.

My personal preference is to keep it simple: I make a single maven module that does the whole application, where only infrequently changing code is put into a completely separate module tree / job. For simplicity, I keep the number of jobs to a minimum.

We tried using a separate job for testing, but that made it tricky to trace the source of a test failure, and it also made 'branching for prod' much more difficult.