Developing a Maven extension to activate profiles based on Git

746 views
Skip to first unread message

Shahim Essaid

unread,
Oct 4, 2013, 7:50:56 PM10/4/13
to jenkins...@googlegroups.com
Hi all,

I'm new to Jenkins and finding it very useful. I'm also getting used to the Git flow pattern and I wanted to integrate it with my Jenkins builds so I started to develop a Maven extension to do that.

Basically, my extension will do the following:

1.  Find the checked out Git ref (from the repository, or from a Maven command line property for overrides or when HEAD is detached) and matche it with a regular expression pattern provided in a specific profile property. If there is a match, the profile is active. (The extension does some checking to try to find the correct Git repository (not working trees) for each project/pom.xml file in case there are multiple Git repositories involved in the build.)
2.  Get the HEAD commit message and do a similar regular expression match. If a match is found, the profile is active but only for this commit.
3.  Check the commit messages starting from HEAD, up to some depth, for a regular expression match for an on/off  indicator.  This allows one to turn on a profile in a commit message and the profile will remain active until it is turned off in a later message. 

This will be an extension that is placed in the "ext" directory in the Maven installation. I'm just getting started but I should have something functional in few days or weeks and I'll share it on Github when it is ready. I would appreciate any feedback or other use cases for how I can make this extension more useful in the context of Jenkins builds.

Thanks,
Shahim

Stephen Connolly

unread,
Oct 4, 2013, 8:48:00 PM10/4/13
to jenkins...@googlegroups.com
Just a question, what is the problem you are trying to solve... Or perhaps to put it another way, *why* would I want this?
--
You received this message because you are subscribed to the Google Groups "Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-use...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


--
Sent from my phone

Shahim Essaid

unread,
Oct 4, 2013, 10:10:53 PM10/4/13
to jenkins...@googlegroups.com
On Fri, Oct 4, 2013 at 5:48 PM, Stephen Connolly <stephen.al...@gmail.com> wrote:
Just a question, what is the problem you are trying to solve... Or perhaps to put it another way, *why* would I want this?

 
The Git flow pattern recommends a pattern for branching and branch naming that can be easily mapped to various types of builds (unit, integration, QA, deplyment, etc.). Maven profiles are the usual way for customizing a Maven build but the standard profile activation mechanism is not that flexible. For example, I can't say that I want a profile activated if a specific Git branch/tag pattern is checked out.

Also, I would like to solve this in Maven instead of doing it with custom Jenkins scripts or plugins. That way I can get the same behavior when a build is done outside Jenkins. The main feature I need is the first one described earlier where a build depends on the checked out branch.  In Jenkins, the Jenkins Git plugin checks out a detached head (not a branch) and keeps the branch information as an environment variable but even with this variable the default Maven activation doesn't allow wildcard or regex matching on the values so it is not that useful.

The idea is that when the Jenkins Git plugin builds all the changed branches from a repository (one by one in one Jenkins Job) the various build behaviors can be triggered by the current branch being built. To do that I am adding a new ProfileActivator [1] to activate profiles based on Git information.  This is the general idea. I am sure there are other ways around this but I would like to make my Maven builds aware of their Git context. Also, this is a good excerise for me to learn all the relevant APIs but I also think that it might be useful for other Jenkins/Maven/Git users. Hope this helps clarify why I am doing this.

[1] http://maven.apache.org/ref/3.1.0/maven-model-builder/apidocs/org/apache/maven/model/profile/activation/ProfileActivator.html

Shahim



--
You received this message because you are subscribed to a topic in the Google Groups "Jenkins Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jenkinsci-users/aOPAkUPQLws/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jenkinsci-use...@googlegroups.com.

Stephen Connolly

unread,
Oct 5, 2013, 4:37:12 AM10/5/13
to jenkins...@googlegroups.com


On Saturday, 5 October 2013, Shahim Essaid wrote:

On Fri, Oct 4, 2013 at 5:48 PM, Stephen Connolly <stephen.al...@gmail.com> wrote:
Just a question, what is the problem you are trying to solve... Or perhaps to put it another way, *why* would I want this?

 
The Git flow pattern recommends a pattern for branching and branch naming that can be easily mapped to various types of builds (unit, integration, QA, deplyment, etc.). 

I have not seen that anywhere, do you have any example links?
 
Maven profiles are the usual way for customizing a Maven build but the standard profile activation mechanism is not that flexible. For example, I can't say that I want a profile activated if a specific Git branch/tag pattern is checked out. 

Using profiles to *heavily* customize a build is usually a bad plan.

99 times out of 100 what you probably want is to enable/disable a specific execution of a plugin.

Most plugins have a `skip` parameter. A plugin bound to the `validate` phase could set properties based on the checked out tag and then those properties could be used to tweak the skip tags of the different plugins... Better yet you could have two profiles: one that binds the plugin to `validate` if the file `${basedir}/.git/HEAD` exists and the other that sets "sensible" defaults if the file is not there (eg if a source bundle had been checked out)

There are limits to the above, eg multi-module builds, but in general you will hit similar issues with profiles (you just don't notice as most people just push maven all the way to `install` most of the time ... And pair with `clean` too... Working around their problems in mis-understanding maven by bashing both it and themselves on the head repeatedly)
 
Also, I would like to solve this in Maven instead of doing it with custom Jenkins scripts or plugins. That way I can get the same behavior when a build is done outside Jenkins. The main feature I need is the first one described earlier where a build depends on the checked out branch.  In Jenkins, the Jenkins Git plugin checks out a detached head (not a branch) and keeps the branch information as an environment variable but even with this variable the default Maven activation doesn't allow wildcard or regex matching on the values so it is not that useful. 

Have you had a look at literate builds by the way? (The multi-branch is what you'll be most interested in)
 
The idea is that when the Jenkins Git plugin builds all the changed branches from a repository (one by one in one Jenkins Job) the various build behaviors can be triggered by the current branch being built. To do that I am adding a new ProfileActivator [1] to activate profiles based on Git information.  This is the general idea. I am sure there are other ways around this but I would like to make my Maven builds aware of their Git context. Also, this is a good excerise for me to learn all the relevant APIs but I also think that it might be useful for other Jenkins/Maven/Git users. Hope this helps clarify why I am doing this.

[1] http://maven.apache.org/ref/3.1.0/maven-model-builder/apidocs/org/apache/maven/model/profile/activation/ProfileActivator.html 

I am less keen on this approach as it requires installing the activator in your maven... That way ant/lib madness lies
Reply all
Reply to author
Forward
0 new messages