How can I get GitVersion /UpdateAssemblyInfo to work with ASP.NET Core 2.0 project - asp.net-core

We have been using a Bamboo build server for a while now and we have GitVersion installed so it can be selected as a task in the Build plan. We typically use the /UpdateAssembleInfo argument when we run the task. For .NET Framework projects, this would update the assemblyinfo file in the source with the bamboo versioning settings so the .NET assemblies had the same version info as our Bamboo builds and subsequent Bamboo deployment, allowing us to know the version of the deployed project in the field by examining the assembly file properties. This was all working quite well.
However, we are now building and deploying .NET Core 2.0 solutions and are finding that GitVersion /UpdateAssemblyInfo is not working.
I searched for a fix for .NET Core but was only able to find solutions that involved using the project.json file, which is no longer used with .NET Core 2.0 ( it changed to the *.csproj file).
I looked at http://gitversion.readthedocs.io/en/latest/usage/command-line/ and I tried running
gitversion.exe /UpdateAssemblyInfo MyProjectName.AssemblyInfo.cs /EnsureAssemblyInfo
where MyProjectName represents the actual project name suffix for the assemblyinfo.cs file in the .NET Core 2.0 ..\\obj\release\netcoreapp2.0 folder. But it did not update that file.
I have to assume that there has to be a solution for using GitVersion with Bamboo and.NET Core 2.0 but I am having a hard time finding one.
Any ideas?

The latest version of GitVersion provides /updateprojectfiles switch to update version info in the Sdk-style .csproj/.vbproj/.fsproj recursively.
From GitVersion/Usage/CommandLine/Arguments:
/updateprojectfiles
Will recursively search for all project files
(.csproj/.vbproj/.fsproj) files in the git repo and update them
Note: This is only compatible with the newer Sdk projects
It produces the needed attributes even if they are not present in the project files, resulting in following properties:
<Project>
<PropertyGroup>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
<InformationalVersion>1.0.0-versionNumber.N+Branch.branchName.Sha.commitId</InformationalVersion>
<Version>1.0.0-versionNumberNNNN</Version>
</PropertyGroup>

As a workaround, you may consider specifying the assembly info as project properties in .csproj
<PropertyGroup>
<Version>1.2.3.4</Version>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
...
</PropertyGroup>
and then setting values during dotnet build. In addition to its options, the dotnet build command accepts MSBuild options like /property
/property:name=value
/p:name=value
Set or override the specified project-level properties, where name is the property name and value is the property value. Specify each property separately, or use a semicolon or comma to separate multiple properties.
So your build command will be something like
dotnet build /p:Version=1.2.3.4;AssemblyVersion=1.2.3.4

Related

MSBuild 16.9 .NET Core 3.1 - OutDir isn't searched for dependencies

