views:

174

answers:

3

I want a tool or a technique to be able to answer the question "What version of file X was used to build Assembly abc.dll?" I recently moved to a .NET development group, and it seems like this question comes up all the time, in one form or another, and we don't quite have a handle on it. Someone will say something like "Hey, is your latest code on the test server?" and the answer is inevitably something like "I don't know".

Back in the old days of Unix development (I'm dating myself here), the SCCS source control system had special keywords such as %I% (version) and %M% (module name) that you could place in your file, that would be replaced with the appropriate SCCS version information whenever the file was checked out. So a neat trick you could do was assign a constant string to "%I% %M%" in your source file, compile, and then run the Unix "strings" command on your resulting library to determine what versions of what files were used to build that file.

I did a quick test to roll-my-own in a C# class file, like this:

public const String VERSION_STRING = "*VERSION* = MyClass 1.0";

Then ran this command line on my DLL directory:

>for %f in (*.dll) do find "VERSION" %f

But the results were:

---------- MYASSEMBLY.DLL
VERSION_STRING

Which is not quite what I was after (it gave me the name of the constant, but none of the version info I had tried to manually embed in the class).

For what it's worth, we're currently using Clearcase for our version control (currently the company standard). Clearcase has some tools that may be able to help us here (such as clearaudit), but that would require some effort towards refinement and retooling of our build process. I should also mention we're considering piloting a switch to subversion. So I guess solutions that work with .NET in any of various version control systems or build environments (MSBuild, NAnt, CruiseControl) are fair game.

Are there any other, particularly .NET-centric, solutions out there, for tracking what version of what file went into what assembly?

A: 

For my "community" work, I use a simple scheme; I use the SVN revision number as the build version in the [AssemblyVersion] / [AssemblyFileVersion] attributes against the assembly. It is pretty easy to query these both at runtime and via explorer, and the script to update them is pretty easy too - the first few tasks in here.

Marc Gravell
+1  A: 

I have positive experience with SubVersion and CC.NET continuous integration server.

You'd set up a NAnt target that grabs latest (it could lock repository here), then builds. After build is done, it makes a version tag in SVN.

Version of a file can be easily deduced from version of a tag while building.

GregC
So does Subversion offer a way to consolidate the versions that all the source files are tagged with (a.cs, b.cs, c.cs), and somehow attach all that info to the resulting DLL file? Clearcase offers that ability (though we are not taking advantage of it yet on this project), so before we pilot or make a switch to a different version control system, I want to see what we gain or lose.
Ogre Psalm33
Repository is tagged with a revision number as a whole. File revision number is assigned on every check-in. These numbers come from the same pool. So if file versions are 1,2,5,8,9 and the build tag version is 7, then file from rev 5 was used.
GregC
Right, I did a little more reading on Subversion and other VCS. It seems like that feature of Subversion makes it convenient for determining what when into a build (and resulting assembly).
Ogre Psalm33
We used MKS, like, 10 years ago. And no, I'm not that old. I've seen the tags and hated them.
GregC
+1  A: 

We quickly abandoned the idea of using special keywords, since integrated meta-data (like version number) into data (the files stored in the VCS) is generally not a very good idea (see the debate in this SO question: "Embedded Version Numbers - Good or Evil?" )

Our approach is to build a "release note" with that kind of information. This simple text file is then stored alongside the build dll.

VonC
Yep, I realize that with Clearcase, embedding version info is not a great option. It's too bad it doesn't work more like SCCS or RCS, where the version info can be substituted on demand, but is not stored in the file. Though, after reading that link, I can see where that approach can have a few issues as well. I guess this is where the Clearcase approach of building a separate "config record" for derived objects becomes very helpful. (You could even build the release note from the config record, if you were so inclined).
Ogre Psalm33
@Ogre: Indeed, but in practice, we never actually used DO. a more general list of versions, written after the build, was enough for us.
VonC
Of the solutions and answers presented so far, I like this one the best. Whether you are using nant or msbuild, it shouldn't be too hard to automate this type of solution.
Ogre Psalm33