CruiseControl failing view compilation with Asp.net MVC 2 RTM - msbuild

Tehnologies:
- CruiseControlNet
- Asp.net MVC 2 RTM
- enabled view compilation
The problem is UrlParameter.Optional setting. I can't seem to make it work when I use this setting inside a view.
When I compile inside Visual Studio, everything works fine, but when CCNet uses MSBuild to compile it it fails with following error:
errorCS0103: The name 'UrlParameter' does not exist in the current context
pointing to the line inside my view where this parameter is set on:
Html.RenderAction(...)
that sets certain route parameter(s) to optional.
I tried adding <%# Assembly name="System.Web.Mvc" %> at the top of my view, but it didn't work either. It works of course when I disable view compilation, but that's not really an option. And I also don't want to set my optional parameters to string.Empty.
Anyone has any hint on this?

Check if your web.config has in the <compilation> section the following entry:
<add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />

Solution/Workaround
I checked CCNet configuration of my project and I added the following line in the <msbuild> element:
<buildArgs>/noconsolelogger /p:Configuration=Release</buildArgs>
After that I also changed my csproj file to set these:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
...
<MvcBuildViews>true</MvcBuildViews>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
...
<MvcBuildViews>false</MvcBuildViews>
</PropertyGroup>
This way my views are only being compiled in development, where we compile as Debug, but not by MSBuild on CCnet where it now compiles as Release.

We had the same issue (actually, that is how I came to find your question/workaround). It turns out our build server had an older version of MVC 2. You need the RC.
HTH.

Related

Can't figure out how to include the source code into the nuget package that gets generated

I have several projects in a solution that i want to be packaged to be used as libraries in other solutions. The goal is to make development and debugging seamless, as if it was all in the same solution.
Specifically, I want to be able to ctrl + click on something from the library and be able to view the original source code and not the decompiled code.
I am using PackageReference to include the libraries to the application. What I have noticed is that when I unzip either the nupkg or snupkg, there is no source files anywhere. On that note, I have searched all over the internet and found conflicting things about where the source files go in the nupkg. I have seen mentions of the following folders in the nupkg: lib, src, content, and contentFiles. Which one should actually contain the source code?
When I unzip the nupkg (or snupkg) the only things I have in it are _rels, lib, package, [Content_Types].xml, and PROJECTNAME.nuspec.
I see that the lib folder contains the dll and the pdb file but no source code.
Furthermore, I noticed that the snupkg file is considerably smaller than the nupkg file which I find to be counter intuitive.
I have tried packaging using
msbuild -t:pack
msbuild -t:pack -IncludeSource=true
nuget pack
nuget pack -IncludeSource=true
and also building with visual studio but to no avail.
Here is my vbproj file
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{C64FB67B-64D0-4607-AE35-A21888FE79A2}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>ROOTNAMESPACE_HERE</RootNamespace>
<AssemblyName>PACKAGE_NAME_HERE.ROOTNAMESPACE_HERE</AssemblyName>
<FileAlignment>512</FileAlignment>
<MyType>Windows</MyType>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<Deterministic>true</Deterministic>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
<TargetFrameworkProfile />
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<version>1.0.0</version>
<RepositoryType>git</RepositoryType>
<Authors>COMPANY_HERE</Authors>
<BuildInParallel>false</BuildInParallel>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<IncludeSource>true</IncludeSource>
<PackageId>PACKAGE_NAME_HERE.ROOTNAMESPACE_HERE</PackageId>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
</PropertyGroup>
...
...
...
<ItemGroup>
<PackageReference Include="NuGet.Build.Tasks.Pack" Version="6.4.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
</ItemGroup>
I have also tried using a nuspec file as well but still no success.
I am using .net framework 4.8
I have spent the last 3 days banging my head against the wall over this and haven't been able to figure it out. I have googling non-stop and have even been using ChatGPT to help me try and trouble shoot and no matter what I try I cant get it to work.
Any help would be greatly appreciated!
It sounds like you want to publish nuget packages with SourceLink activated.
SourceLink will add metadata to the packaged assemblies that contains hints about where the original code from which the package was build can be found, e. g. a GIT repository URL and the particular commit SHA. The Visual Studio Debugger during debugging will read the metadata and thus be able to download the source from the repository and show it to you.
This will be the original source like you wanted.
See the docs at https://learn.microsoft.com/en-us/dotnet/standard/library-guidance/sourcelink.
What you have to do is add SourceLink as a package dependency to the project from which the package will be built.
For github and an SDK-style project it looks like this:
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All"/>
<!-- alternatively, using the new GlobalPackageReference element -->
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
Since you seem to be using the old project format, you may need to do it differently. Visual Studio will most likely do the right thing for you when adding the package through the package manager UI.
Note that this is a build-time dependency only and will not add any libraries.
SourceLink by default will only do its job when some MSBuild properties are set. More on that below.
This is a snippet I use (again, SDK-style) to have SourceLink active on every release build:
<PropertyGroup>
<!-- ugly workaround because MSBuild apparently cannot set a bool property from the result of an evaluated expression -->
<TreatAsOfficialBuild>false</TreatAsOfficialBuild>
<!-- Abuse "Release" config as trigger for SourceLink, because I don't want to type -p:ContinuousIntegrationBuild every time
This should work as long as we do not locally debug release builds from commits that have not been pushed to github yet -->
<TreatAsOfficialBuild Condition="'$(Configuration)' == 'Release'">true</TreatAsOfficialBuild>
<PublishRepositoryUrl>$(TreatAsOfficialBuild)</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<ContinuousIntegrationBuild>$(TreatAsOfficialBuild)</ContinuousIntegrationBuild>
<DeterministicSourcePaths>$(TreatAsOfficialBuild)</DeterministicSourcePaths>
</PropertyGroup>
For the debugger to be able to download the source, the package must have been built from a commit that is available on the remote repo.
I trust you already know that you may not be able to debug into that source with breakpoints if the build you are debugging is optimized like in a "Release" build.
If you want to be able to debug through every line of the package's original source, you would have to build that package without optimization (like in a "Debug" build). For SourceLink to be active on debug builds too, you would need to adapt the criteria for the TreatAsOfficialBuild property accordingly.