I'm trying to use MSBuild in a powershell script to build many projects and solutions in a full application suite. I set the parameter for OutDir to point to a single binaries directory and from an output perspective that works.
However the documentation states that OutDir is included in AssemblySearchPaths. But looking at the logs MSBuild is clearly stuck using the hintpath from the csproj file. I've tried setting AdditionalLibPaths as well with no success. This appears to be an issue with building from Visual Studio 2019 as well. My hintpaths point to a common debug directory. A release build still looks in the debug directory. This used to work in older versions of Studio in the .NET Framework days. It worked in older TFS XAML builds setting Output Location to "SingleFolder"
I've also played around with OutDir path ending various quantities of back slashes. I suspect that this old issue is fixed.
How can I get MSBuild to use an alternate directory for the dependencies?
https://learn.microsoft.com/en-us/visualstudio/msbuild/common-msbuild-project-properties?view=vs-2019
EDIT:
As per the accepted answer, adding OutDir to the AssemblySearchPaths does the trick. For me, I've created a proj file that I've added to each .NET Core csproj files. My thought is that when this gets fixed I can remove the tweak in one place.
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<AssemblySearchPaths>$(AssemblySearchPaths);$(OutDir)</AssemblySearchPaths>
</PropertyGroup>
My hintpaths point to a common debug directory. A release build still
looks in the debug directory.
The outdir is always the output folder which does not distinguish between Release and Debug. So you have to use <OutDir>C:\ttt\$(Configuration)\</OutDir> to distinguish between them.
Actually, the system msbuild properties are read earlier than the start of build task. You have to set the properties before the start of build process.
Simply modifying the system properties outdir in csproj will only take effect during the build process, but the system properties are still read before the build starts, also AssemblySearchPaths property read the previous outdir property. So you always take the default values before the modification.
You have to use Directory.Build.props file, it set the values earlier than msbuild start.
1) create a file called Directory.Build.props under your project folder.
2) add the outdir property like these into the file.
<Project>
<PropertyGroup>
<OutDir>C:\ttt\$(Configuration)\</OutDir>
</PropertyGroup>
</Project>
3) restart VS to enable it.
However, I note that it works well in non-sdk net framework projects but it does not list under new-sdk net core projects.
non-sdk net framework projects
new-sdk net core projects
Not sure it is an issue or the Team has forgotten it. Anyway, I have reported it to our DC Forum. You can vote it or add any comments if I did not described it in detail.
As a workaround, you could try to set the new value for AssemblySearchPaths property.
In order not to lose the original value of AssemblySearchPaths, you must add it to csporj file rather than Directory.Build.props file.
Just add these into csproj file:
<PropertyGroup>
<AssemblySearchPaths>$(AssemblySearchPaths);$(OutDir)</AssemblySearchPaths>
</PropertyGroup>
Update 1
I think it is an issue for net core projects.
What I said before is for VS IDE build. Now for MSBuild Command Line, it is another situation.
For non-sdk net framework projects
When I used msbuild xxx\xxx.csproj -p:outdir=c:\ttt -v:diagnostic, it shows this:
Well. It works perfect as we wished.
However, when we used the same command line for new-sdk net core projects, it does nothing. So I think it is quite an issue for net core projects.
And you should note that AdditionalLibPaths cannot be recognized by AssemblySearchPaths.
When I used this under :
msbuild xxx\xxx.csproj -p:AdditionalLibPaths=c:\ttt -v:diagnostic
And you should note that there is no property for AdditionalLibPaths under the list of AssemblySearchPaths property. And it also does not work for net core projects.
In short, it is quite an issue for net core projects no doubt. I also modify the DC ticket.
Now for new-sdk net core projects,
Since you used msbuild command line to set properties, so there is no need to use Directly.Build.props file. MSbuild command line property assignment is actually the same effect of the file.
Also, AssemblySearchPaths is not ready-only. You could modify it. And actually, all msbuild properties can be overwritten and that is a flexible feature of MSBuild.
In summary, you still have to use AssemblySearchPaths.
Solution
Since The Team has some problems with this detail in the net core project, we can use the flexibility of MSbuild to manually modify to get what we want:
1) abandon using Directly.Build.props file and also keep adding these on the net core csproj file:
<PropertyGroup>
<AssemblySearchPaths>$(AssemblySearchPaths);$(OutDir)</AssemblySearchPaths>
</PropertyGroup>
2) use the following command line for net core projects:
msbuild xxx\xxx.csproj -p:Outdir=c:\ttt -v:diagnostic

disable web.config generation for asp.net core 3.1 project

