MSBuild : Incremental build issue - msbuild

I have question related to partial build. Scenario is as follows.
I have solution which contains Windows form application project and its supporting class library projects. I am building solution using MSBuild. Before building I change assemblyfile version for each project using msbuild custom task. This causes AssemblyInfo files getting modified. Since assemblyinfo files are modified, msbuild builds every single project even though there are no REAL code changes except change in assemblyInfo file. So everytime I build solution it builds ALL projects where as in ideal case it should have built only those projects where real code changes has happened. Because of this solution build time remains same even if there were changes in single project.
There is another side effect of this. I am publishing this application using clickonce. So every time solution gets build it builds every single project in solution. This cause new hash signature generated for every assembly/exe in manifest file every time I do new build. Due to this when updates to application are published clickonce forces user to download every single dll/exe in application. Whereas ideally only updated (one or two may be) files should have been downloaded on user's system.
Essentially what I want is.
1. Build only those projects which has been modified.
2. Update assemblyfile version for ONLY modified projects.
This way I will be able to reduce build time and solve clickonce issue as well.
Any solution/workaround for this?

Related

TeamCity can't find the <something>.fakes.dll

I'm setting up a CI with TeamCity 8 (v8.1.4).
I finally managed to setup TFS integration - ie checkout from TFS.
I used the super easy Auto Detect Build Steps [thank you JetBrains for that] to determine the Build Steps necessary.
I used the Get missing NuGet packages step, which works as expected.
Then I have a Visual Studio Solution build step, that seems to build great, just until the point where it wants to build the Unit Test and Integration Test projects, which both use Microsoft Fakes.
Here I can see that TeamCity tries to search everywhere for the [AssemblyNameUnderTest].Fakes.dll - where [AssemblyNameUnderTest] is whatever dll that is tested.
I haven't included that dll to my project nor in TFS, since I thought that it would be regenerated each and every time I change something to the original AssemblyNameUnderTest (ClassLibrary) Project.
Should I include the [AssemblyNameUnderTest].Fakes.dlls to the project and TFS or am I right that they are regenerated ?
And if I'm right with the regeneration, then why TeamCity can't find it ?
Thanks in advance,
Michael
Ah, so I found the answer to one of my questions: http://hamidshahid.blogspot.be/2012/11/microsoft-fakes-framework.html
The files in the "Fakes" folder are only generated at the time of
adding the fakes assembly. They are added to the solution and should
be checked into source control.
The "FakesAssemblies" folder and all the files in it are generated
whenever the project is compiled. This is important because if you are
adding fakes for assembly for a changing component, the generation of
FakesAssemblies will ensure that all changes are reflected in the
generated assembly.
So I did that - ie it is the default behaviour.
Above that my .fakes files have the "Fakes" build action, but it still isn't working for TeamCity.
Also, TeamCity uses the MSBuild.EXE from "C:\Program Files (x86)\MSBuild\12.0\Bin" for the build.
Anyone a bright idea ?
To fix the build, I removed the Fakes stuff and implemented Moq mocks.
Seems to give you more control of what exactly happens.

ClickOnce deployment minumum required version auto-increment with MSBuild

