Why is the "DotNetCore" build task so slow? - .net-core

We've have a number of .Net Framework 4.x solutions, some of which were recently migrated to .Net 6. As part of this work I created build pipelines for the new solutions, however these are extremely slow when compared to the builds of the .Net Framework solutions.
The slow build task is ".Net Core" ("DotNetCoreCLI#2"), and is used in three places: "restore" command to restore the solution's NuGet packages, "build" command to build the solution, and "test" command to run the solution's unit test projects.
Taking one solution as an example (around 50 projects), these are the approx timings:
restore: 1m20s
build: 3m
unit tests: 3m
And here are the approx. timings from builds of the .Net Framework solution, which you can see were substantially faster:
restore: 9s - using the "NuGet" ("NuGetCommand#2") task
build: 1m13s - using the "Visual Studio Build" ("VSBuild#1") task
unit tests: 40s - using the "Visual Studio Test" ("VSTest#2") task
I believe the latter two tasks utilise VS2019 (installed on our on-prem Azure DevOps server), and I recently found this 3rd-party marketplace build task, which is a VS2022 equivalent of these tasks. I have updated the .Net6 build pipeline to use these instead of the "DotNetCoreCLI#2" build and test tasks (and I reverted to using "NuGetCommand#2" for the restore). The timings are now on a par with the .Net Framework build pipeline:
restore: 10s ("NuGetCommand#2")
build: 50s (marketplace task)
unit tests: 32s (marketplace task)
I would prefer to use built-in tasks over marketplace tasks, but why is the "DotNetCoreCLI" task so slow? Am I missing something with regards to configuration, or is it just a case of newer technology not always equating to improved performance?!

Visual Studio tasks are pretty heavy and largely there for legacy support.
When making the jump to modern .NET, rule #1 is forget everything about the old way you build projects. When using .NET 6, you get a much better experience doing everything with the dotnet CLI from NuGet package restoration (dotnet restore) to testing (dotnet test) and publishing an artifact (dotnet publish <ARGS>). Use those in your build pipeline with the UseDotNet#2 and DotNetCoreCLI#2 pipeline tasks.
Very important to note, in Azure DevOps you can cache your NuGet dependencies so you don't have to download them unless they change.

Related

Building MSI in azure devops

