Incrementing build numbers

51 views
Skip to first unread message

rra866

unread,
Jul 30, 2007, 9:29:53 AM7/30/07
to ccnet-user
I am a little new to this, but we have CC.net setup in conjunction
with msbuild and the builds we do work fine pulling from source safe.
What I need to do during the build process is change the build number
on assemblies. I do not want to do this on the developers local
machines as I only want released code from the server build process.
How do I go about this?

Thanks!!

Andrew Badera

unread,
Jul 30, 2007, 9:34:27 AM7/30/07
to ccnet...@googlegroups.com
Use NAnt to write C# to interact with AssemblyInfo.

Phil Sayers

unread,
Jul 30, 2007, 9:40:49 AM7/30/07
to ccnet...@googlegroups.com
nant has the asminfo task you can use to write the assemblyinfo file for you as part of the build process, and write in the version # based on a pattern of your choosing.
 
here is a copy of how we do it.  i have a loop elsewhere that calls this many times, we have a whole bunch of assemblyinfo files to "touch" as part of the build.
 
 
<target name="versionIterator" description="Touches a specific assemblyinfo.vb" >
  <asminfo output="${AssemblyInfoVersionFileToTouch}" language="VB">
   <imports>
    <import namespace="System" />
    <import namespace="System.Reflection"/>
    <import namespace="System.Runtime.InteropServices" />
    <import namespace="System.Security" />
    <import namespace="System.Resources" />
    <import namespace="System.Security.Permissions" />
   </imports>
   <attributes>
    <attribute type="AssemblyCompanyAttribute" value="company name" />
    <attribute type="AssemblyCopyrightAttribute" value="some copywright statement." />
    <attribute type="AssemblyProductAttribute" value="Am.Net" />
    <attribute type="NeutralResourcesLanguageAttribute" value="en-US" />
    <attribute type="AllowPartiallyTrustedCallersAttribute" asis="true"/>
    <attribute type="System.Reflection.AssemblyInformationalVersionAttribute" value="${sys.version}" />
    <attribute type="AssemblyVersionAttribute" value="${sys.version}" />
   </attributes>
  </asminfo>
 
 </target>

Andrew Badera

unread,
Jul 30, 2007, 9:52:36 AM7/30/07
to ccnet...@googlegroups.com
Nice, I was unaware of that task, and it looks like it might solve a problem I was looking to fix with complicated script. Does that have any concurrency issues, if multiple users attempt builds that use the same assemblies/assemblyinfo files? It just updates the existing AssemblyInfo file?

Phil Sayers

unread,
Jul 30, 2007, 9:59:00 AM7/30/07
to ccnet...@googlegroups.com
i have it setup so each "build" gets it own copy of the source code from subversion, so there's never a conflict between builds.
 
Included in that sourcecode are the assemblyinfo files.  the nant task just overwrites them with the asminfo task and does the build.  discarding the changed files at the end.
 
if you have multiple builds trying to use the same files, then i suggest you give each build it's own copy.  it doesn't matter if that per-build copy is actually a single file in your source control system.  I think i have 5 or 6 svn working copies on my build server all from the same code branch in svn.  Sure it makes the disk a little busy, but there is never a file-in-use locking problem.

Andrew Badera

unread,
Jul 30, 2007, 10:01:38 AM7/30/07
to ccnet...@googlegroups.com
Wow, you just made my day, CI-style. I'd been putting off dealing with some of these issues, relying on people to be patient when it came to forcing a build. Thanks!

rra866

unread,
Jul 30, 2007, 11:57:20 AM7/30/07
to ccnet-user
I think this approach will work, thanks all for helping!

R.

Andrew Badera

unread,
Jul 30, 2007, 1:53:02 PM7/30/07
to ccnet...@googlegroups.com
Unfortunately, this does more than just "touch" an AssemblyInfo file -- it looks like it can only create new ... so what happens to AssemblyInfo attributes being set by developers?

http://nant.sourceforge.net/release/0.85-rc1/help/tasks/asminfo.html

Phil Sayers

unread,
Jul 30, 2007, 2:03:05 PM7/30/07
to ccnet...@googlegroups.com
for a given visual studio solution & project...
 
we have a solution level "SolutionInfo.vb" file that is "link-added" to all the projects.
This contains common attributes that are appropriate for all projects....we use
    company name, copywright, version number, trademark...etc
 
in each solution there is an "assemblyinfo.vb" file, where we put assembly specific attributes.
 
