1

I want to set up a parameterized build in Hudson that only takes one parameter -- the type of build to create (QA, Stage, Production). However, each of those builds requires several different environment variables to be set. Something like (pseudocode):

if ${CONFIG} == "QA" then
    ${SVN_PATH} = "branches/dev"
    ${BUILD_CONFIG} = "Debug"
    # more environment variables...
else if ${CONFIG} == "Production" then
    ${SVN_PATH} = "trunk"
    ${BUILD_CONFIG} = "Release"
    # more environment variables...
else # more build configurations...
end if

There are myriad steps in our build -- pull from subversion, then run a combination of MSBuild commands, DOS Batch files, and Powershell scripts.

We typically schedule our builds from the Hudson interface, and I want the parameter entry to be as idiot-proof as possible.

Is there a way to do this?

roufamatic
  • 18,187
  • 7
  • 57
  • 86

2 Answers2

6

Since you do so many things for a release, how about scripting all the steps outside of Hudson. you can use ant, batch files, or whatever scripting language you prefer. Put that script in your scm to get the revision control.

pro's:

  • you get the logic out of Hudson, since Hudson only calls the script.
  • You don't need to create environment variables that need to get persisted between shells (global variables).
  • you can use config/properties files for every environment, which you should also put into version control
  • you can run these scripts outside of Hudson, if you need to
  • Hudson job config get's way easier
  • you don't have the side effects of changing the global environment variables. You should always try to create jobs that don't change any global settings, because that always calls for trouble.
Peter Schuetze
  • 16,185
  • 4
  • 44
  • 58
  • I agree with this approach. It's a shame though -- one of my favorite things about Hudson is the ability to choose the best tool for the job and use it. Still, the more I use it, the more I think that ignoring all options but "run shell script" is the only truly maintainable solution. – roufamatic Dec 03 '10 at 17:23
  • Agreed, this is what I was getting at in paragraph two of my answer. +1 for the list of pros. – Dave Bacher Dec 03 '10 at 17:52
2

Hudson supports build parameters, which are build-time variables that Hudson makes available as environment variables to your build steps (see the Hudson Parameterized Build wiki page). In your job, you can have one choice parameter CONFIG that the user enters. (To set up the parameter, under your job's configuration, select This build is parameterized.)

Then, you can basically write what you've coded in pseudocode at the start of your build step. Or since you have multiple steps, put the environment setup in a file that's referenced from your existing build scripts. (Depending on your shell, there are various tricks for exporting variables set in a script to the parent environment.) Putting the setup in a file that's integrated with your existing build scripts will make it much easier to manage and test (i.e. it's testable outside of Hudson) as well as give you an easy way to invoke your scripts locally.

You might also consider separating your unified build into separate jobs that perform each of the configurations that you've described. Even though they may reference a central build script, the CONFIG types that you've defined seem like they should be distinct actions and deserve separate jobs.

Dave Bacher
  • 15,652
  • 3
  • 63
  • 86
  • I'll give you a point but this doesn't really help. What tricks are you aware of that allows me to change the environment of the calling process (java, running Hudson)? I've tried using SETX as well as calling into .NET's SetEnvironmentVariable method. Both seem to work, but neither can affect the calling process's environment variable set. So subsequent calls by my disparate build steps don't see the changes. What I'm really looking for is something like the SetEnv plugin except it must allow a bit of structured programming around it. – roufamatic Dec 03 '10 at 08:42
  • So you say, it doesn't work using the `setx` in the first build step and get the variables in the second build step? – Peter Schuetze Dec 03 '10 at 12:25
  • The only thing that works is using powershell to call into SetEnvironmentVariable / GetEnvironmentVariable. But that's not convenient and won't work with the other build steps (e.g. pull from subversion, build MSBuild projects) (unless I follow the approach in your answer, of course... in which case the whole problem changes :-) – roufamatic Dec 03 '10 at 17:25
  • @roufamatic, meh, there's no need to vote for my answer if it's not helpful. I'm not familiar enough with batch and powershell to give useful advice there. On Linux/posix, you'd need to source the setup script at the start of each build step, which is one of many reasons why I (and @Peter) suggest putting the setup in a separate file to avoid duplication. – Dave Bacher Dec 03 '10 at 19:06
  • I give points to people who write clear answers, even if it's not exactly what I want. And now that the immediate stress of my day has gone, it'd be inaccurate to say it didn't help at all. :-) – roufamatic Dec 03 '10 at 22:59