We current do manual builds/publish from Visual Studio 2010 and we require users to always be running the latest version (check before startup and minimum required version set). I am working on scripting our deployment out and have no issues using msbuild to build/publish. However, I have not found a way to auto-increment the minimum required version when msbuild runs. What are my options to automatically bump this when publishing via msbuild?
I did see quite a few articles on this topic here, but they seemed to be specific to VS and not MSBuild.
Updating the MinimumRequiredVersion Automatically
Introduction to Project Editor
In Solution Explorer, right click on your project and select unload project.
Once the project has become unavailable, right click again and select edit <project_name>.<lang> proj.
Introduction to MSBuild
Properties use key/value pairs to extract information
Using the property name as an alias, you can use $(OutputPath) to obtain the value for the element <OutputPath>.\bin</OutputPath>
We’ll use the following properties generated for a ClickOnce deployment
<MinimumRequiredVersion>1.0.0.6</MinimumRequiredVersion>
<ApplicationRevision>7</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
MSBuild Tasks can be specified in the project (*.proj) file and invoked during a build event.
FormatVersion is a built-in task for .NET 4.0 and later that formats the ApplicationVersion and ApplicationRevision into a single version number.
Implementation
Copy and Paste the following code into the opened project file as a child element to the root <Project> element.
<Target Name="AutoSetMinimumRequiredVersion" BeforeTargets="GenerateDeploymentManifest">
<FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
<Output PropertyName="MinimumRequiredVersion" TaskParameter="OutputVersion" />
</FormatVersion>
<FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
<Output PropertyName="_DeploymentBuiltMinimumRequiredVersion" TaskParameter="OutputVersion" />
</FormatVersion>
</Target>
This code will take ApplicationVersion and ApplicationRevision as parameters in the Format Version task and will save the output by overwriting the MinimumRequiredVersion with the full publish version.
Save and reload your project. Every ClickOnce deployment will now automatically update to the most recently published version.
Many thanks to Kev for their answer which I have basically rehashed here with a little bit of added clarification for any beginners. Here's a blog post I made about the issue that expands even more on my answer here.
Right now, I'm leaning towards updating the MinimumRequiredVersion via a custom command-line utility that will simply read in the project file and increment it. It's the only option I've come up with for scripting out my build.
I'm not sure if you're going about this the best possible way.
I would recommend using a continuous integration (CI) server like Team City that is responsible for deployments. If having the latest version of the source code is a requirement for publishing, then that is probably something you should build into a well-tested CI build configuration, and take away from the hands of the potentially forgetful/occasionally error-prone users.
Since you are wanting to publish using MSBuild and not Visual Studio, I assume you are publishing from a build server or using some sort of script. You can use the Set-ProjectFilesClickOnceVersion PowerShell script to both set the ClickOnce Application Version as well as force the Minimum Required Version to be the latest version. You would want to do this before running MSBuild. My blog describes in more detail how to setup your build server to accommodate publishing ClickOnce applications.

How to know before the compilation if a project will be build or not and make a custom task run or not

I'm looking to create a msbuild custom task that will control how the assembly version is generated on a build.
The first problem that I'm facing is that I don't want to change the assembly version if the project has not changed.
Because changing the assembly version will make a change to the project, and because the project will be modified (by me), it will cause the project to be built. The project would not be built if my task did not run.
Is there a way in msbuild to get my task to run before compilation and to know if the project will actually be built or to know that the project has not changed.
Thanks
It depends on how you want to add version, your build system works and so on.
If you have one version for all assemblies in product you can create simple task with
condition whether svn/git/.. revision changed. And then add +1 to all AssemblyInfo.cs files.
The same solution you can apply on per project base.
Real conditions that is used to decide compile or not are too complex.

MSBuild: What is it, and when do I need it?