MsBuild not generating PDB files in Release configuration

<MSBuild Projects="$(ProjectFile)" Targets="_WPPCopyWebApplication;"
Properties="OutDir=..\publish;Configuration=Release;Platform=AnyCPU" />
I am using above script to publish Asp.Net project. In the project settings, I have absolutely made sure debug symbols are generated in release mode. Still MsBuild is not generating the pdb files in the output.
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>Full</DebugType>
<DefineDebug>false</DefineDebug>
<DefineTrace>true</DefineTrace>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DocumentationFile>WebProject.xml</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
After looking at the Microsoft.Web.Publishing.targets source, I have found a variable (ExcludeGeneratedDebugSymbol) being set to True in Release mode. From the comments, it looks like they wanted to exclude symbols from WebSite project, but the condition is not properly set for WebApplication project.
So, I have decided to override my build scrip from the caller arguments and it worked like a charm. I have not yet ascertained any side affects it may cause or using the undocumented property for future stability, but it works for now.
From the Microsoft.Web.Publishing.target file
<!--For website we will always exclude debug symbols from publishing unless it is set explicitly by user in website publish profile-->
<ExcludeGeneratedDebugSymbol Condition="'$(ExcludeGeneratedDebugSymbol)'=='' And '$(_WebProjectType)' == 'WebSite'">True</ExcludeGeneratedDebugSymbol>
<ExcludeGeneratedDebugSymbol Condition="'$(ExcludeGeneratedDebugSymbol)'=='' And '$(Configuration)' == 'Release'">True</ExcludeGeneratedDebugSymbol>
<ExcludeGeneratedDebugSymbol Condition="'$(ExcludeGeneratedDebugSymbol)'==''">False</ExcludeGeneratedDebugSymbol>
I have updated my script as follows.
<MSBuild Projects="$(ProjectFile)" Targets="_WPPCopyWebApplication;"
Properties="OutDir=..\publish;Configuration=Release;Platform=AnyCPU"; ExcludeGeneratedDebugSymbol=false />
You could also updated your publish profile (.pubxml) file to include that property value. I had to do this today with the new build bits in TFS Build 2015 to have the web publishing include the .pdb files. See example contents of file with property added to bottom.
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit http://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<SiteUrlToLaunchAfterPublish />
<publishUrl>C:\Publish</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<ExcludeApp_Data>False</ExcludeApp_Data>
<LaunchSiteAfterPublish>False</LaunchSiteAfterPublish>
<ExcludeGeneratedDebugSymbol>false</ExcludeGeneratedDebugSymbol>
</PropertyGroup>
</Project>
You can put this directly in your *.csproj file, as the last property group section (right before the Import elements):
<PropertyGroup>
<ExcludeGeneratedDebugSymbol Condition="$(DebugSymbols) == true">false</ExcludeGeneratedDebugSymbol>
</PropertyGroup>

