The initial goal was to release some new software into a test environment, which I'm still working on! First things first though.
What does a release involve?
The manual steps that would be involved in actually performing a release:
- Checkout a clean source tree from trunk/master/branch
- Update the version from a SNAPSHOT to GA release number
- Build and deploy the release into a maven repository
- Commit the changes to a tag in a central repository
This process allows us to keep a permanent (enough) record of the source when the code was released and also access the binaries from maven in a meaningful way.
There might be other steps that you also perform along the way, but they're the main one in my opinion.
Releasing with maven
My build tool of choice is maven, it works for me and I like the fact that it's descriptive and even a little verbose. We've always had our builds using the maven-release-plugin, which despite it's rough edges has always done the job.
I also create release build configurations in TeamCity, which allow us with a single click to produce a versioned software release into dev integration, test, uat or production. It makes life easy.
Part of the release process requires an scm to be provided to maven:
<scm>
<connection>scm:git:https://hostname/path/to/repo.git</connection>
<developerConnection>scm:git:ssh://git@hostname:7999/path/to/repo.git</developerConnection>
<scm>
And here's where it started to get a little tricky.
As you can see, the connection and developerConnection are different. The developerConnection is used during the release process to commit/push changes to a maven pom to a central repository.
I've chosen to use ssh here as we build using a specific build user and I didn't want to provide a username/password in a maven settings file, instead choosing passwordless ssh and registering the key with Stash.
Git, SSH and Windows
And now it started to get really "fun", but I'm going to cut a long story very short.
I tried a myriad of ways to pass an identity key to git during the maven build process, ultimately I was able to discard all of that and simply set an environment variable called HOME and point it to a directory containing a .ssh directory containing my identity file id_rsa.
e.g. HOME=C:\Users\BuildAgent
where C:\Users\BuildAgent contains .ssh\id_rsa.
Simplifying the release build
During my attempts to get git working with ssh and windows I stumbled across a great post by Axel Fontaine, which made me view the process I described in "What does a release involve?" very literally, rather than the more obscure process that the maven-release-plugin takes.
Essentially it involves:
- versions:set versions:commit scm:checkin (but don't push)
- deploy
- scm:tag (do push)
- scm:checkout (the tag that was created above as a verify step)
You could argue that a couple of the steps above are unnecessary but I like checks and balances.
This process allowed me to ditch the maven release plugin (and associated properties) in favour of a simpler maven-scm-plugin and versions-maven-plugin.
The configuration for these plugins sits within a parent pom, in such a way that descendents don't need to apply (or know about) any additional configuration.
As part of the setup for the scm plugin I included the following configuration:
The configuration for these plugins sits within a parent pom, in such a way that descendents don't need to apply (or know about) any additional configuration.
As part of the setup for the scm plugin I included the following configuration:
<configuration>
<tag>${project.version}</tag>
<connectionType>developerConnection</connectionTypegt;
<configuration>
Tying it together with TeamCity templates
Build Configuration Templates have been around for an eternity, but I've never found a reason to use them. Now I have, and they're great.
then following build steps:
and, finally added an environment Build Parameter for HOME.
Which makes it very quick, simple and easy for release builds to be created with a minimal of effort and certainly less fuss.
Worth it?
We now have a build that:
- is twice as quick to perform than maven-release-plugin
- requires no configuration within a projects pom file (aside from referencing a parent)
- Can be created in less than a minute in TeamCity
You decide.