views:

615

answers:

4

I have a project that need to be deployed into multiple environments (prod, test, dev). The main differences mainly consist in configuration properties/files.

My idea was to use profiles and overlays to copy/configure the specialized output. But I'm stuck into if I have to generate multiple artifacts with specialized classifiers (ex: "my-app-1.0-prod.zip/jar", "my-app-1.0-dev.zip/jar") or should I create multiple projects, one project for every environment ?!
Should I use maven-assembly-plugin to generate multiple artifacts for every environment ? Anyway, I'll need to generate all them at once so it seams that the profiles does not fit ... still puzzled :(

Any hints/examples/links will be more than welcomed.

As a side issue, I'm also wondering how to achieve this in a CI Hudson/Bamboo to generate and deploy these generated artifacts for all the environments, to their proper servers (ex: using SCP Hudson plugin) ?

+2  A: 

I would use the version element (like 1.0-SNAPSHOT, 1.0-UAT, 1.0-PROD) and thus tags/branches at the VCS level in combination with profiles (for environments specific things like machines names, user name passwords, etc), to build the various artifacts.

Pascal Thivent
Hmm.. But how a snapshot version for PROD will look like ? I considered to use classifiers instead, so I can have 1.0-SNAPSHOT-PROD.jar and the assembly plugin to generate them all ... Since env/staging issues are quite general I thought that a best practice will exist in regard of it. If you have a simple (and realistic) example will help alot
@jaguard How could a PROD artifact be a SNAPSHOT? PROD artifacts are typically **released** artifacts i.e. artifacts with fixed versions (non SNAPSHOT). I don't get your question.
Pascal Thivent
You're right, so I'll rephrase it: From the snapshot I need to generate specific artifacts with encoded env and a fixed version (based on maven.build.timestamp) in this format (ex: 01.01.09.32.Tue-1730-dev.zip using this time format: yy.ww.EE-HHmm). Since the builds (dev/tests) will be generated almost daily from the snapshot, I'm just looking for a good practice to generating them (profiles, different projects/CI builds) ...etc
+3  A: 

I prefer to package configuration files separately from the application. This allows you to run the EXACT same application and supply the configuration at run time. It also allows you to generate configuration files after the fact for an environment you didn't know you would need at build time. e.g. CERT I use the "assembly" tool to zip up each domain's config files into named files.

Chris Nava
So you suggest to have additional separate projects for every environment ? Can you please come with an example for it ?
Yes. Individual modules are required for each output. Alternatively, you could zip them all together in one package and have the installer extract just the necessary folder.
Chris Nava
I also like this doing it this way, although it is somewhat cumbersome. It is a good idea to have a single binary that can work in any environment and is promoted from one to the next (e.g. DEV->TEST->PROD).
Ken Liu
We also version the configuration files in their own separate projects so they are controlled, but this causes an explosion of maven projects...would be interested if anyone has come up with a better scheme.
Ken Liu
A: 

We use profiles to achieve that, but we only have the default profile - which we call "development" profile, and has configuration files on it, and we have a "release" profile, where we don't include the configuration files (so they can be properly configured when the application is installed).

I would use profiles to do it, and I would append the profile in the artifact name if you need to deploy it. I think it is somewhat similar to what Pascal had suggested, only that you will be using profiles and not versions.

PS: Another reason why we have dev/ release profiles only, is that whenever we send something for UAT or PROD, it has been released, so if there is a bug we can track down what the state of the code was when the application was released - it is easier to tag it in SVN than trying to find its state from the commit history.

Ravi Wallau
We have almost daily based builds generated for DEV and TEST, since for PROD will count just the full releases ...so will get a lot of "snapshot" builds ... Any good practice how to achieve this ?
A: 

I had this exact scenario last summer.

I ended up using profiles for each higher environment with classifiers. Default profile was "do no harm" development build. I had a DEV, INT, UAT, QA, and PROD profile.

I ended up defining multiple jobs within Hudson to generate the region specific artifacts.

The one thing I would have done differently was to architect the projects a bit differently so that the region specific build was outside of the modularized main project. That was it would simply pull in the lastest artifacts for each specific build rather than rebuild the entire project for each region.

In fact, when I setup the jobs, the QA and PROD jobs were always setup to build off of a tag. Clearly this is something that you would tailor to your specific workplace rules on deployment.

Mike Cornell