FxCop in MSBuild and disabling CA0060 exceptions

I am very new to MSBuild and it is taking me a little while to work out how to do things.
So I am trying to integrate FxCop into my project to be automatically run when I build them on the build server.
At the moment the way to go seems to be to add a custom task to the build that you call when you build. So I have so far created the following:
<Target Name="ExecuteFxCop">
<ItemGroup>
<Files Include="bin\XXXX.dll" />
</ItemGroup>
<!-- Call the task using a collection of files and all default rules -->
<MSBuild.ExtensionPack.CodeQuality.FxCop
TaskAction="Analyse"
Files="#(Files)"
SearchGac="True"
OutputFile="FxCopReport.xml">
</MSBuild.ExtensionPack.CodeQuality.FxCop>
</Target>
However when I run this >msbuild XXXX.csproj /t:ExecuteFxCop it fails with error 512 which I have narrowed down to an exception from indirectly-referenced assemblys:
<Exception Keyword="CA0060" Kind="Engine" TreatAsWarning="True">
<Type>Microsoft.FxCop.Sdk.FxCopException</Type>
<ExceptionMessage>The indirectly-referenced Silverlight assembly 'System.Runtime.Serialization, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' could not be found. This assembly is not required for analysis, however, analysis results could be incomplete. Silverlight reference assemblies should be specified with the '/reference' switch. This assembly was referenced by: XXX\bin\ESRI.ArcGIS.Client.dll.</ExceptionMessage>
</Exception>
But I cannot add this reference. Is there a way to get the build to see this reference or preferably just disable the error altogether?
I did try: http://social.msdn.microsoft.com/Forums/en-US/vstscode/thread/c6780439-bc04-459e-80c3-d1712b2f5456/ but it doesn't work
Try the work-around here: http://geekswithblogs.net/blachniet/archive/2011/07/12/avoiding-fxcop-warning-ca0060.aspx
Edit
For example, using the FxCop MsBuild task, set ContinueOnError and check the ExitCode as follows:
<Target Name="ExecuteFxCop">
<ItemGroup>
<Files Include="bin\XXXX.dll" />
</ItemGroup>
<!-- Call the task using a collection of files and all default rules -->
<MSBuild.ExtensionPack.CodeQuality.FxCop
TaskAction="Analyse"
Files="#(Files)"
SearchGac="True"
OutputFile="FxCopReport.xml"
ContinueOnError="WarnAndContinue">
<Output TaskParameter="ExitCode" PropertyName="ExitCode"/>
</MSBuild.ExtensionPack.CodeQuality.FxCop>
<Error Condition="$(ExitCode) != 512" Text="FxCop failed with exit code: $(ExitCode)"/>
</Target>
P.S. (This is not tested)
Not sure if you're still looking for a solution but what usually works for me is adding the
fxcop cmd-option /d:{dir-of-random-assemblies}
which essentially tells fxcop to look in that additional directory for assemblies.
Adding a reference to a proj that doesn't need it is a bad idea in my opinion.
http://msdn.microsoft.com/en-US/library/bb429449(v=vs.80).aspx

How to change Assembly Version Number using AssemblyInfoTask?

