How to use Msbuild.Community.Tasks.Version in a csproj file - msbuild-task

I want to use the VersionTask from the MSBuild Community Tasks to set the Revision calculation type. However, I am having difficulty understanding how to actually wire up the task within my csproj file.
The project has an AssemblyInfo.cs which has the following attribute defined:
[assembly: AssemblyVersion("3.2.5.*")]
What I want to do is over-ride the generation of the Revision number handling with my own custom handling.
I have put the customised Version task into the csproj file as follows:
<UsingTask TaskName="MyCo.Build.Tasks.Version" AssemblyFile="$(SolutionDir)\..\Build\.build\MyCo.Build.Tasks.dll" />
The actual task is then called as follows:
<Target Name="BeforeBuild">
<Message Text="Setting Revision Number to $(BuildNumber)" />
<MyCo.Build.Tasks.Version RevisionType="BuildServerNumber" Revision="$(BuildNumber)" /></Target>
I can see the target BeforeBuild being called because of the Message Task but the exe file still has the standard generated numbering as follows: File Version : 3.2.5.27547
I was expecting something like 3.2.5.111 (the build number passed into MSBuild as a parameter).
As the Version task is overriding the default handling of the '*' value for Revision I don't believe it is necessary to actually modify the AssemblyInfo.cs file.
Do I need to pass the output value from the Version task into an MSBuild parameter? Do I actually need to use the AssemblyVersion task to update the values in the file?
Obviously I am trying to avoid having to change the AssemblyInfo.cs, I just want to override the Version number handling.
Can someone advise please?
EDIT: I just found the following example of usage in the chm file from the installer which partly answers my question.
<Version BuildType="Automatic" RevisionType="Automatic" Major="1" Minor="3" >
<Output TaskParameter="Major" PropertyName="Major" />
<Output TaskParameter="Minor" PropertyName="Minor" />
<Output TaskParameter="Build" PropertyName="Build" />
<Output TaskParameter="Revision" PropertyName="Revision" />
</Version>
<Message Text="Version: $(Major).$(Minor).$(Build).$(Revision)"/>
However, when I run the build I can output the generated Assembly Version in a Message task but the exe file still has the default Revision as before

I got a resolution to this here: How to override the revision number
In the end I had to actually update the AssemblyInfo file for each project during the build. So on the build server (TeamCity) I placed the code I needed in the Microsoft.Common.targets file so that it wasn't required in each project ad then passed the release number and TeamCity build number to each build task.

The Revision is the number of days since 1/1/2000 when you set it to Automatic - you can supply your own "StartDate" if you want.

Related

How to retrieve AssemblyVersionAttribute in MSBuild script

When trying to retrieve the [assembly: AssemblyVersion("1.2.3.4")] present in AssemblyInfo.cs file from a custom MSBuild script, I always get $(Version) value 1.0.0.0 instead of the value written in the file.
Can somebody tell me how to fix this issue? Unfortunately, other entries I have found so far, didn't point me to the right direction.
Actually, you just want to get the assembly dll version by MSBuild rather the nuget package version.
$(Version) is the value of the nuget package version after you pack the lib project. See this official document.
If you want to get the internal assembly dll version, it can be a bit complex but it can be done with some MSBuild tasks.
Use this:
<Target Name="RetrieveIdentities" BeforeTargets="Build">
<GetAssemblyIdentity
AssemblyFiles="$(TargetPath)">
<Output
TaskParameter="Assemblies"
ItemName="MyAssemblyIdentities"/>
</GetAssemblyIdentity>
<Message Text="Version: %(MyAssemblyIdentities.Version)"/>
</Target>
And %(MyAssemblyIdentities.Version) is the value of the AssemblyVersion.

Changing default APK output to include version in the name using MSBuild

