Build, test, and deploy .NET Core apps

TFS 2017

Use a pipeline to automatically build and test your .NET Core projects. Learn how to do the following tasks:

Note

For help with .NET Framework projects, see Build ASP.NET apps with .NET Framework.

Note

In Microsoft Team Foundation Server (TFS) 2018 and previous versions, build and release pipelines are called definitions, runs are called builds, service connections are called service endpoints, stages are called environments, and jobs are called phases.

Note

The following guidance applies to TFS version 2017.3 and newer.

Create your first pipeline

Create a .NET project

If you don't have a .NET project to work with, create a new one, and upload your code to your GitHub repository or Azure Repos. Start by installing the latest .NET 6.0 SDK.

Create a new .NET 6 webapp.

dotnet new webapp -f net6.0

From the same terminal session, run the application locally using the dotnet run command from your project directory.

dotnet run

Upload your code

Upload your code to new webapp GitHub or Azure Repos:

Create the pipeline

Classic

  1. Create a pipeline and select the Empty Pipeline template.

  2. In the task catalog, find and add the .NET Core task. The following task runs dotnet build to build the code in the sample repository.

  3. Save the pipeline and queue a build. When the Build #nnnnnnnn.n has been queued message appears, select the number link to see your pipeline in action.

    You now have a working pipeline that's ready for you to customize!

  4. When you're ready to make changes to your pipeline, Edit it.

Read further to learn some of the more common ways to customize your pipeline.

Build environment

You can build your .NET Core projects by using the .NET Core SDK and runtime on Windows, Linux, or macOS. Your builds run on a self-hosted agent. Make sure that you have the necessary version of the .NET Core SDK and runtime installed on the agent.

Restore dependencies

NuGet is a popular way to depend on code that you don't build. You can download NuGet packages and project-specific tools that are specified in the project file by running the dotnet restore command either through the .NET Core task or directly in a script in your pipeline.

You can download NuGet packages from NuGet.org.

dotnet restore internally uses a version of NuGet.exe that's packaged with the .NET Core SDK. dotnet restore can only restore packages specified in the .NET Core project .csproj files. If you also have a Microsoft .NET Framework project in your solution or use package.json to specify your dependencies, use the NuGet task to restore those dependencies.

In .NET Core SDK version 2.0 and newer, packages get restored automatically when running other commands such as dotnet build.

  1. Select Tasks in the pipeline. Select the job that runs your build tasks. Then, select + to add a new task to that job.

  2. In the task catalog, find and add the .NET Core task.

  3. Select the task and, for Command, select restore.

  4. Specify any other options you need for this task. Then save the build.

Note

Make sure the custom feed is specified in your NuGet.config file and that credentials are specified in the NuGet service connection.

Build your project

You build your .NET Core project either by running the dotnet build command in your pipeline or by using the .NET Core task.

Build

  1. Select Tasks in the pipeline. Select the job that runs your build tasks. Then select + to add a new task to that job.

  2. In the task catalog, find and add the .NET Core task.

  3. Select the task and, for Command, select build or publish.

  4. Specify any other options you need for this task, and then save the build.

Install a tool

To install a .NET Core global tool like dotnetsay in your build running on Windows, take the following steps:

  1. Add the .NET Core task and set the following properties:

    • Command: custom.
      • Path to projects: leave empty.
    • Custom command: tool.
    • Arguments: install -g dotnetsay.
  2. Add a Command Line task and set the following properties:

    • Script: dotnetsay.

Run your tests

If you have test projects in your repository, then use the .NET Core task to run unit tests by using testing frameworks like MSTest, xUnit, and NUnit.The test project must reference Microsoft.NET.Test.SDK version 15.8.0 or higher. Test results get automatically published to the service. These results are available to you in the build summary and can be used for troubleshooting failed tests and test-timing analysis.

Use the .NET Core task with Command set to test. Path to projects should refer to the test projects in your solution.

Collect code coverage

If you're building on the Windows platform, code coverage metrics can be collected by using the built-in coverage data collector. The test project must reference Microsoft.NET.Test.SDK version 15.8.0 or higher. If you use the .NET Core task to run tests, coverage data is automatically published to the server. The .coverage file can be downloaded from the build summary for viewing in Visual Studio.

  1. Add the .NET Core task to your build job and set the following properties:

    • Command: test.
    • Path to projects: Should refer to the test projects in your solution.
    • Arguments: --configuration $(BuildConfiguration) --collect "Code coverage".
  2. Ensure that the Publish test results option remains selected.

