TFS 2010: Perform different builds and command line task in sequence? - msbuild

my build process with TFS 2010 should perform different task one after the other like:
Build 1st project in solution
Execute MSBuild via command line (to publish the project)
Execute a 3rd party tool via command line (to obfuscate the binaries)
Build a 2nd project in the solution (an InstallShield project)
How can I achieve this? I can define several project in the Build Definition but how can I invoke several command line task between these build steps? And the MSBuildArguments in the Build Definition: Are these arguments for every msbuild call for each project/solution?
Thanks
Konrad

At first, you need to add in your build definition the distinct *.*proj instead of one big *.sln - or (even better) construct more than one *.sln & order them to get build in the build definition. So you could organize a Project1.sln, Project2.sln etc that are only used from the Build.
In addition to that, you would have to make changes in the build process template to get this.By default you get something like that, that executes each set project/solution within a bigger foreach:
A good way would be to enhance this as a sequence, where all your custom action are set as InvokeProcess activities:
Obviously, you would have to insert here a flow control, so that Publish & Dotfuscator execute the first time (where Project1.sln gets build), while ISDEV executes the second time (where Project2.sln gets build). In the sample below I used a switch & packed Publish & Dotfuscator in a new Sequence.
Finally, you would have to have a counter of some sort. The most immediate option is to set a new Int32 Variable with default == 1 and increase it by hand during execution. In the sample below this is done in the lower Assign:
This final override of Complie the Project, along with a changed Build Definition should get what you 're after.

The team build definition takes a list of sln's and msbuild project files. You can put simply split your InstallShield project out into it's own solution ( most developers won't have a copy of InstallShield anyways likely ) and write an msbuild targets file for steps 2 and 3. Then just tell your build definition to build solution 1, the targets file and solution 2.
You could also choose to put the stuff in the targets file in a postbuild event for one of the projects in solution 1.
I wouldn't do this in workflow.

Related

TF Build 2013 building specific version using changeset, label, buildNumber or buildId

I have two team builds created in VS 2013 - Dev and Test - using the TfvcTemplate.12.xaml build process template. Both builds also use a custom .proj file defined in the process tab "Build/Projects" parameter.
Dev is set to Continuous Integration to build on each check-in. For the Test build, I'd like to update to a particular version.
When firing the build manually, in the parameters tab, I have successfully been able to specify a Changeset in the "Get Version" option. (C9999)
1) I'd like to eventually fire this build from command line, so is it possible to pass this in as a /msBuildArgument instead? e.g. /p:GetVersion=C9999
(I've tried this, and it successfully passes GetVersion to my .proj files, but it does not override the iBuildDetail.SourceGetVersion, which I think is what needs to happen to tell MSBuild what version to get from source control.)
2) Would using the "Label", "BuildId" or "BuildNumber" be better options, and if so, can I specifiy them as /msBuildArguments?
I have found a few related posts, but these offer suggestions that don't seem directed to 2013, but rather 2010 and 2008.
This screenshot shows where I can successfully enter and build a specified changeset and what I'm attempting to pass via arguments.
I found some buried documentation which indicates to prefix the label with an "L". Setting Get Version = "LlabelName" did the trick.
https://msdn.microsoft.com/en-us/library/gg490833.aspx#VersionSpecs
This is helpful, but it seems the labels are tied the to the build's retention policy. For this reason, I'll be using Changesets to specify the version I want to get (build and deploy).
Also, I found a couple parameters to specify Changeset (or labels) to add to the TFSBuild start command I am executing from the command line:
/getOption:Custom /customGetVersion:C9999 (or LlabelName)

How to permanently save a build variable as a build step?

I have the following variables defined:
Now once a build is complete (the last step in the build process), I want to update the VersionRevision variable, basically increment it.
So I'm looking for an API I can call from C# and create a console application or a powershell script to edit the build definition (if I have to do this)?
You can use VSTS Rest API to update the variable value in Build Definition. Both Console Application and Powershell Script is OK for this.
If I understand correctly, you want to get these build variables and them assignment them as your version number.
After the build completes, update and increment the VersionRevision. It's not a good way and seems not available to achieve it.
In TFS build there is a $(Rev:.r) which means
Use $(Rev:.rr) to ensure that every completed build has a unique name.
When a build is completed, if nothing else in the build number has
changed, the Rev integer value is incremented by one.
Source: Specify general build definition settings
To version your assemblies you could just add an powershell script in your build definition, detail ways to achieve please follow this link from MSDN: Version your assemblies
And usually we only define and assignment variables with the Major and Minor version. If you want to change the value of them. You may need manually edit the build definition.
More related link about how to manage version numbers as part of your vNext builds.
vNext Build Awesomeness – Managing Version Numbers
Generate custom build numbers in TFS Build vNext

Build only ChangeSet using MSBuild in Visual Studio Online