we use the nant asminfo task to only touch the common solutioninfo.vb file.  Pretty much to update the year on copywright over time, and different builds have slightly different versioning strategies....one version style for developers, one for QA, and another for our customer builds.

Chris Weiss

unread,
Jul 30, 2007, 2:20:37 PM7/30/07
to ccnet...@googlegroups.com

We use some script to do a search/replace on the version numbers in
the AssemblyFileVersion tag in all AssemblyInfo.cs files in the source
tree. This leaves whatever other metadata is in the AssemblyInfo.cs
files intact:

<foreach item="File" property="filename">
<in>
<items basedir="${CCNetWorkingDirectory}">
<include name="**\AssemblyInfo.cs"></include>
</items>
</in>
<do>
<echo message="Updating ${filename}" />
<script language="C#">
<code><![CDATA[
public static void ScriptMain(Project project)
{
//FileStream file = File.Open(project.Properties["filename"],
FileMode.Open, FileAccess.ReadWrite);
StreamReader reader = new StreamReader(project.Properties["filename"]);
string contents = reader.ReadToEnd();
reader.Close();
string replacement = string.Format(
"AssemblyFileVersion(\"{0}.{1}.{2}.{3}\")]",
project.Properties["build.version.major"],
project.Properties["build.version.minor"],
project.Properties["build.version.revision"],
project.Properties["build.version.build"]
);
string newText = Regex.Replace(contents,
@"AssemblyFileVersion\("".*""\)\]", replacement);
StreamWriter writer = new
StreamWriter(project.Properties["filename"], false);
writer.Write(newText);
writer.Close();
}
]]>
</code>
</script>
</do>
</foreach>

A couple of things to note:
-We only update the AssemblyFileVersion because we strong sign the
assemblies and if we rev the AssemblyVersion each time, it'll break
references every build.
-We manage the version numbers entirely outside of CCNet using a text
file with the build number. The text file is force synced checked out,
number incremented, and not checked back in until after a successful
build is published. This way, we ensure that versions received by Q/A
are always consecutive (which makes defect tracking much easier).
-The AssemblyInfo.cs files are not checked back in and the "stock"
AssemblyFileVersion is 1.0.0.0, so it's easy to tell if someone's
using an "official" file, or something compiled on a developer box.

--
-Chris

Brad Stiles

unread,
Jul 30, 2007, 2:35:03 PM7/30/07
to ccnet...@googlegroups.com
Andrew Badera <andrew...@gmail.com> wrote:

> Unfortunately, this does more than just "touch" an AssemblyInfo file
> -- it looks like it can only create new ... so what happens to
> AssemblyInfo attributes being set by developers?


At the risk of souding like a broken record, I'll plug an Apress book
called "Expert .NET Delivery Using NAnt and CruiseControl.NET". This
exact situation is addressed in there. It uses two separate files. One
file contains the project specific attributes, such as assembly name,
etc. The other contains the stuff that might be changed by the build,
or that the company wants to ensure are in each build, such as the build
number and copyright information.

Brad


Phil Sayers

unread,
Jul 30, 2007, 2:47:00 PM7/30/07
to ccnet...@googlegroups.com
+1


-----Original Message-----
From: ccnet...@googlegroups.com [mailto:ccnet...@googlegroups.com]On
Behalf Of Brad Stiles
Sent: Monday, July 30, 2007 2:35 PM
To: ccnet...@googlegroups.com
Subject: [ccnet-user] Re: Incrementing build numbers

Andrew Badera

unread,
Jul 30, 2007, 3:12:00 PM7/30/07
to ccnet...@googlegroups.com
That book is on my list with Amazon actually, looking forward to reading it when I get through some Martin and Schwaber stuff on Agile and Scrum.

The problem with having a file for those attributes is that they must be universal to all projects that are part of this process, and/or they need to be maintained by the deployment/change management people, rather than developers. This can lead to a problem where, say, a developer sets CLS compliancy or COM visibility to resolve an issue in development, and if/when the issue surfaces down the line in testing, QA, or worse, production, no one knows why without a lot of digging.

I'm actually writing a NAnt task now ... I'll make it available to anyone else who could use it. It will scoop up and retain the existing attributes of the assembly, and only do work on the version.

Andrew Badera

unread,
Jul 30, 2007, 5:56:45 PM7/30/07
to ccnet...@googlegroups.com
I've attached the a ZIP of the source for my NAnt task. I'm only looking to increment the build number, so that's what the task is set up for, but it should also give anyone who wants it a basis for altering their choice of AssemblyVersion values. If you don't get the zip, contact me, we can figure something else out.

