views:

1498

answers:

5

I've got the following scenario: An application is built via the IDE and via a build script. The build script is used for the initial setup (fetching dependencies, setting up environment), to generate the binaries and for the continuous integration process. I want the binaries to have as an AssemblyFileVersion the month and day on build, and svn revision on the revision. This causes the AssemblyInfo.cs to change on every revision, which creates a lot of noise in the source control log. I can ignore the files, but then as part of the setup I'd need to regenerate those.

I'd like to know if anyone has any other ideas, or what do you do in this case.

+4  A: 

I think a common practice for AssemblyInfo.cs is to just generate it dynamically as part of the build process, rather than keeping a static file around.

By generating, you can use any arbitrary/configurable settings you want.

I believe NAnt has an <asminfo> task for this purpose. I'm guessing there's something similar for MSBuild as well. Or you could just write a custom file generation script and use it to shove a custom AssemblyInfo.cs into your build.

Andy White
The thing I don't like about dynamic generation is there is always the risk that the process which is generating the file changes over time, so it may be fine for mainline development, but what happens 2 years from now when you want to checkout an old branch or tag...can you totally rely on this?
Si
@Si: it would not be a problem if the process itself is under version control, no?
Bruno Lopes
True, if you version the process and tooling then that should be reliable. I don't have a problem with dynamic generation of AssemblyInfo on trunk, but then svn would need to ignore it (avoid noise), so you'd have to muck around removing svn:ignore and adding AssemblyInfo on your release branch.
Si
A: 

If you don't check the changed AssemblyInfo.cs back into source control, then why is there noise?

I'd recommend using a single value of AssemblyFileVersion for the entire build, and that you either check in a single file containing that version, and/or label the build with the version number. That way, you won't feel the need to check in multiple modified AssemblyInfo.cs files.

John Saunders
If the file remains changed on the local working copy, then there is noise when I want to commit changes, and I'll need to remind myself not to commit those files. I've run into those scenarios in the past and it created a bit of a frail environment.
Bruno Lopes
Oh. I'm not an SVN user - wouldn't have thought it would commit files not checked out.
John Saunders
@John, I may have read wrong your answer. If the file doesn't exist on the repo, it must be ignored not to appear on the change list. Svn wouldn't try and commit it in that case
Bruno Lopes
+1  A: 

We only update AssemblyInfo on trunk after an RTM/RTW/GA/(Whatever:) release build.

Our Nightly/Beta/RC/QA/(Whatever:) builds just take a copy of the updated AssemblyInfo.cs (from a working copy on CI server) into their appropriate branch or tag. We use Subversion, and you can branch/tag on a working copy with uncommitted changes.

This allows us to keep both the correct version of AssemblyInfo for the Nightly/Beta build in the branch or tag, and only touch AssemblyInfo in trunk after a final release has taken place. The build server has a switch to tell it to commit this to trunk on this type of build.

FWIW, we drive it all from MSBuild scripts, using different values for properties set for each project type, passed through from our build server (CruiseControl.NET).

[EDIT] Also note that the developer's version of AssemblyInfo isn't updated (unless they manually change it), so they don't get the noise of modified AssemblyInfo on each build. We let developers control Major.Minor, the build server controls Build, and we leave Revision for QA to link to their own system (because it's ignored by WiX/MSI anyway).

Si
This seems like a good way to manage it for a medium/large project. I'm just a bit antsy about having the CI server commiting to the repo. Feels a bit odd.
Bruno Lopes
Fair enough, but our build server creates the branch/tag automatically based on it's own build, it also create the CI project against this branch. I much prefer having a single server (or image of server) with a known setup controlling releases rather than leaving it up to developer systems :)
Si
+5  A: 

Right now I'm settled on a solution inspired by Andy White's answer:

  • AssemblyInfo.cs is generated by the AssemblyInfo task from http://msbuildtasks.tigris.org/ and is kept outside the source control tree.
  • The version is [major].[minor].[month][day].[svn revision]. Major and Minor are set manually, the others are managed by the build script. The Community Tasks pack includes both tasks needed to get the working copy svn revision and date.

The downside:

  • When someone checks out a fresh copy the setup target of the build script must be run, otherwise Visual Studio will complain about missing files. This is a problem I'd like to remove in the future.
Bruno Lopes
A: 

We also use a generation step to create the AssemblyInfo.[cs|vb] files, though we simply use a template copy of the file as the source, and then a small Perl script to parse that template, replace the version string, and generate the final output.

The problem with this system is that VB projects seem to constantly load the AssemblyInfo file, which means that the project will have an error when it first loads, even before the PreBuild step can run to create the AssemblyInfo.vb file. We haven't found a solution to that problem yet - if anyone has insight, I'd love to hear it...