I seem to have missed Day 1 of MsBuild 101. I find myself asking "What does it do, what does it replace, and when do I need it?" since I can just hit F5 and compile my application.
What is the bigger picture I'm missing?
MSBuild is the build platform that enables all build activity in the Visual Studio world.
A better, more practical example would be to state that
The .csproj files (every C# project) are msbuild files
When you hit F5, you basically (oversimplifying) call msbuild.exe and passing in your .csproj file.
MSBuild empowers all the things that make hitting F5 work. From creating the "debug" or "release" folder, to dropping references into the bin\ directory, to invoking CSC ... and everything in between ... MSBuild "powers" all that.
If all you will ever need from a build is the output that F5 gives you, then you know about all you probably need to know about MSBuild.
In most commercial/practical development scenarios, however, there will come a time where there is a need to customize the build process. The most common approach is automating the build process (using either TeamBuild or some homegrown system). You may also need to
create a "packaged" deployment
link to another library outside of your project that is also actively
being developed
publish your build to an FTP and send an email to a customer notifying
them of its availability.
The use of a unified and extensible build platform (ie MSBuild) is what makes all these these possible, while still being part of the build process ... keeping the "build" part of the development pipeline simple and contained.
It's useful when you want do automated builds, and have to implement a build process
The F5 Key Is Not a Build Process and links therein (e.g this) is a good read in that regard.
Also, your Visual Studio project files are msbuild files. If you want to do more advanced stuff when you build (e.g. run a javascript minifier, have more control over autogenerated version identifiers, post processing of files etc.) , you'll have to dig into msbuild.
msbuild is used when you want to build your project from the command line. Whenever you see a continuous integration product that will automatically build your project, it will call msbuild to perform the actual build step.
I think that build servers should have the option to press F5 key in a simpler way than via windows API.
I know this is pretty stale, but here's my take on MSBuild.
It's a scriptable build tool really similar to ANT. They both use XML for configuration, so you'll be able to figure it out fairly quickly. Both have the concept of "Targets" for instance, lots more similarities in thinking, if you know ANT the switch shouldn't be tough.
MSBuild files generated from Visual Studio is really like the generated ANT scripts you get from Eclipse that build your projects, remember your includes and define your dependencies. You can modify them directly for fun and profit.
I like MSBuild, it fixes some of the stuff I find annoying about ANT.

Why does Tfs2010 build my Wix project before anything else?

A similar question was asked and answered about a year ago, but was either a different issue (everything was in beta) or misdiagnosed. It's located here: MSbuild task fails because "Any CPU" solution is built out of order.
My issue is that I have a wix installer project, and after upgrading to Tfs2010 on monday, the build fails on linking because it can't find the build product of the Wpf application in the project. After some digging, it's because it hasn't been built yet. Building in Vs2010 works as normal. The wix project is set to depend on the Wpf project, and when viewing Project Build Order in the IDE, everything looks as normal.
The problem was originally encountered with only two platform definitions in the solution; x86 and x64. There are also two flavors, Debug and Release, and TFSBuild.proj is set to build all four combinations. There was no occurence of AnyCPU anywhere. Per the referenced question above, I tried changing the Wpf project to use AnyCPU so that it would be built first. At this point, the wix project used the exact configuration and the Wpf project used the flavor with AnyCPU. However, doing so didn't seem to change anything.
I'm using the Tfs2010 RTM, Vs2010 RTM, and the most recent version of Wix, which at the time of this writing is 3.5.1602.0, from 2010-04-02. Anyone else running into this?
2010-04-27: After a fair amount of digging, and reproducing on a cloned VM build machine, I believe I know what's going on and also what's failing, but I don't quite know how to fix it.
The situation is that this bug seems to exhibit symptoms based on pure luck-of-the-draw project ordering in the solution file. It appears as if the solution file will just blindly build the projects in the order they appear, relying on its ability to detect unbuilt references and build them on demand when needed.
In my particular solution file, my Wix project was ordered before my Wpf application project. This resulted in the Wix project being built first, and while the dependency on the Wpf project was detected correctly, the actual MSBuild task was skipped because of the undefined $(BuildProjectReferences) variable I mention a couple of comments down from the main post in this thread. With MSBuild verbosity still on diagnostic, BuildProjectReferences can be seen as undefined building the Wix project, and it can be seen defined as true upon building the Wpf project within the task to build the Wix project. Yet, when tested, it evaluates undefined again, the task is skipped, and the Wix build fails because it can't find the build output of the unbuilt Wpf project.
So bottom line: project dependency is skipped because of bad $(BuildProjectReferences) variable. Interestingly, this variable is present only in the Wix2010.targets file, and not in wix.targets; I guess that's why this is just showing up after I installed Tfs2010 and Vs2010.
The solution: How do I make sure that BuildProjectReferences is passed along correctly to the subsequent MSBuild tasks? Is there something special with variable scoping going on?
2010-09-14: A bug was opened for this issue in the WiX toolset: http://sourceforge.net/tracker/?func=detail&atid=642714&aid=2990231&group_id=105970 and fixed a while ago. Hopefully, this is no longer an issue. If so, please do open a new bug.
To address your comment directly, nothing in my solution has an AnyCPU configuration in their build files. I created the AnyCPU configurations only to test the solution suggested by the thread I linked to in my original post. After it didn't work, I removed the AnyCPU configurations again.
Furthermore, the projects are in the same solution file, however in separate solution folders (interface folder, installer folder) if that matters.
Interestingly enough, I was going to make a small sandbox example so that I could illustrate the problem I was having, however after creating my tiny sample solution, I couldn't get the error to reproduce. This makes me think that perhaps this is a result of using a team project that was upgraded from a Tfs2008 team project rather than one that was created fresh in Tfs2010. I may try branching my project into a new one to test this theory if I can't figure out why the test solution works.
p.s. also, I'm new to stackoverflow--why on earth are comments limited in length if the "answer your own question" workflow is intended only to provide concrete answers?
So I threw the build verbosity up to diagnostic and read through it today, and one line in particular stood out to me:
Task "MSBuild" skipped, due to false condition; ('#(_ProjectReferenceWithConfiguration)'!='' and '$(BuildingInsideVisualStudio)' != 'true' and '$(BuildProjectReferences)' == 'true' and '#(_MSBuildProjectReferenceExistent)' != '') was evaluated as ('..\WpfApp\WpfApp.csproj'!='' and '' != 'true' and '' == 'true' and '..\WpfApp\WpfApp.csproj' != '').
This was seen as my installer project was attempting to build my wpf project since the wpf project is referenced. In particular, for some reason $(BuildProjectReferences) is evaluating to '' when I'm fairly sure it should be 'true'.
However earlier in the log, at the beginning of the MSBuild task for the WpfApp project, I saw this:
Task "MSBuild" (TaskId:15)
...
Initial Properties:
...
BuildProjectReferences = true
So the property was indeed correct up until the beginning of the task, but then was apparently overwritten? I'm sort of unclear as to how these properties get set.
Its a bug, a bug, a bug. I don't know, who is responsible, but here's a working dirty filthy hack:
Open your .sln file in notepad.
Find your wix projects in the list of projects.
Cut them out, and paste them back after all other projects are listed.
Cry in the shower as you try to scrub the dirty off, only to emerge hours later, rubbed raw and still with the stench of filth clinging to you like corpse's skin.
Following Rob Mensching's edit of my original post, it seems that this has indeed been fixed in WiX 3.6.0917.0 at the latest.
I was seeing this problem (wix 3.7 not finding the dependent project output) in my local and TFS builds (for both VS2010 and VS2012).
I finally got around it by setting the msbuild property /m:1 to only use a single build process. I set /m to allow msbuild to figure out how many processes it could use to simultaneously build with.
I faced with a same problem today and find a solution like this:
Open your solution file on notepad the find your setup project and change postProject setting. This will tell msbuild this project should wait another project to build. I don't know why but it is not added by default.
Project("{GUID}") = "MyInstaller", "MyInstallerPath", "{Installer Project GUID}"
ProjectSection(ProjectDependencies) = postProject
{Prebuild Project GUID} = {Prebuild Project GUID}
EndProjectSection
EndProject
'Prebuild Project GUID' is the number on the right of the project that you want to install.
TFS uses a set of properties to control the names of the solutions and configurations to build ( iterate through ). For each combination of solution and configuration it then uses the project dependencies / build order to control the order of the projects getting built. It's possible that your EXE/DLL's are AnyCPU and that your WiX is x86 and that although the WiX has a dependency on the EXE/DLL the x86 is built before your AnyCPU. Or maybe they are even in different solutions so it's kind of hard to tell without looking at your source but that's basically how it works.
What we did is to first report the bug to wix and then we found your question.
We solved the problem on our side by saying that, by default, the wix project will build the references. We updated the file C:\Program Files\MSBuild\Microsoft\WiX\v3.5\wix2010.targets by setting <BuildProjectReferences>True</BuildProjectReferences> in the project which set the path. So, yes, we have done this manually ; we have reported the bug as well as our fix.