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.
Related
As the title says: How can I pass parameters to the msbuild process(es) initiated by Visual Studio?
I need to modify the MSBUILDDEBUGPATH parameter as our solution has many post-build events making use of xcopy (which I don't like, but thats the way it is).
This results in the creation of many batch files in the folder C:\Users\MyUser\AppData\Local\Temp\tmp[guid].exec.cmd which execution gets prevented by our greate HIPS software resulting in killing all msbuild.exe processes.
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.
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.
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.
I have the following need:
I'll have to create an MSBuild task that will produce an xml file, which I then need to embed as a resource to one of the projects being built. How do I change my MSBuild proj to accomplish that? Is there a built-in task I can use for embedding the file, or do I need to create one? If the latter, any direction on that would be great.
Thanks in advance!
Update: based on the suggestions given, I've ended up adding an empty xml file to the project as a resource, creating a simple MSBuild custom task (http://bartdesmet.net/blogs/bart/archive/2008/02/15/the-custom-msbuild-task-cookbook.aspx) that writes content to that file as I need it, and running that task as a "BeforeBuild" target. Works like a charm. Note that I've had to "exclude the file from source control", so it won't get checked out every time I build the project, and I've also added some code to the task to make sure the file isn't read-only (http://www.del337ed.com/blog/index.php/2007/09/05/clearing-the-read-only-flag-on-a-file-in-c/).
If you don't need to create the whole Xml file from scratch and could add a stubb file to your project you could use the XmlPoke Task to update this file in the BeforeBuild Target (see Sergios answer).
You can use builtin in your .csproj/.vbproj file target BeforeBuild (not forget to uncomment it) and call required MSBuild task in BeforeTarget. In that project add that resource as embedded. That's all.