We have for a while been building various web projects with AzureDevops and self hosted build agents.
Today I had to add a new build, consisting of a windows service written in .net core 3.1. This service has to be installed by our customers, so we have to provide it in a friendly installable way. As some of our developers were already used to handle MSI/*.vdproj projects, they added a vdproj into the *.sln to manage that. On a developper machine, this is not a problem even with VS2019: you just have to use the relevant VS studio extension...
But when it comes to building that in a CI/CD context, this becomes a real challenge. I quickly understood that we can't use MSBuild at all for that and found some alternative using directly Visual Studio (devenv)... Inspired by this thread (still opened), I came up with the following command line:
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\devenv" [...]\MySolution.sln /build "Release" /Project MyInstallationProject
This worked fine both on my developer machine and even on the build agent machine. But when I add it into a build pipeline as a command line task, it seems to hang, and after a while I get the following result for the job:
##[error]The job running on agent <MyAgent> ran longer than the maximum time of 60 minutes. For more information, see https://go.microsoft.com/fwlink/?linkid=2077134
What can I do to make it work?
What are the best practices for generating a self installable in a CI/CD context? (Is MSI still relevant? )
As a workaround, you can try to install the extension Build VS Installer and use the task DutchWorkz - Build VS Installer(s) to build Visual Studio Installer Project in Azure Pipelines.
Here are some tickets(ticket1, ticket2) with similar issue you can refer to.

Difference between .NetCore, VisualStudio build and MSBuild task in Azure Pipeline?

I'm creating a new CI Azure Pipeline for my .Net Core projects. In Azure pipeline, Microsoft has provided three task for build i.e., .Net Core, Visual Studio Build and MSBuild.
Since all three task does build operation, do we have any specific criteria to choose one task over another?
I've gone through the documentation provided by Microsoft but I couldn't find much detail on this.
https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/build/visual-studio-build?view=azure-devops
Edit
Note: I'm aware that Visual Studio build task has a versioning sub task, but this can be achieved by separate custom task as well.
Difference between .NetCore, VisualStudio build and MSBuild task in Azure Pipeline?
As we know, dotnet is built on top of msbuild, we could call msbuild tasks by using the dotnet CLI.
That is the reason why you can use MSBuild task or .Net Core task to build your project/solution.
Assuredly, dotnet has some features that aren't in msbuild, like dotnet new. At this point, dotnet is easier to use than msbuild.
But, if we build some .net projects (not .net core), we just need use MSBuild task instead of .NET Core task. Because we do not need install unnecessary dotnet SDK.
So, when we building the project/solution without special needs, the .net core task and the msbuild task are just a matter of taste.
On the other hand, MSBuild is part of Visual Studio, when we build the project/solution with Visual Studio, it will invoke the MSBuild to execute some build task to complete the build project/solution.
Sometimes we do not want to install the full Visual Studio on our build server just to build our project/solution, in this case, we could use the MSBuild task to build the project/solution on the server instead of installing the full Visual Studio.
So in a nutshell, dotnet is built on top of msbuild and MSBuild is part of Visual Studio, that is the reason why you can use MSBuild and Visual Studio to build .net core project.
Check this thread for some more details.
Hope this helps.
Being not so rigorous, I can say that dotnet contains msbuild, and msbuild contains nuget. So as you can pack packages with msbuild, you can also build projects with dotnet.

build Coded UI tests in TFS 2017 + vsTest + error

I have codedUI and unit tests in my solution. Solution and the unit tests are successfully building in TFS 2017. CodedUI tests fail. I get an error.
Failed to initialize the unit test extension 'urn:CodedUITest': A unit test extension is not registered for the following attribute: Microsoft.VisualStudio.TestTools.UITesting.CodedUITestAttribute.
All the tests successfully pass in my local machine. What configuration am I missing in my build process?
kindly, help!.
According to the error info, seems the issue should more related to build agent Environment setting. Make sure you have Visual Studio and Coded UI features installed on the build agent. You could double check this by remote to the build agent and manually run Code UI in the agent machine instead of through TFS build.
If you are using Nuget Visual Studio Test Platform Installer , this is not support for now, take a look at the similar issue: VSTS build release agent unable to run Coded UI tests when using the Nuget VsTest platform
Currently Coded UI and UWP tests not support with VSTest platform
nuget package. /cc #PBoraMSFT for blog/doc and timeline for support.

dotnet core 1.0.1 preview2 freeze/hangs on dotnet test?

On some systems, and not others, at my office, it seems dotnet core is unstable, perhaps something else (visual studio 2017 rc?) is interfering, and "dotnet test" commands which work elsewhere, are hanging (no output, no tests run, just freezes):
xUnit.net .NET CLI test runner (64-bit .NET Core win10-x64)
Discovering: x.y.UnitTests
Discovered: x.y.UnitTests
Starting: x.y.UnitTests
I am trying to figure out what the cause of this is. It blocks CI and developers. I believe it may be possible to isolate and fix, and I'm asking this in case anyone sees it, or if I figure it out, I'll answer it so others who get stuck here can get unstuck.
xUnit support for dotnet core projects requires very specific versions of dotnet core, dotnet core CLI, xunit, and dotnet-test-xunit as defined in the xUnit documentation. I too have experienced the behavior you describe when attempting to run tests in Visual Studio Team Services where I unfortunately don't control the .NET Core CLI version. The same tests run without issue on my local machine, where I have confirmed that the xunit package versions and dotnet tooling versions match those supported by xUnit. I suspect that the machines you are experiencing the issues on do not have the supported dotnet tooling and xunit package versions.
I found a solution to my very similar issue. I used anynch methods in my tests and accessed the result with .Result. This can cause a deadlock situation in x-unit. Instead try declaring your methods with async and then using await to get the result. I found the solution on stackoverflow
Following xUnit docs I've switched to using dotnet xunit command instead of dotnet test. Also I had to specify extra parameter -parallel none. That solved my issue.

How to continue to use ASP.NET Core RC1 tooling on Azure

We have a project using ASP.NET Core RC1 on Azure. This is using continuous deployment and has been working without issue for months. We plan to convert this project to use RC2 and the associated dotnet CLI tools shortly, although we can't do this just yet.
Our builds are working fine locally. However we have recently started getting build errors when we deploy to live, chiefly the following (taken from the deployment log on Azure):
Compiling Infrastructure for DNX,Version=v4.5.1
D:\Program Files (x86)\dotnet\dotnet.exe compile-csc #D:\home\site\repository\Source\Infrastructure\obj\Release\dnx451\dotnet-compile.rsp returned Exit Code 1
My assumption looking at this is that Azure is now using the RC2 toolchain by default, even though we wish to stick with RC1 for the time being (we have had the following in our global.json file for months)
{
"sdk": {
"version": "1.0.0-rc1-update1"
},
.........
}
Is this assumption correct, and is there a way to force the build process to continue to use the RC1 components (dnx etc.) for the time being?
This thread suggests that RC1 is now no longer supported "out of the box" for these deployments, and references a post providing two workarounds to this issue:
Use a custom deployment script
Manually set the version of Kudu in App Settings
I have chosen the latter as this was the quickest implementation, and our deployments are now building correctly as before.

Resources