when building an APK using MSBuild I would like to change the output apk name to include the version number
so
android:versionName="3.1.5"
would end up like:
MyAndroidApp-3.1.5.apk
i tried to do a post-build step where i try to copy the apk to a different name , but there aren't any macros in the post build step that has the version (that i can see)
When calling
MSBuild .\trunk\TaxiTabletUniversal.Droid.MyAndroidProject /t:SignAndroidPackage /p:Configuration=Release
the output apk ends up with the name:
company_name.mypackage_name-Signed.apk
In the Android Package Signing setting i can only specify the keystore and paswords, but no output name.
I would like the output name to pickup the versionName in the
AndroidManifest.xml
file
Changing default APK output to include version in the name using
MSBuild
Sorry but the answer could be negative, as I know MSBuild itself doesn't have the ability to read data like Version-number from AndroidManifest.xml. In other words, it's not supported by msbuild.
MSBuild can access any property defined in project file or imported targets file, but it can't access AndroidManifest.xml file. And there's no official msbuild task can to this for us, so if you do need this behavior, we have to code ourselves to read the version info from that xml file. Topics about this: one, two, three...(Too many topics online talk about this, so I don't talk too much here, if you meet some issue about coding that, let me know:-
))
Here're two possible ways after that coding:
1.Create a .exe file with code to execute the renaming job, and call the .exe in a post-build event
2.Write a custom task named CustomTask, and add this script into the project file to call this task after build or SignAndroidPackage target.
<UsingTask TaskName="CustomTask.CustomTask"
AssemblyFile="path\CustomTask.dll"/>
<!--Maybe it should be AfterTargets="SignAndroidPackage"-->
<Target Name="CustomTarget" AfterTargets="Build">
<CustomTask/>
</Target>
May it makes some help.

Can you include a generated file to a WiX project without adding it as an existing file

We use HEAT to build a file for our web project installer. I want to know if there is a way that I can have the file included in the compilation, but not included in the project.
The reason I need this is I would like to not check the file in on our source control, but have it build when we build the wixproj. Otherwise we have to hijack/checkout the file in order to reliably build the project.
If you are using MSBuild and a .wixproj to build your .MSI then you will need to get the output from HEAT to be listed in a Compile item in the .wixproj. If the file is not included it will not get compiled into the final .MSI.
Fortunately, MSBuild provides quite a few options to dynamically include items. For example, you could have a custom target in your .wixproj that runs HEAT and adds the output
<Target Name='RunHeat'>
<Exec Command='heat.exe param param param -o path\to\output.wxs' />
<ItemGroup>
<Compile Include='path\to\output.wxs' />
</ItemGroup>
</Target>
Now if you get the RunHeat target to run before the Compile target in wix.targets then the Compile item generated in RunHeat will be included in the Compile target. Given the flexibility of MSBuild there are probably a dozen other ways you could accomplish this task.
Hope that helps and good luck!

How to use StyleCop with TeamCity