<BuildIncrementTask
     AsmName="[AssemblyName]"
     LocalPath="[LocalRoot]"
     BranchOrTrunk="[Any branching etc. folder(s) under the project's main folder]"
     />

BranchOrTrunk is used for branch or trunk folders under your main project folder:
$/Company/Product/Project/Trunk/Properties/AssemblyInfo.cs
$/Company/Product/Project/Branch 06_06_2007/Properties/AssemblyInfo.cs


You can omit the BranchOrTrunk value if instead your path looks like:
$/Company/Product/Project/Properties/AssemblyInfo.cs


Critiques welcome. Questions answered. No, it's not the neatest piece of code either, I'm probably going to do more work on it, and factor out some likely reusable stuff.

--Andrew Badera
andrew...@gmail.com
http://andrew.badera.us/



On 7/30/07, Andrew Badera <and...@badera.us> wrote:
That book is on my list with Amazon actually, looking forward to reading it when I get through some Martin and Schwaber stuff on Agile and Scrum.

The problem with having a file for those attributes is that they must be universal to all projects that are part of this process, and/or they need to be maintained by the deployment/change management people, rather than developers. This can lead to a problem where, say, a developer sets CLS compliancy to true to resolve an issue in development, and if/when the issue surfaces in testing, or worse, production, no one knows why without a lot of digging.

I'm actually writing a NAnt task now ... I'll make it available to anyone else who could use it.
On 7/30/07, Brad Stiles < bradley...@gmail.com> wrote:
AsmVersionTask.Tasks.zip

Andrew Badera

unread,
Jul 30, 2007, 6:00:55 PM7/30/07
to ccnet...@googlegroups.com
Sorry, addendum: to clarify, both local path and the branch/trunk value correspond to path on disk, not in source control.

--ab

On 7/30/07, Andrew Badera <andrew...@gmail.com> wrote:

Andrew Badera

unread,
Jul 30, 2007, 7:44:12 PM7/30/07
to ccnet...@googlegroups.com
http://andrew.badera.us/AsmVersionTask.Task/AsmVersionTask.Tasks.zip


I'm only looking to increment the build number, so that's what the task is set up for, but it should also give anyone who wants it a basis for altering their choice of AssemblyVersion values. If you don't get the zip, contact me, we can figure something else out.

<BuildIncrementTask
     AsmName="[AssemblyName]"
     LocalPath="[LocalRoot]"
     BranchOrTrunk="[Any branching etc. folder(s) under the project's main folder]"
     />

BranchOrTrunk is used for branch or trunk folders under your main project folder:
$/Company/Product/Project
/Trunk/Properties/AssemblyInfo.cs
$/Company/Product/Project/Branch 06_06_2007/Properties/AssemblyInfo.cs


You can omit the BranchOrTrunk value if instead your path looks like:
$/Company/Product/Project/Properties/AssemblyInfo.cs


Critiques welcome. Questions answered. No, it's not the neatest piece of code either, I'm probably going to do more work on it, and factor out some likely reusable stuff.

--Andrew Badera
andrew...@gmail.com
http://andrew.badera.us/



Sean Eby

unread,
Jul 31, 2007, 9:44:12 AM7/31/07
to ccnet-user
I don't know if this is a good method or not, but I do it a bit
differently (All in an MSBuild file).

1) Get the AssemblyInfo from Source Safe
2) Increment the BuildNumber based on the CCNetLabel
3) Check the AssemblyInfo back in to SourceSafe

Here is the Increment target:
<!-- Increment the AssemblyVersion -->
<Target Name="IncrementAssemblyVersion">
<Message Text="===== Starting IncrementAssemblyVersion... =====" />

<!-- Modify AssemblyInfo.vb $(CCNetLabel) is sent from CCNet -->
<FileUpdate Files="$(BuildPath)\AssemblyInfo.vb"
Regex="AssemblyVersion\d*.*"
ReplacementText="AssemblyVersion(&quot;$(CCNetLabel)&quot;)>" />

<Message Text="===== ... IncrementAssemblyVersion finished. =====" /
>
</Target>


