Getting MsBuild buildin parameter in custom build task - msbuild

I have created a custom build template (for TFS 2013) and jacked in the task after the build and now want to make some actions needed.
On parameter that I need to get hold of in the task i the binaryfolder which I feel that MsBuild aldready know but how can I pass this into the task?

Are some more searching the net I found that the enum WellKnownEnvironmentVariables points to the variables that I needed just had to create a custom task in the build template of type GetEnvironmentVariable assinging the result to a variable and then passing this variable to a second task that needed the path.

Related

How to pass data from MSBuild to XAML build workflow

I have a MSBuild script that has data I need to use in my TFS 2013 XAML build definition. Is there a way to transfer data from MSBuild into the XAML build workflow?
I originally was thinking I could get access to the MSBuild properties in my XAML, but this appears to be a one-way path i.e. XAML -> MSBuild via the parameters to the RunMSBuild activity but not the other way around.
An easy way to achieve this is write the version number into a file via WriteLinesToFile Task and then add a custom activity in XAML workflow to read this number.

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

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.

Build process xaml file cannot find Workspace

I am attempting to follow the tutorial for CI with Azure and a Team Foundation Build Server located here, but am running into an issue with the configuration of the build configuration template XAML file, in Step 5. In trying to configure a new ConvertWorkSpaceItem, and add it to the modified build template TFS provides (TfvsTemplate.12.xaml) so that a custom script can be run on a TFS build agent, I attempt to set the property Workspace = "Workspace", but am given a compiler error: 'Workspace' is a type and cannot be used as an expression.
I've done some troubleshooting already, and the errors that have happened to others -- not scoping the CreateWorkSpaceItem, or using the wrong version of TFS or Visual Studio -- do not seem to be issues. I placed the logic correctly inside the "Run on Agent" block, so the scope should be right, and Visual Studio and my TFS Server are both running 2013. My only thought is that the instructions are out of date, and there is some other step that needs to be taken that I am missing. Any ideas?
EDIT:
Here are the parameters for the first failed convert item. The second failed Convert item is similar. The Input and Result variables are parameters defined by me for the workflow as part of the instructions for the tutorial. The error displayed is: "Compiler error(s) encountered processing expression "Workspace". 'Workspace' is a type and cannot be used as an expression."
ok this has come up a couple of times now, for TFS 2013.
Built in variables used to be available for
SourcesDirectory, Binaries Directory and Workspace
these are no longer available in TFS 2013 you now have to use
Microsoft.TeamFoundation.Build.Activities.Extensions.WellKnownEnvironmentVariables
to access these.
Getting the workspace is a little more complicated but if you assign some local variables you should be able to get the workspace object.
Declare local variables for sourcesDirectory (string) and buildDetail (IBuildDetail) and workSpace(Workspace) set their scope to the whole workflow
Create an GetEnvironmentVariable Activity and set its Result value to be sourcesDirectory and use Microsoft.TeamFoundation.Build.Activities.Extensions.WellKnownEnvironmentVariables.SourcesDirectory.
Repeat the same for buildDetail = WellKnownEnvironmentVariables.BuildDetail
Create an assign task for the workSpace object, set this one as
workSpace =
"[buildDetail.BuildServer.TeamProjectCollection.GetService().GetWorkspace(sourcesDirectory)]"
This should then give you a Workspace object to use.
note: syntax might be slightly out.
To compliment the removal of these variables MS have added a new Activity
GetLocalPath
which may be of use to you instead

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

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.