Hi community!

First of all, thanks for having developed (those of you that can relate)
and given support to this awesome tool that is Jenkins.

So, we have been using jenkins for a bit here at work. We have a big
modular project, that used to use ant to compile the several modules that
we had (the project is kinda old and by then Maven wasn't popular, i guess
that's why it wasn't born using maven to manage the dependencies).

In order to introduce the least level of changes to the developers
workflow, I have implemented a hook in the SCM *SVN for now* that detects
the modules and creates a jenkin job for each of it based on some groovy
magic and a template job.

The behaviour that we want, is the following:


We make a commit with changes to project A and B;
A is depended by C, and Z depends on C (A<- C<-Z), and B is depended by Y
(B<-Y).

So, I have implemented a hook, that does the following:

Checks if A and B are maven modules, and if they are and don't exist, it
creates a jenkins job for them.

Second, it launches the jobs for A and B, with a parameter of deploy=true
so that it will make a mvn deploy at the end, but only for A and B

Plus, seen that all of the jobs have set the option of *'Build whenever a
SNAPSHOT dependency is built'*, and the deploy parameter by default is set
to false, B will trigger a build on Y; and A will trigger a build in C, and
C will trigger a build in Z, but none of these other builds, will deploy
anything to the repository (as intended).

Also, because we have the option of '*Block build when upstream project is
building'*. If we make changes to A and Z, the building of A, blocks Z, so
that A will build first, and then Z, who will see the changes in A.

This approach however, has two problems which are the reason why I'm
writing you this somehow lengthy email (thanks for sticking around until
here). They are:

*Problem 1:* If changes are made now to B and Z, and Z is introduced with a
dependency on B (B<-Y,Z), because jenkins does not know yet that Z depends
now on B, they will be built at the same time, which can cause errors, if Z
depends on methods that were introduced in this commit to B.

*Problem 2:* A,C, and Z are committed, A has a method that C and Z now use.
A's job fails, C and Z jobs also fail, because of the dependency on A, thus
we receive by default 3 emails, and then eventually 3 other emails when A
is corrected.

So, Problem 1 is easy to solve with an extra 'round' on the build. I'm
thinking on doing something like have a cleanOnly parameter for the jobs,
which makes them simply check out the updates from the SCM, parse the new
pom, and make a mvn clean. Afterwards, Jenkins should realize that now both
Y and Z depend on B, thus B will be built first and block Z's build, when
the second normal round of builds (with cleanOnly to false) is done.

Problem 2 however, is harder to solve. We don't want that many emails to be
sent. And in case of a fail, we want only one email (the example I gave are
3 emails, which isn't that much added load to your inbox, but seen that we
have ~60 modules, and lots of dependencies, this becomes a problem). I'm
thinking on using the *'Editable email notification'* along with some
groovy magic to solve it. The idea is for instance, have a file written to
a temporary location when a fail email is sent. Afterwards, you check if
that file is there or not, if it is, you don't send anymore emails...
voodoo like that.. not sure exactly what kind of voodoo yet though.

But I'm wondering if this is the way to go. I read about the *Incremental
Builds* option and just having the *'Send e-mail for each failed
module'* unchecked
and put everything under the control of an aggregator pom. (And we have a
problem to solve before being able to use the aggregator pom, because we
use a custom Mojo that just breaks that simple aggregator pom. But my
estimation of the effort that needs to be put into solving that is less
than my estimation of solving problem 2 with groovy magic)

Any ideas or opinions if the aggregator pom is the way to go or not? should
I just stick with solving problem 2 with groovy magic, any idea which trick
of magic should I use?

Thanks in advance.
 - João Antunes

Reply via email to