Collect code coverage metrics with Coverlet

If you're building on Linux or macOS, you can use Coverlet or a similar tool to collect code coverage metrics.

You can publish code coverage results to the server with the Publish Code Coverage Results task. The coverage tool must be configured to generate results in Cobertura or JaCoCo coverage format.

To run tests and publish code coverage with Coverlet, do the following tasks:

  • Add a reference to the coverlet.msbuild NuGet package in your test project(s) for .NET projects below .NET 5. For .NET 5, add a reference to the coverlet.collector NuGet package.
  • Add the following snippet to your azure-pipelines.yml file:
- task: UseDotNet@2
  inputs:
    version: '5.0.x'
    includePreviewVersions: true # Required for preview versions
  
- task: DotNetCoreCLI@2
  displayName: 'dotnet build'
  inputs:
    command: 'build'
    configuration: $(buildConfiguration)
  
- task: DotNetCoreCLI@2
  displayName: 'dotnet test'
  inputs:
    command: 'test'
    arguments: '--configuration $(buildConfiguration) --collect:"XPlat Code Coverage" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura'
    publishTestResults: true
    projects: 'MyTestLibrary' # update with your test project directory
  
- task: PublishCodeCoverageResults@1
  displayName: 'Publish code coverage report'
  inputs:
    codeCoverageTool: 'Cobertura'
    summaryFileLocation: '$(Agent.TempDirectory)/**/coverage.cobertura.xml'

Package and deliver your code

Upload the build output to Azure Pipelines. You can create and publish a NuGet package, or package the build output into a .zip file to deploy to a web application.

Publish artifacts to Azure Pipelines

Use the Publish Artifacts task to publish the output of your build to Azure Pipelines.

Publish to a NuGet feed

If you want to publish your code to a NuGet feed, take the following steps:

  1. Use a .NET Core task with Command set to pack.

  2. Publish your package to a NuGet feed.

Deploy a web app

  1. Use a .NET Core task with Command set to publish.

  2. Make sure you've selected the option to create a .zip file archive.

  3. To publish this archive to a web app, see Azure Web Apps deployment.

Build an image and push to container registry

For your app, you can also build an image and push it to a container registry.

Troubleshoot

If you can build your project on your development machine, but you're having trouble building it on Azure Pipelines, explore the following potential causes and corrective actions:

  • Check the .NET Core SDK versions and runtime on your development machine and make sure they match the agent. You can include a command-line script dotnet --version in your pipeline to print the version of the .NET Core SDK. Either use the .NET Core Tool Installer to deploy the same version on the agent, or update your projects and development machine to the newer version of the .NET Core SDK.

  • You might be using some logic in the Visual Studio IDE that isn't encoded in your pipeline. Azure Pipelines runs each of the commands you specify in the tasks one after the other in a new process. Examine the logs from the pipelines build to see the exact commands that ran as part of the build. Repeat the same commands in the same order on your development machine to locate the problem.

  • If you have a mixed solution that includes some .NET Core projects and some .NET Framework projects, you should also use the NuGet task to restore packages specified in packages.config files. Add the MSBuild or Visual Studio Build task to build the .NET Framework projects.

  • Your builds might fail intermittently while restoring packages: either NuGet.org is having issues, or there are networking problems between the Azure data center and NuGet.org. You may want to explore whether using Azure Artifacts with NuGet.org as an upstream source improves the reliability of your builds, as it's not in our control.

  • Occasionally, when we roll out a new version of the .NET Core SDK or Visual Studio, your build might break. For example, if a newer version or feature of the NuGet tool gets shipped with the SDK. To isolate this issue, use the .NET Core Tool Installer task to specify the version of the .NET Core SDK that's used in your build.

FAQ

Q: Where can I learn more about Azure Artifacts and the TFS Package Management service?

A: Package Management in Azure Artifacts

Q: Where can I learn more about .NET Core commands?

A: .NET Core CLI tools

Q: Where can I learn more about running tests in my solution?

A: Unit testing in .NET Core projects

Q: Where can I learn more about tasks?

A: Build and release tasks