Has anyone had any success with running StyleCop from TeamCity?
I know StyleCop supports a command line mode, however i am not sure how this will integrate into the report output by TeamCity.
I've checked out this plugin found here: https://bitbucket.org/metaman/teamcitydotnetcontrib/src/753712db5df7/stylecop/
However could not get it running.
I am using TeamCity 6.5.1 (latest).
I don't know how familiar you are with MSBuild, but you should be able to add a new Build Step in TC 6 and above, and set MSBuild as the build runner, and point it to a .proj file which does something similar to the following:
<Target Name="StyleCop">
<!-- Create a collection of files to scan -->
<CreateItem Include="$(SourceFolder)\**\*.cs">
<Output TaskParameter="Include" ItemName="StyleCopFiles" />
</CreateItem>
<StyleCopTask
ProjectFullPath="$(MSBuildProjectFile)"
SourceFiles="#(StyleCopFiles)"
ForceFullAnalysis="true"
TreatErrorsAsWarnings="true"
OutputFile="StyleCopReport.xml"
CacheResults="true" />
<Xslt Inputs="StyleCopReport.xml"
RootTag="StyleCopViolations"
Xsl="tools\StyleCop\StyleCopReport.xsl"
Output="StyleCopReport.html" />
<XmlRead XPath="count(//Violation)" XmlFileName="StyleCopReport.xml">
<Output TaskParameter="Value" PropertyName="StyleCopViolations" />
</XmlRead>
<Error Condition="$(StyleCopViolations) > 0" Text="StyleCop found $(StyleCopViolations) broken rules!" />
</Target>
If you don't want to fail the build on a StyleCop error, then set the Error task to be Warning instead.
You'll also need to add the following to your .proj file:
<UsingTask TaskName="StyleCopTask" AssemblyFile="$(StyleCopTasksPath)\Microsoft.StyleCop.dll" />
Microsoft.StyleCop.dll is included in the StyleCop installation, and you'll need to set your paths appropriately.
To see the outputted StyleCop results in TeamCity, you will need to transform the .xml StyleCop report to HTML using an appropriate .xsl file (called StyleCopReport.xsl in the script above).
To display the HTML file in TeamCity, you'll need to create an artifact from this .html output, and then include that artifact in the build results.
The Continuous Integration in .NET book is a great resource.
Did you know that teamcity provides specific properties just from msbuild?
No need for the service messages, see:
http://confluence.jetbrains.net/display/TCD65/MSBuild+Service+Tasks
So you dont have to add a custom report page.
Use the build stats e.g.
<TeamCitySetStatus Status="$(AllPassed)" Text="Violations: $(StyleCopViolations)" />
you can then log the statistic too:
<TeamCityReportStatsValue Key="StyleCopViolations" Value="$(StyleCopViolations)" />
And then create a custom graph to display, and you already have the violations in your msbuild output.
edit main-config.xml and add:
<graph title="Style Violations" seriesTitle="Warning">
<valueType key="StyleCopViolations" title="Violations" buildTypeId="bt20"/>
</graph>
Where buildTypeId="bt20" bt20 is your style build.
I'm late to the show here but a very easy way to achieve this is to install the StyleCop.MSBuild NuGet package in any project which you want to analyse with StyleCop.
After installing the package, StyleCop analysis will run on every build you do, regardless of where or how it is invoked, e.g VS, command line, msbuild, psake, rake, fake, bake, nant, build server, etc. No special actions are required.
If you want the build to fail when StyleCop rules are broken you just need to add the following element to your project file under each appropriate build configuration, E.g.
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<StyleCopTreatErrorsAsWarnings>false</StyleCopTreatErrorsAsWarnings>
...
Again, this will work on every build, regardless of where and how it is invoked.
There's a (new?) third-party TeamCity plugin for StyleCop here, (though I haven't tried it yet).
UPDATE: as far as I can tell, the latest version only works with TeamCity 7 (or I did something wrong). Also, I have a very slow (virtual) build server, so even after the services were restarted, it took a while for the StyleCop runner to appear in the web interface.
Another stupid thing I did was not read the readme properly: you have to unzip the downloaded zip, and use the zip inside.
I also originally started with just a list of .cs files in the "Include" option (for the build step), but that didn't work; links to sln or csproj files do work though.

Checking a file out (TFS) for a pre-build action

I've added a pre-build action for an ASP.NET web control (server control) project, that runs jsmin.exe on a set of Javascript files. These output files are part of the source control tree and are embedded into the assembly.
The problem is when the pre-build runs, jsmin can't write the file as it's readonly. Is it possible to check the file out before hand? Or am I forced to set the file's attributes in the command line.
Any improved solution to the problem is welcome.
Update
One small issue with Mehmet's answer -you need to prepend the VS directory:
"$(DevEnvDir)tf" checkout /lock:none "$(ProjectDir)myfile"
If you're using Team Foundation Server, you can use team foundation command line utility (tf.exe) to check out the file(s) during pre-build and then check them back in during post-build. If you're using something else for source control, you can check if they have a command line tool like tf.exe.
If you do not want to check the files in as part of the build (which you normally wouldn't for this sort of thing) then I would simply set the attributes of the .js files before running jsmin on them. The easiest way of setting the files read-writeable is to use the the Attrib task provided by the MSBuild community extensions. The same community extensions also provide a JSCompress task for easily calling JSMin from MSBuild.
Therefore you'd have something like the following (not tested):
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
<!-- rest of TFSBuild.proj file -->
<Target Name="AfterGet">
<Message Text="Compressing Javascript files under "$(SolutionRoot)"." />
<CreateItem Include="$(SolutionRoot)\**\*.js">
<Output TaskParameter="Include" ItemName="JsFiles"/>
</CreateItem>
<Attrib Files="#(JsFiles)" ReadOnly="false"/>
<JSCompress Files="#(JsFiles)" />
</Target>
Note that by modifying the files after getting them may well cause issues if you tried to move to an incremental build.

Resources