Local builds and build servers

So this week I added NuGet publishing straight from TeamCity for AutoMapper. Every time I push to master, a new NuGet package is automatically published to the official NuGet repository. In order to do so, I just used the built-in steps in TeamCity to pack and publish the package.

TeamCity makes it very simple to do so, and it’s just a couple of screens to set up. What I’m conflicted on is how much logic should be in the build server configuration versus the build script that lives with the source code.

On one hand, putting this in the source code (the entire build/deploy script) ensures that the logic of how to build and deploy a component is version controlled along with the code itself, so that I can deploy any version at any time. This is what the Continuous Deployment book recommends, to version deployment scripts along with the rest of the code.

The flip side is that deployments in general change at different rates and different reasons than code. In fact, I’ve often seen these be totally orthogonal concerns, and I don’t want to necessarily have to make a commit in source control just to alter my deployment strategy.

Where it hit me in AutoMapper was the server build was failing in how I configured the steps, but I couldn’t drop back to a local build to run individual steps in isolation and debug. Instead, I kept having to run the entire build. With a build whose entire set of build/deployment steps are entirely in a script that is version controlled and runnable locally, I could have incrementally, and in isolation, built out the build/deployment scripts.

I haven’t figured out the best way to go, but with the increasing power of build servers to be the definition of your build in a very easy fashion, it’s going to be tougher to decide.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in ContinuousIntegration. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Can’t you version control your build configuration? We use ccnet and each project has a ccnet.config in it’s project folder that is version controlled and the primary ccnet.config basically sets some global paths and stuff and then includes all the projects ccnet.config files. Oh, and the top level ccnet.config is in svn as well. We even have a build project that looks for change to ccnet.config, gets them and ccnet has a filewatcher that reads new config files whenever it seems them.

    • Anonymous

      Nah, not with TeamCity.

    • Dominik

      IMHO this is hard to achieve this with Teamcity, but someone can put .BuildServerconfigproject-config.xml into source control to get it restored without teamcity backup mechanism.

  • Anonymous

    I have very good experience with having the build/deployment script under version control. It’s easy to debug and you can change the actual steps to deploy without changing the high-level API (rake tasks).

    You might want to have a look at Machine.Specifications and Machine.Fakes, both run on CodeBetter CI and push NuGet packages straight from the release build configs.

  • Anonymous

    Let’s pretend that some day teamcity.codebetter.com will be closed down. And so? What you would to do then?

  • If it’s already setup in your build script, it makes sense to keep it there. If you were doing it manually and wanted to automate it, using the TeamCity build steps makes the most sense – because it’s easy, you just plug some fields and done.

    If TeamCity were to go away after that, you would then take the hit of writing the script to make it happen. With TeamCity, you could also make the build step optional or based on something in the log file (such as a version number, etc.) as to when it is pushed (nm, that’s some icky coupling).

    I realize you’re pushing to NuGet from master every time, but consider having a develop branch where the latest and greatest bits are sourced and pushed as -prerelease. This way, edge users can pull the latest and greatest, while you can spend a little more time testing the master build before pushing it to GA. Just a thought, I realize we discussed this already yesterday. :)

  • StarTrekRedneck

    I like the independence that the script gives you, and I agree deployment seems like a completely orthogonal concern. Have you considered putting the deployment script/application in its own repository? Viewing the script as its own app could give you additional freedoms.