The dotnet publish command for my ASP.NET Core 3.1 project creates a web.config file in my publish/ directory. I don't want this file to be generated (or copied to that folder, at least) - it is never to be used with IIS at all.
When I took a look at the command output with verbosity increased, I found the following text:
Target "_TransformWebConfig" in file "C:\Program Files\dotnet\sdk\3.1.200\Sdks\Microsoft.NET.Sdk.Publish\targets\TransformTargets\Microsoft.NET.Sdk.Publish.TransformFiles.targets" from project "C:\repos\reportweb\reportweb\reportweb.csproj" (target "_AspNetCoreProjectSystemPostPublish" depends on it):
Using "TransformWebConfig" task from assembly "C:\Program Files\dotnet\sdk\3.1.200\Sdks\Microsoft.NET.Sdk.Publish\targets\..\tools\netcoreapp2.1\Microsoft.NET.Sdk.Publish.Tasks.dll".
Task "TransformWebConfig"
Configuring the following project for use with IIS: 'C:\repos\reportweb\reportweb\bin\Release\netcoreapp3.1\linux-x64\publish\'
Updating web.config at 'C:\repos\reportweb\reportweb\bin\Release\netcoreapp3.1\linux-x64\publish\web.config'
Configuring project completed successfully
Done executing task "TransformWebConfig".
Done building target "_TransformWebConfig" in project "reportweb.csproj".
Is it somehow possible to configure my project to skip the _TransformWebConfig Target or TransformWebConfig Task - or to use another way to skip the generation? I know I could make MSBuild delete the file afterwards, but having this disabled seems less hacky to me.
You can control this with the IsWebConfigTransformDisabled MSBuild property:
To prevent transformations of the web.config file, set the MSBuild property $(IsWebConfigTransformDisabled):
dotnet publish /p:IsWebConfigTransformDisabled=true
Because this is an MSBuild property, you can also set it in the .csproj, instead of passing it as a command-line argument:
<PropertyGroup>
<IsWebConfigTransformDisabled>true</IsWebConfigTransformDisabled>
</PropertyGroup>

MSBuild Exclude Project when DeployOnBuild flag is set to true

I have the following msbuild arguments:
/m /p:DeployOnBuild=true;PublishProfile="$(PublishProfile).pubxml"
I've added a project that is a shared .NET Web Application that should not be deployed, and does not need publish profiles. However when my build agent runs, it fails because my project does not have publish profiles.
Is there a way to exclude a project or somehow work around this without having to specify individual projects to include?
Is there a way to exclude a project or somehow work around this without having to specify individual projects to include?
AFAIK, I am afraid there is no such way or property we could exclude a project to be deployed on the Azure DevOps directly.
If you do not want to specify individual projects to include.
As a workaround, you could define the property DeployOnBuild in the projects that you want to publish, and pass a value to the property in msbuild arguments to make only this(those) project(s) can be built.
Details:
Edited project(s) which you want to publish and added the following property group before the Import statements in the .csproj file:
<PropertyGroup>
<DeployOnBuild Condition=" '$(DeployProjOrNot)'!='' ">$(DeployProjOrNot)</DeployOnBuild>
</PropertyGroup>
Then the msbuild arguments:
/m /p:DeployProjOrNot=true /p:PublishProfile="$(PublishProfile).pubxml"
In this case, those projects will be published, and the shared .NET Web Application (should not add above Property) will not be published due to the value of the property DeployOnBuild is not set to be true.
Hope this helps.

Why is .Net Core 2.2 now publishing a ton of other dlls

I just upgraded my .net core 2.0 project to 2.2. To my knowledge, I didn't change any other settings, but now when I publish to my file system, it publishes a ton of folders and dlls that it didn't before.
Do I need to publish them? If not, can I suppress their output?
Here is my publish profile settings:
Here is what the output directory looked like before the upgrade:
Now, here is just a snippet of what the output directory looks like:
Introduction: This issue seems to result from .net core 2.0.
From the picture you shared above. I know you choose Framework-Dependent Mode.
In this mode, generated files should be like what you have in picture1. And if your choose self-contained mode, generated files should be like what you have in picture2.
But in .net core2.0, there seems to be some different. When we publishing projects in .net core2.0, or just upgraded from 2.0 like yours. We must set self-contained property to false explicitly so that the Framework-Dependent mode can work normally.
Do I need to publish them?
No, you don’t need to publish generated files from self-contained mode as you choose framework-dependent mode.
If not, can I suppress their output?
Here is one workaround:
Looks like you use VS IDE to publish it, when publishing make sure choose 'create profile'. So we will have a PublishProfile, we can find it below Properties in Solution Window. Open the FolderProfile.pubxml and add the <PublishWithAspNetCoreTargetManifest>true</PublishWithAspNetCoreTargetManifest> in the PropertyGroup. Also, we can set the <DeleteExistingFiles>false</DeleteExistingFiles> to true.
After that, publish the project again the issue can be resolved.
The final format of PublishProfiles looks like below:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
...
<publishUrl>bin\Release\netcoreapp2.2\publish\</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
<PublishWithAspNetCoreTargetManifest>true</PublishWithAspNetCoreTargetManifest>
</PropertyGroup>
</Project>
In addition: You can find more info from this issue. Thanks to natemcmaster. His advice do work at my side.