I am trying to automate the process for setting the Version for all DLL's, after spending some time I came to know the AssemblyInfo Task with which it can most likely be achieved.
So I went ahead and installed it, specifically version 1.0.51130.0.
After Installing, I manually added the Import Tag (by unloading the each project) of AssemblyInfoTask in .cspoj files (the solution has more than 35 proj files).
<Import Project="$(MSBuildExtensionsPath)\Microsoft\AssemblyInfoTask\Microsoft.VersionNumber.Targets"/>
Next I modified the Microsoft.VersionNUmber.Target file which will be installed in path: C:\Program Files\MSBuild\Microsoft\AssemblyInfoTask, and I modified the following section:
<!-- Properties for controlling the Assembly Version -->
<PropertyGroup>
<AssemblyMajorVersion>4</AssemblyMajorVersion>
<AssemblyMinorVersion>0</AssemblyMinorVersion>
<AssemblyBuildNumber></AssemblyBuildNumber>
<AssemblyRevision></AssemblyRevision>
<AssemblyBuildNumberType>DateString</AssemblyBuildNumberType>
<AssemblyBuildNumberFormat>01MMdd</AssemblyBuildNumberFormat>
<AssemblyRevisionType>AutoIncrement</AssemblyRevisionType>
<AssemblyRevisionFormat>00</AssemblyRevisionFormat>
</PropertyGroup>
<!-- Properties for controlling the Assembly File Version -->
<PropertyGroup>
<AssemblyFileMajorVersion>4</AssemblyFileMajorVersion>
<AssemblyFileMinorVersion>0</AssemblyFileMinorVersion>
<AssemblyFileBuildNumber></AssemblyFileBuildNumber>
<AssemblyFileRevision></AssemblyFileRevision>
<AssemblyFileBuildNumberType>DateString</AssemblyFileBuildNumberType>
<AssemblyFileBuildNumberFormat>01MMdd</AssemblyFileBuildNumberFormat>
<AssemblyFileRevisionType>AutoIncrement</AssemblyFileRevisionType>
<AssemblyFileRevisionFormat>00</AssemblyFileRevisionFormat>
</PropertyGroup>
Next I set the assemblyInfo.cs file's version to 1.0.0.0 in every project. Finally I saved and close it, reopened solution, and built. It works like a champ!
Now what want is to customize the Version to 4.0.1053.1 where 10 is the part of year indicator which is 2010 and 53 denotes the week number, at last 1 denotes revision number.
How to achieve this using the AssemblyInfo Task? I came across several posts that a new version of AssemblyInfo Task is available in Build Extension Pack.
I have installed the MSBuild Extension Pack December 2010 and its version is MSBuild Extension Pack 4.0.2.0 Installer
First.. use a globalassemblyinfo.cs that is linked from each project.
Add its as linked file to each project.
This means you update one file, not 30+ assemblyinfo files...then:
use MSBuild.Community.Tasks....
Then call
<AssemblyInfo CodeLanguage="CS"
OutputFile="$(VersionFile)"
AssemblyCompany="Company"
AssemblyProduct="Product"
AssemblyCopyright="Copyright © Company 2011"
ComVisible="false"
AssemblyVersion="$(BUILD_NUMBER)"
AssemblyFileVersion="$(BUILD_NUMBER)" />
Assuming you have something like:
<Import Project=".\tasks\MSBuild.Community.Tasks.Targets"/>
I do this in Jenkins by having a package build that is parameterised using the List Subversion Tags parameter type. The Subversion tag must follow the version number format (major.minor.revision.build), e.g. tags/2.0.0.1. The tag name is then assigned to a Jenkins parameter, e.g. $VERSION becomes 2.0.0.1
I use the WriteLinesToFile msbuild task to write out the assembly attribute to a second file alongside the PropertyInfo.cs called VersionInfo.cs. As checked in to source control, this just contains a default version number:
// Do not change this. The version is set on package builds only by setting the AsmVersion MSBuild property
[assembly: System.Reflection.AssemblyVersion("0.0.0.0")]
The package build on the build server passes in the version via the AsmVersion parameter:
/p:AsmVersion=$VERSION
The .csproj file is modified to have a BeforeBuild target (Visual Studio creates a commented out one for you):
<Target Name="BeforeBuild">
<WriteLinesToFile
Condition=" '$(AsmVersion)' != '' " File="Properties\VersionInfo.cs"
Overwrite="True"
Lines="[assembly: System.Reflection.AssemblyVersion("$(AsmVersion)")] // Generated by build" />
</Target>
When building in Visual Studio, or without passing in the AsmVersion, your assembly will have a default version of 0.0.0.0. When building in the package build, you will get your desired build number.
As #bruceboughton proposed, you can easily generate a version assembly file during compilation without using MSBuild.Community.Tasks library:
<PropertyGroup>
<Version>0.0.0</Version>
<InformationalVersion>0.0.0-dev~commithash</InformationalVersion>
<VersionFileName>$(BaseIntermediateOutputPath)Version.cs</VersionFileName>
</PropertyGroup>
<Target Name="GenerateVersionFile" BeforeTargets="BeforeBuild">
<WriteLinesToFile
File="$(VersionFileName)"
Overwrite="True"
Lines="
[assembly: System.Reflection.AssemblyVersion("$(Version)")]
[assembly: System.Reflection.AssemblyFileVersion("$(Version)")]
[assembly: System.Reflection.AssemblyInformationalVersion("$(InformationalVersion)")]" />
<ItemGroup>
<Compile Include="$(VersionFileName)" />
</ItemGroup>
</Target>
Remove definitions of the parameters you specify in the generated file from Properties\AssemblyInfo.cs file.
After that you can specify version by adding a parameter to the msbuild:
msbuild /property:Version=1.2.3 /property:InformationalVersion=1.2.3-dev~commithash .\SolutionFile.sln
Update for .NET Core style .csproj files: If you've come upon this question after having transitioned to the new .csproj format used by .NET Core, you can just set the Version property (no need to to bother with MSBuild tasks).
How I finally got this to work MSBuild version 12 (VS 2013).
Used Nuget to get MSBuildTasks Community package
Edited my .csproj file and added a path to the import the package:
<Import Project="..\packages\MSBuildTasks.1.5.0.235\build\MSBuildTasks.targets" Condition="Exists('..\packages\MSBuildTasks.1.5.0.235\build\MSBuildTasks.target')"/>
Figured out the Regex to change just the Revision number in the AssemblyInfo.cs file:
(?<=AssemblyFileVersion\("[0-9]\.[0-9]\.[0-9]\.)(\*)
which is not XML compatible, so has to be changed to:
(?<=AssemblyFileVersion\("[0-9]\.[0-9]\.[0-9]\.)(\*)
Uncommented the <Target Name="BeforeBuild"> section and added the following:
<Target Name="BeforeBuild">
<FileUpdate Files="properties\AssemblyInfo.cs"
Regex="(?<=AssemblyFileVersion\("[0-9]\.[0-9]\.[0-9]\.)(\*)"
ReplacementText="$(Revision)" />
</Target>
When running MSBuild added the "Revision" property to the command line e.g.
msbuild.exe myProject.csproj /t:Build /p:Configuration=Release;Revision=12345

.NET Different References List for Debug / Release

In my debug build I have a reference to a DLL that is only required in the Debug configuration (the reference is for CodeSite, a logging tool).
Is it possible to exclude this reference in the Release build (my logging class only uses this reference when built in the Debug configuration).
Using VB.NET and VS2008.
Yes this is possible but it will require you to manually edit the .vbproj file. Once you have the file open you'll an XML reference tag for the DLL's you've referenced and it will look like the following
<Reference Include="SomeDllName" />
You need to add a condition property which species it should only be done during debug time
<Reference Include="SomeDllName" Condition="'$(Configuration)'=='Debug'" />
It's possible to do this, but you'll need to mess with the project file manually.
We do this in MiscUtil so we can have a .NET 2.0 build and a .NET 3.5 build. For instance:
<ItemGroup Condition=" '$(Configuration)' != 'Release 2.0' ">
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
<Aliases>global</Aliases>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
</ItemGroup>
That should be enough to get you started :) Basically take the current reference out of where it is in your normal project file, and put it in its own ItemGroup with an appropriate condition.