I have set up a Build Definition to build a solution on Visual Studio Online (VSO). It's working fine, but it builds all the code every time when I check in the code.
How can I build a particular changeset from the code?
How can I use/pass this number to the "MSBuild Arguments" to use it there for deployment?
You need to turn off the CI build feature(Uncheck "Continuous integration (CI)" option under "Triggers" tab in your build definition) if you don't want it to build all the code every time when you check in.
To build a particular changeset, you can enter the changeset number in "Source Version" textbox when you queue a new build. (In Git, it is "Commit" textbox)
To pass the version number to MSBuild Arguments, you can use the pre-defined variable "$(Build.SourceVersion)", it is filled with the source version number you specified when you queue the build.

How to execute arbitrary line of code in TFS build process?

I am creating a custom process template in our TFS server.
I would like to execute the following line of during the process, to automatically modify the assembly's revision number in AssemblyInfo.cs based on the current MMDD:
File.WriteAllText(file, Regex.Replace(File.ReadAllText(file), "(?<=\[assembly: AssemblyFileVersion\(""[0-9]*.[0-9]*.[0-9]*.)[0-9]*(?=""\)\])", Function(m) DateTime.Now.ToString("MMdd")))
Unfortunately I cannot find out how to execute an arbitrary line of VB.NET code in the build process. There are no code activities called "execute", "run" etc.
I tried to hack it by inserting a lambda function into a WriteBuildMessage() call, but found that lambdas are disallowed:
(EDIT: after other problems with that expression were fixed, it now simply gives the error: "Statement lambdas cannot be converted to expression trees" - ergo I can't do what I'm trying to do here. If "File.WriteAllLines" was string instead of void then I could return it and be laughing.)
Is there a way I can execute an arbitrary line of VB.NET code as part of the build process?
Note: I got around it by adding a node to InvokeMethod directly on System.IO.File.WriteAllText, passing the Regex.Replace call as one of the parameters.
I'll leave the question open in case anyone can provide a direct answer to the original question.
As you mentioned yourself it is possible to use the "InvokeMethod" in order to somewhat execute a line of code.
What I would suggest is to create a custom activity where you can provide it with the parameters, such as the file name and file path.
In order to achieve this two main tasks are needed:
Include a custom build process template
Creating a custom activity
You either do this in your current solution or you create a whole new solution to handle your custom activities and process template.
Include Custom Build Process Template
Whether you choose to work on your current solution or a new one, it is important to have the Process Build Template included in a separate project.
The project needs to be an "Activity Library" which is found under installed (VS 2013):
Right-click solution -> Add.. -> New Project... -> Visual C# -> Workflow
In this project you add your process template that you have been working on, by adding it as an existing item and making it a link. This can be done by pressing the small arrow at the "add" button
When this is included you will need to include several references, which can be found here [1]
Creating Custom Activities
As for the Build Process Template all the custom activities needs a project to be build in. This is to ensure that when they are to be used it is simply referencing the project or including the dll.
This project also needs to be an Activity Library, where this time the activities are to be created.
An activity is a Code Activity and can be created by:
Right-click Project -> Add -> New Item... -> Visual C# Items -> Workflow -> Code Activity
And again this project needs several references in order to build, which can be found here[1]
References:
For more information and ideas take a look at this:
[1]: Ewald Hofman - Customize Team Build
You should not create this yourself. You should use the precreate TfsVersion activity built into the TFS Community Build Tools.
https://tfsbuildextensions.codeplex.com/wikipage?title=How%20to%20integrate%20the%20TfsVersion%20build%20activity&referringTitle=Documentation
This tool will do all of the heavy lifting and is supported by the Visual Studio ALM Ranger and MVP's.

Run msbuild task before ccnet generates the label

The exact sequence of ccnet operations(taken from here):
1) Wait for the triggers to awaken.
2) Ask the source control system for a list of the modifications since the last build.
3) If any modifications were found or if the triggers said "force the build":
3.1) Generate a label for the build.
3.2) Run the prebuild tasks in the order specified, failing the build in case of error.
3.3) Get the source code from the source control system.
3.4) Run the build tasks in the order specified, failing the build in case of error.
3.5) If the repository should be labeled:
3.5.1) Let the source control system apply the label.
3.6) Run the publisher tasks.
4) Go to 1.
Is there a way to run some msbuild task before step 3.1 is executed in ccnet.
Problem Statement:
I am using "fileLabeller" to display the content of a file in ccnet label. If the file exists this works good. But lets say by any chance the file doesn't exist, then i want to call a msbuild task which creates this file and sets up some dummy text.
I called this msbuild task in prebuild event but to my dismay this didn't work out as label generation happens before prebuild.
Is there a way to call this msbuild task before label generation takes place?
Cruisecontrol.net will log all output to a file with a specific label. This means that a label has to be determined before anything else happens.
If you need to run Msbuild to build a label, you might need to write your own labeller.