specflow fails when trying to generate test execution report

I've got a project that's using SpecFlow, NUnit and Coypu to do acceptance tests on a web application. I've got the project building OK via Jenkins on a build server. Jenkins calls a psake script which runs msbuild on the specs project, then the script calls nunit-console to run the specs/tests, and then I want to generate a report from SpecFlow.
Framework "4.0"
task Default -depends RunSpecs
task BuildSpecs {
$env:EnableNuGetPackageRestore = "true"
msbuild /t:Rebuild ReturnsPortal.Specs.csproj
}
task RunSpecs -depends BuildSpecs {
exec { & "C:\path\to\NUnit 2.5.9\bin\net-2.0\nunit-console-x86.exe" /labels /out=TestResult.txt /xml=TestResult.xml .\bin\Debug\TheWebApp.Specs.dll }
exec { & "C:\path\to\SpecFlow\1.8.1\specflow.exe" nunitexecutionreport TheWebApp.Specs.csproj /out:SpecResult.html }
}
That last exec call to specflow.exe fails though, with:
The element <ParameterGroup> beneath element <UsingTask> is unrecognized. C:\Program Files (x86)\Jenkins\jobs\TheWebApp\workspace\Web\Sites\TheWebApp.nuget\nuget.targets
A bit of googling hints that maybe it's a problem with the msbuild version being used (e.g. here, here). But I have Framework "4.0" in my psake script, and the Specs project is targeting .NET Framework 4.0, and it builds fine in the build step, so I'm not sure why specflow seems to be using an earlier version of msbuild. Or is maybe the problem somewhere else?
This was the answer for me, from the SpecFlow Wiki:
Important for .NET 4.0 projects: Because specflow.exe is compiled for .NET 3.5, it cannot load .NET 4.0 assemblies by default. To generate this report for .NET 4.0 projects, you have to force specflow.exe to use the .NET 4.0 runtime by using the config file. Just copy the config below and create a specflow.exe.config file and put it next to your specflow.exe and you will be able to create the step definition report.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0.30319" />
</startup>
</configuration>
I attempted to use the config file solution suggested above. It worked for testing locally, but as soon as I pushed my code to our CI environment it choked on it since the CI environment doesn't have that config file. We restrict out CI environment to only use clean versions of the various packages, so we didn't want to try to inject the special config into the CI server.
We noticed that SpecFlow works just fine with several of our .NET 4.0 projects without the special config file. After a little research, the actual 'problem' appears to be NuGet 2.1. Everything works fine for .NET 4.0 projects with NuGet 1.7.
Somewhere between 1.7 and 2.1 NuGet introduced new features in the NuGet.targets file that aren't supported by the older versions of MSBuild. Specifically the problem seems to be the <ParameterGroup> beneath element <UsingTask>, as explained by the error message.
A cursory glance at the targets file indicates that the section is responsible for keeping NuGet up to date. Removing this section completely resolves the issue in the same manner that adding the config file above does, albeit also removing the self-update functionality that is seems to provide. Given that the .targets file is committed to the repository, this solution also works on our CI environment with out any changes on the CI side.
It's not necessarily a better solution than ngm's, it's just a different one. Depending on your environment, this may be a preferable way to go, or perhaps not.