Configurable Builds: One configuration file per environment
One of the most important things when coding build files is to try and make them as configurable as possible.
At the very least on an agile project there will be a need for two different configurations - one for developer machines and one for continuous integration.
On my last two .NET projects we have setup our Nant build to take in a parameter which indicates which build configuration should be used. We then have a configuration file by that name which contains the environment specific data.
The build file would contain the following code before anything else:
<fail unless="${property::exists('environment')}" message="You must provide the environment property to the build script using -D:environment=[dev|ci]" /> <include buildfile="${trunk.dir}\config\${environment}.properties.xml" />
dev.properties.xml would look like this:
<?xml version="1.0" ?> <properties> <property name="property1" value="value1" /> <property name="property2" value="value2" /> </properties>
We would call the build file for the dev environment like so:
nant -buildfile:build-file.build target-name -D:environment=dev
Configuring the build this way assumes that the dev builds all have the same properties. On the projects where I used this approach this was the case.
The disadvantage of it is that you need to remember to pass in the environment variable each time you call the build. This can be countered by wrapping the full nant call in a batch script if it becomes too much of a hassle.
Here's what we do for the Twist builds, given that we build and deploy on various platforms:
build.developer.properties is an override for it all, which is what most developers on 'non-standard configuration use'
We check in the property files for all hosts into svn. So individual machines can always pick them up from the source tree. Dev machines probably don't have this checked in.
build.properties is just the default values for everything else.
Ketan Padegaonkar
2 Sep 08 at 5:45 am
"One of the most important things when coding build files is to try and make them as configurable as possible".
As possible? Or as necessary? I dread wading through heavily configurable build files; jumping around to figure out where properties are defined and set. I'm not saying they shouldn't be flexible, but YAGNI applies to scripts too!
Jim Arnold
2 Sep 08 at 9:26 am
As necessary is probably more accurate you're right.
It's always interesting looking at the trade off you have to take between making something configurable and the levels of indirectness you end up creating as a result.
From what I've seen I think at most you should only have one extra configuration file that you need to look in for properties - when you have the properties scattered all over the place it becomes really painful as you say.
So in this case we would only need to look for properties in dev.properties.xml or qa.properties.xml and that would give us everything we need.
Mark Needham
2 Sep 08 at 9:32 am
We have a similar thing except it gets its filename from the name of the machine you are on when on a dev box…
so for example my machine name might be GNM23454 and there would be a properties file called :
environment.GNM23454.properties
In there is a DB connection and everyone has their own login and oracle DB schema.
We have a couple of helper targets on the build which tell you which DB you are connected to.
Its all running under ANT
Jim Barritt
2 Sep 08 at 1:51 pm
[...] on from my first post about making builds configurable, the second way of doing this that I have seen is to have one [...]
Configurable Builds: One configuration file per user at Mark Needham
2 Sep 08 at 1:59 pm
In general though, I'd see a build per environment as an anti-pattern. Rebuilding between deployments to various testing environments hurts your traceability between those tests and the guarantee that what you deploy in a late testing environment or production was actually tested earlier.
A similar nant deployment script that takes properties per environment and modifies an already built application's configuration files based on those properties seems to be along the same lines, but without the unneeded rebuilding.
At least we hope the rebuilding isn't needed. We don't have configuration being compiled with source code do we?
Eric Minick
2 Sep 08 at 5:55 pm
[...] One configuration file per environment [...]
Configurable Builds: One configuration file per machine at Mark Needham
13 Sep 08 at 3:57 am