On Jul 30, 4:44 pm, "Andrew Badera" <andrew.bad...@gmail.com> wrote:
> http://andrew.badera.us/AsmVersionTask.Task/AsmVersionTask.Tasks.zip
>
> I'm only looking to increment the build number, so that's what the task is
> set up for, but it should also give anyone who wants it a basis for altering
> their choice of AssemblyVersion values. If you don't get the zip, contact
> me, we can figure something else out.
>
> <BuildIncrementTask
> AsmName="[AssemblyName]"
> LocalPath="[LocalRoot]"
> BranchOrTrunk="[Any branching etc. folder(s) under the project's main
> folder]"
> />
>
> BranchOrTrunk is used for branch or trunk folders under your main project
> folder:
> $/Company/Product/Project/Trunk/Properties/AssemblyInfo.cs
> $/Company/Product/Project/Branch 06_06_2007/Properties/AssemblyInfo.cs
>
> You can omit the BranchOrTrunk value if instead your path looks like:
> $/Company/Product/Project/Properties/AssemblyInfo.cs
>
> Critiques welcome. Questions answered. No, it's not the neatest piece of
> code either, I'm probably going to do more work on it, and factor out some
> likely reusable stuff.
>
> --Andrew Badera

> andrew.bad...@gmail.comhttp://andrew.badera.us/


>
> On 7/30/07, Andrew Badera <andrew.bad...@gmail.com> wrote:
>
>
>
> > That book is on my list with Amazon actually, looking forward to reading
> > it when I get through some Martin and Schwaber stuff on Agile and Scrum.
>
> > The problem with having a file for those attributes is that they must be
> > universal to all projects that are part of this process, and/or they need to
> > be maintained by the deployment/change management people, rather than
> > developers. This can lead to a problem where, say, a developer sets CLS
> > compliancy or COM visibility to resolve an issue in development, and if/when
> > the issue surfaces down the line in testing, QA, or worse, production, no
> > one knows why without a lot of digging.
>
> > I'm actually writing a NAnt task now ... I'll make it available to anyone
> > else who could use it. It will scoop up and retain the existing attributes
> > of the assembly, and only do work on the version.
>

> > On 7/30/07, Brad Stiles <bradley.sti...@gmail.com> wrote:

Pelton, Brian

unread,
Jul 31, 2007, 12:21:54 PM7/31/07
to ccnet...@googlegroups.com
I have upgraded to CCNet 1.3. My CCTray 1.3 is part of my "Startup"
folder and each time I log on, CCTray is visible.

In the registry, the Visible setting is 0.

Any ideas why this is starting visible?

--Brian

Russ Rand

unread,
Jul 31, 2007, 12:54:25 PM7/31/07
to ccnet...@googlegroups.com
Andrew,

    I cannot seem to get the file, but it shows as being there. Strange. Would you be willing to send directly to both rra...@hotmail.com and rra...@gmail.com? Just in case one of them gets flakey with zip files.
 
Thanks!!

Roland Bär

unread,
Aug 2, 2007, 12:15:08 PM8/2/07
to ccnet...@googlegroups.com
Hi

For our projects we do it with a nant script that is called before the
compiler is called:

cruisecontrol.net configuration:
<nant>
<executable>C:\Program Files\Nant\bin\nant.exe</executable>
<buildFile>C:\Projects\Configuration\SetVersion.build</buildFile>
<buildArgs>-D:VersionFile=AssemblyInfo.cs</buildArgs>
</nant>

nant script:
<?xml version="1.0" ?>
<project name="Set release version number" default="version" basedir=".">
<description>Sets the Version with the CruiseControl.NET Build Number
as the Revision Number.</description>
<target name="version" description="sets the release version number">
<delete file="${CCNetWorkingDirectory}\${VersionFile}.new"
if="${file::exists(CCNetWorkingDirectory + '\' + VersionFile +
'.new')}" />
<loadfile file="${CCNetWorkingDirectory}\${VersionFile}"
property="VersionInfo" />
<regex pattern="^(?'begin'.*AssemblyVersion\(.\d+\.\d+\.\d+\.)\d+(?'end'.*)$"
input="${VersionInfo}" options="Singleline"/>
<echo file="${CCNetWorkingDirectory}\${VersionFile}.new">${begin}${CCNetLabel}${end}</echo>
<copy file="${CCNetWorkingDirectory}\${VersionFile}.new"
tofile="${CCNetWorkingDirectory}\${VersionFile}" />
</target>
</project>

You haev to ensure that the version is in the Format "1.0.0.0" (and
not with stars like the default value "1.0.*").

Like this all the additional data in the assemlyInfo.cs file stays and
just the last number is set to the build number.

Greetings
Roland

On 7/30/07, rra866 <rra...@gmail.com> wrote:
>

Reply all
Reply to author
Forward
0 new messages