Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
This article describes how to use Azure Pipelines to work with .NET Core projects. The article walks you through the following tasks:
- Create a .NET Core web app and upload it to a GitHub repository.
- Create an Azure DevOps project and an Azure Pipelines pipeline to build the project.
- Set up your build environment with self-hosted agents.
- Restore dependencies, build your project, and test with the .NET Core (
DotNetCoreCLI@2
) task or a script. - Use the .NET Core (
DotNetCoreCLI@2
) task to add other .NET SDK commands to your pipeline. - Use the Publish Code Coverage Results (
Publish code coverage results v2
) task to publish code coverage results. - Package and deliver your build output to your pipeline, a NuGet feed, a ZIP archive, or other targets.
- Create a .NET Core web app and upload it to a GitHub repository.
- Create an Azure DevOps project and an Azure Pipelines pipeline to build the project.
- Set up your build environment with Microsoft-hosted or self-hosted agents.
- Restore dependencies, build your project, and test with the .NET Core (
DotNetCoreCLI@2
) task or a script. - Use the .NET Core (
DotNetCoreCLI@2
) task to add other .NET SDK commands to your pipeline. - Use the Publish Code Coverage Results (
Publish code coverage results v2
) task to publish code coverage results. - Package and deliver your build output to your pipeline, a NuGet feed, a ZIP archive, or other targets.
Note
To work with .NET Framework projects, see Build ASP.NET apps with .NET Framework.
Prerequisites
To complete all the procedures in this article, you need the following prerequisites:
- An Azure DevOps organization. You can create one for free.
- Membership in the organization Project Administrators group, so you can create Azure DevOps projects and grant project access to pipelines. Azure DevOps organization owners automatically have this membership.
- An Azure DevOps project in the organization. Create a project in Azure DevOps.
- The ability to run pipelines on Microsoft-hosted agents, by requesting a free tier of parallel jobs. This request can take several business days to process. For more information, see Configure and pay for parallel jobs.
- The Administrator or Creator role for service connections, which you can assign as a Project Administrator.
- A GitHub account and repository.
To complete all the procedures in this article, you need the following prerequisites:
- An Azure DevOps collection.
- An Azure DevOps project created in the organization. For instructions, see Create a project in Azure DevOps.
- Membership in the Project Administrators group, so you can create Azure DevOps projects and grant project access to pipelines. Azure DevOps Organization owners automatically have this membership.
- The Administrator or Creator role for service connections, which you can assign as a Project Administrator.
- A GitHub account and repository.
Create a .NET project and upload it to GitHub
If you want to use a .NET project already in your GitHub repository, you can skip this section.
If you don't have a .NET project to work with, create a new one on your local machine as follows:
- Install the .NET 8.0 SDK, or make sure it's installed.
- Open a terminal window on your local machine.
- Create a project directory and navigate to it.
- Create a new .NET 8 web app by running
dotnet new webapp -f net8.0
. - Build and run the application locally by using
dotnet run
. - When the application starts, press Ctrl+C to shut it down.
- Upload or connect the local project to your GitHub repository.
Create a pipeline
If you have a pipeline you want to use, you can skip this section. Otherwise, you can use either the YAML pipeline editor or the classic editor to create a pipeline as follows:
In your Azure DevOps project, select Pipelines from the left navigation menu.
Select New pipeline or Create pipeline if this pipeline is the first in the project.
On the Where is your code screen, select GitHub.
You might be redirected to GitHub to sign in. If so, enter your GitHub credentials.
On the Select a repository screen, select the repository your .NET app is in.
You might be redirected to GitHub to install the Azure Pipelines app. If so, select Approve & install.
On the Configure tab, select Show more and then select the ASP.NET Core pipeline template from the list. This template provides many of the steps and settings that this article describes.
You can also select Starter pipeline on the Configure tab to start with a minimal pipeline and add the steps and settings yourself.
On the Review tab, examine the YAML code. You can customize the file for your requirements. For example, you can specify a different agent pool or add a task to install a different .NET SDK.
In your Azure DevOps project, select Pipelines from the left navigation menu.
Select New pipeline or Create pipeline if this pipeline is the first in the project.
Select your source repository type. For this example, use GitHub Enterprise Server.
On the next screen, enter the following information:
- The URL for your GitHub account, for example
https://github.com/myname
. - Your GitHub personal access token (PAT).
- A service connection name, for example
my-github
.
- The URL for your GitHub account, for example
Select Create.
Select your GitHub repository.
On the Configure tab, select Show more and select the ASP.NET Core pipeline template from the list. This template provides many of the steps and settings that this article describes.
Examine the new YAML pipeline code. You can customize the YAML file for your requirements. For example, you could add a task to install a different .NET SDK or to test and publish your project.
When you're ready, select Save and run.
Optionally edit the Commit message, and then select Save and run again.
On the Summary tab, select the job in the Jobs section to watch your pipeline in action.
You now have a working pipeline that's ready to customize.
Set up your build environment
Azure Pipelines uses self-hosted agents to build your .NET Core project. You can use the .NET Core SDK and runtime on Windows, Linux, macOS, or Docker agents. Make sure that you have the necessary version of the .NET Core SDK and runtime installed on the agents.
To install a specific version of the .NET SDK, add the UseDotNet@2
task to a YAML pipeline file or the Use .NET Core task in the classic editor.
Note
For agents that run on physical systems, installing SDKs and tools through your pipeline alters the build environment on the agent's host.
The following example YAML snippet installs .NET SDK 8.0.x:
steps:
- task: UseDotNet@2
inputs:
version: '8.x'
To install a newer SDK, set performMultiLevelLookup
to true
.
steps:
- task: UseDotNet@2
displayName: 'Install .NET Core SDK'
inputs:
version: 8.x
performMultiLevelLookup: true
includePreviewVersions: true # Required for preview versions
You can select the agent pool and agent for your build job. You can also specify agents based on their capabilities. For example, the following YAML pipeline snippet selects a pool and agent capabilities.
pool:
name: myPrivateAgents
demands:
- agent.os -equals Darwin
- anotherCapability -equals somethingElse
You can build your .NET Core projects by using the .NET Core SDK and runtime for Windows, Linux, or macOS. By default, your builds run on Microsoft-hosted agents, so you don't need to set up infrastructure.
The Azure Pipelines Microsoft-hosted agents include several preinstalled versions of supported .NET Core SDKs. See Microsoft-hosted agents for a complete list of available images and configuration examples.
The following YAML pipeline snippet sets Ubuntu OS for the agent pool.
pool:
vmImage: 'ubuntu-latest'
Microsoft-hosted agents don't include some older versions of the .NET Core SDK, and don't typically include prerelease versions. If you need these versions of the SDK on Microsoft-hosted agents, you can install them by using the Use DotNet (UseDotNet@2) task.
For example, the following code installs the .NET 5.0.x SDK:
steps:
- task: UseDotNet@2
inputs:
version: '5.x'
Windows agents already include a .NET Core runtime. To install a newer SDK, set performMultiLevelLookup
to true
as in the following snippet:
steps:
- task: UseDotNet@2
displayName: 'Install .NET Core SDK'
inputs:
version: 8.x
performMultiLevelLookup: true
includePreviewVersions: true # Required for preview versions
Self-hosted agents
Alternatively, you can use self-hosted agents to build your .NET Core projects. You can set up Linux, macOS, or Windows self-hosted agents.
Self-hosted agents let you:
- Avoid the cost of running the
UseDotNet@2
tool installer. - Decrease build time if you have a large repository.
- Run incremental builds.
- Use preview or private SDKs that Microsoft doesn't officially support.
- Use SDKs available only on your corporate or on-premises environments.
For more information, see Self-hosted agents.
Restore dependencies
NuGet packages are a way for your project to depend on code that you don't build. You can download NuGet packages and project-specific tools by running the dotnet restore
command, either through the .NET Core (DotNetCoreCLI@2
) task or as a script in your pipeline. The dotnet restore
command uses the NuGet.exe packaged with the .NET Core SDK and can only restore packages specified in the .NET Core project *.csproj files.
You can use the .NET Core (DotNetCoreCLI@2
) task to download and restore NuGet packages from Azure Artifacts, NuGet.org, or another authenticated external or internal NuGet repository. If the NuGet feed is in the same project as your pipeline, you don't need to authenticate. For more information, see .NET Core task (DotNetCoreCLI@2).
When you use Microsoft-hosted agents, you get a new machine every time you run a build, which restores the packages with each run. Restoration can take a significant amount of time. To mitigate this issue, use Azure Artifacts or a self-hosted agent to take advantage of the package cache.
The following pipeline uses the DotNetCoreCLI@2
task to restore an Azure Artifact feed.
trigger:
- main
pool:
vmImage: 'windows-latest'
steps:
- task: UseDotNet@2
displayName: 'Install .NET Core SDK'
inputs:
version: 8.x
performMultiLevelLookup: true
includePreviewVersions: true # Required for preview versions
variables:
buildConfiguration: 'Release'
steps:
- task: DotNetCoreCLI@2
inputs:
command: 'restore'
feedsToUse: 'select'
vstsFeed: 'my-vsts-feed' # A series of numbers and letters
- task: DotNetCoreCLI@2
inputs:
command: 'build'
arguments: '--configuration $(buildConfiguration)'
displayName: 'dotnet build $(buildConfiguration)'
In .NET Core SDK version 2.0 and newer, packages restore automatically when you run commands such as dotnet build
. You still need to use the .NET Core (DotNetCoreCLI@2
) task to restore packages if you use an authenticated feed.
Manage the credentials for an authenticated feed by creating a NuGet service connection in Project Settings > Pipelines > Service connections. For more information about NuGet service connections, see Publish NuGet packages with Azure Pipelines.
Restore packages from NuGet.org
To restore packages from NuGet.org, update your pipeline as follows.
You can add the restore command to your pipeline by editing the YAML code directly or by using the task assistant.
Add the .NET Core (DotNetCoreCLI@2
) task directly by inserting the following snippet into your azure-pipelines.yml file before your build tasks.
steps:
- task: DotNetCoreCLI@2
displayName: Restore
inputs:
command: restore
projects: '**/*.csproj'
feedsToUse: select
To use the task assistant:
- Go to the position in the YAML file where you want to insert the task.
- Select .NET Core from the task catalog.
- On the configuration screen, select restore from the Command dropdown list.
- In the Path to project(s) or solution(s) field, enter the path to your *.csproj files. You can use the wildcard **/*.csproj for all *.csproj files in all subfolders.
- For Feeds to add, ensure that Feed(s) I select here and Use packages from NuGet.org are selected.
- Select Add.
- Select Validate and save, and then select Save to commit the change.
Restore packages from an external feed
To specify an external NuGet repository, put the URL in a NuGet.config file in your repository. Make sure any custom feed is specified in your NuGet.config file, and that credentials are specified in a NuGet service connection.
To restore packages from an external feed, add the restore
task as instructed in the previous section, but change the configuration settings as follows:
Add the .NET Core (DotNetCoreCLI@2
) task directly by inserting the following snippet into your azure-pipelines.yml file before your build tasks. Replace <NuGet service connection>
with your service connection name.
steps:
- task: DotNetCoreCLI@2
displayName: Restore
inputs:
command: restore
projects: '**/*.csproj'
feedsToUse: config
nugetConfigPath: NuGet.config # Relative to root of the repository
externalFeedCredentials: <NuGet service connection>
To use the task assistant:
- Add the .NET Core task and select restore on the configuration screen as in the preceding procedure.
- For Feeds to add, select Feeds in my NuGet.config.
- Under Path to NuGet.config, enter the path to your NuGet.config file, relative to the root of your repository. You can select the ellipsis ... next to the field to browse to and select the location.
- Under Credentials for feeds outside this organization/collection, select credentials to use for external registries in the selected NuGet.config file. For feeds in the same organization, you can leave this field blank. The build’s credentials are used automatically.
Restore packages for .NET Framework projects
If you also have a Microsoft .NET Framework project in your solution or use package.json to specify your dependencies, use the NuGetCommand@2 task to restore those dependencies.
- task: NuGetCommand@2
inputs:
command: 'restore'
restoreSolution: '**/*.sln'
feedsToUse: 'select'
Note
For Ubuntu 24.04 or higher, you must use the NuGetAuthenticate task instead of the NuGetCommand@2 task with the .NET CLI. For more information, see Support for newer Ubuntu hosted images.
Build your project
Build your .NET Core project by running the dotnet build
command. You can add the command to your pipeline by using the .NET Core (DotNetCoreCLI@2
) task or as a command line script.
Use the .NET Core task
You can add a build task with the YAML pipeline editor by directly editing the file or by using the task assistant.
Add the .NET Core (DotNetCoreCLI@2
) task directly by inserting the following snippet. Update the arguments
to match your needs.
steps:
- task: DotNetCoreCLI@2
displayName: Build
inputs:
command: build
projects: '**/*.csproj'
arguments: '--configuration $(buildConfiguration)'
To use the task assistant:
- Go to the position in the YAML file where you want to insert the task.
- Select the .NET Core (
DotNetCoreCLI@2
) task. - Select build from the Command dropdown list.
- In the Path to project(s) or solution(s) field, enter the path to your *.csproj files. You can use the wildcard **/*.csproj for all *.csproj files in all subfolders.
- Select Add.
- Select Save to commit the change.
Build .NET Core with a command line script
You can also build using a command line script.
To add a build command line by directly editing the YAML file, add the following code:
steps:
- script: dotnet build --configuration $(buildConfiguration)
displayName: 'dotnet build $(buildConfiguration)'
You can also use the task assistant to add the Command line task.
- Go to the position in the YAML file where you want to insert the task.
- Select the Command line (
CmdLine@2
) task from the list. - In the Script field, enter the
dotnet build
command with parameters. For example,dotnet build --configuration $(buildConfiguration)
. - Under Advanced > Working Directory, enter the path to the *.csproj file as the working directory. If you leave it blank, the working directory defaults to
$(Build.SourcesDirectory)
. - Select Add.
- Select Save to commit the change.
Add other .NET SDK commands to your pipeline
You can add other .NET SDK commands to your pipeline by using the .NET Core (DotNetCoreCLI@2
) task or as scripts.
Add a .NET CLI command with the .NET Core task
The .NET Core (DotNetCoreCLI@2) task lets you easily add .NET CLI commands to your pipeline. You can add .NET Core (DotNetCoreCLI@2
) tasks by editing your YAML file or by using the classic editor.
To add a .NET Core command using the task assistant in the YAML pipeline editor, do the following steps:
- Go to the position in the YAML file where you want to insert the task.
- Select .NET Core from the task catalog.
- Select the command you want to run from the dropdown list in the Command field.
- Configure any options needed.
- Select Add.
- Select Save to commit the change.
Add a .NET Core CLI command in a script
You can add a .NET Core CLI command as a script
in your azure-pipelines.yml file. For example:
steps:
# ...
- script: dotnet test <test-project>
Install a tool
To install a .NET Core global tool like dotnetsay in a build running on Windows, add a .NET Core task and set the following properties in the configuration:
- Command: custom
- Path to projects: leave empty
- Custom command:
tool
- Arguments:
install -g dotnetsay
To run the tool, add a Command Line task and enter dotnetsay
in the Script field.
Run your tests
When you have test projects in your repository, you can use the .NET Core (DotNetCoreCLI@2
) 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 automatically publish to the service and are available to you in the build summary. You can use the test results to troubleshoot failed tests and analyze test timing.
To add a test task to your pipeline, add the following snippet to your azure-pipelines.yml file:
steps:
# ...
# do this after other tasks such as build
- task: DotNetCoreCLI@2
inputs:
command: test
projects: '**/*Tests/*.csproj'
arguments: '--configuration $(buildConfiguration)'
If you use the task assistant to add the .NET Core (DotNetCoreCLI@2
) task, set the following properties:
- Command: test
- Path to projects: Set to the test projects in your solution
- Arguments:
--configuration $(BuildConfiguration)
Alternatively, you can run the dotnet test
command with a specific logger and then use the PublishTestResults@2
task:
steps:
# ...
# do this after your tests run
- script: dotnet test <test-project> --logger trx
- task: PublishTestResults@2
condition: succeededOrFailed()
inputs:
testRunner: VSTest
testResultsFiles: '**/*.trx'
Collect code coverage
When you build on the Windows platform, you can collect code coverage metrics by using the built-in coverage data collector. The test project must reference Microsoft.NET.Test.SDK version 15.8.0 or higher.
When you use the .NET Core (DotNetCoreCLI@2
) task to run tests, coverage data automatically publishes to the server. You can download the *.coverage file from the build summary to view in Visual Studio.
To collect code coverage, add the --collect "Code Coverage"
argument when you add the test task to your pipeline.
steps:
# ...
# do this after other tasks such as build
- task: DotNetCoreCLI@2
inputs:
command: test
projects: '**/*Tests/*.csproj'
arguments: '--configuration $(buildConfiguration) --collect "Code Coverage"'
If you use the task assistant to add the .NET Core (DotNetCoreCLI@2
) task, set the following properties:
- Command: test
- Path to projects: Set to the test projects in your solution
- Arguments:
--configuration $(BuildConfiguration) --collect "Code Coverage"
Ensure that the Publish test results option remains selected.
Alternatively, to collect code coverage results by using the dotnet test
command with a specific logger and then run the PublishTestResults@2 task, use the following code:
steps:
# ...
# do this after your tests run
- script: dotnet test <test-project> --logger trx --collect "Code Coverage"
- task: PublishTestResults@2
inputs:
testRunner: VSTest
testResultsFiles: '**/*.trx'
Collect code coverage metrics with Coverlet
If you build 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 (PublishCodeCoverageResults@2) task. You must configure the coverage tool to generate results in Cobertura or JaCoCo coverage format.
To run tests and publish code coverage with Coverlet:
- Add a reference to the
coverlet.collector
NuGet package. - Add the following snippet to your azure-pipelines.yml file:
- 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: '<test project directory>'
- task: PublishCodeCoverageResults@2
displayName: 'Publish code coverage report'
inputs:
codeCoverageTool: 'Cobertura'
summaryFileLocation: '$(Agent.TempDirectory)/**/coverage.cobertura.xml'
Package and deliver your code
To package and deliver your build output, you can:
- Publish your build artifacts to Azure Pipelines.
- Create a NuGet package and publish it to your NuGet feed.
- Publish your NuGet package to Azure Artifacts.
- Create a ZIP archive to deploy to a web app.
- Publish symbols to an Azure Artifacts symbol server or a file share.
You can also build an image for your app and push it to a container registry.
Publish artifacts to Azure Pipelines
To publish the output of your .NET build to your pipeline, follow these steps.
- Run
dotnet publish --output $(Build.ArtifactStagingDirectory)
using the .NET CLI, or add the .NET Core (DotNetCoreCLI@2
) task with the publish command. - Publish the artifact by using the Publish Pipeline Artifact (PublishPipelineArtifact@1) task. This task uploads all the files in
$(Build.ArtifactStagingDirectory)
as an artifact of your build.
Add the following code to your azure-pipelines.yml file:
steps:
- task: DotNetCoreCLI@2
inputs:
command: publish
publishWebProjects: True
arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)'
zipAfterPublish: True
- task: PublishPipelineArtifact@1
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)'
artifactName: 'myWebsite'
To copy more files to the build directory before publishing, use the Copy Files (CopyFile@2) task.
Note
The publishWebProjects
input in the .NET Core (DotNetCoreCLI@2
) task is set to true
by default, and publishes all web projects in your repository. For more information, see the azure-pipelines-tasks GitHub repository.
To publish the output of your .NET build to your pipeline, do the following tasks:
- Run
dotnet publish --output $(Build.ArtifactStagingDirectory)
using the .NET CLI or add the .NET Core (DotNetCoreCLI@2
) task with the publish command. - Publish the artifact by using the Publish build artifact (PublishBuildArtifacts@1) task.
The following azure-pipelines.yml code also publishes your build artifacts as a ZIP file. The PublishBuildArtifacts@1
task uploads all the files in $(Build.ArtifactStagingDirectory)
as an artifact of your build.
steps:
- task: DotNetCoreCLI@2
inputs:
command: publish
publishWebProjects: true
arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)'
zipAfterPublish: True
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
For more information, see Publish and download build artifacts.
Publish to a NuGet feed
To create a NuGet package and publish it to your NuGet feed, add the following snippet to your azure-pipelines.yml file:
steps:
# ...
# do this near the end of your pipeline
- script: dotnet pack /p:PackageVersion=$(version) # define the version variable elsewhere in your pipeline
- task: NuGetAuthenticate@1
inputs:
nuGetServiceConnections: '<NuGet service connection>'
- task: NuGetCommand@2
inputs:
command: push
nuGetFeedType: external
publishFeedCredentials: '<NuGet service connection>'
versioningScheme: byEnvVar
versionEnvVar: version
Note
The NuGetAuthenticate@1
task doesn't support NuGet API key authentication. If you're using a NuGet API key, use the NuGetCommand@2
task with the command
input set to push
and the --api-key
argument. For example, dotnet nuget push --api-key $(NuGetApiKey)
.
For more information about versioning and publishing NuGet packages, see Publish NuGet packages with Azure Pipelines.
Publish a NuGet package to Azure Artifacts
You can publish your NuGet packages to your Azure Artifacts feed by using the NuGetCommand@2 task. For more information, see Publish NuGet packages with Azure Pipelines.
Publish a ZIP file archive to a web app
To create a ZIP file archive that's ready to publish to a web app, add the following snippet to azure-pipelines.yml. Run this task after you build your app, near the end of your pipeline in most cases. For example, run this task before you deploy to an Azure web app on Windows.
steps:
# ...
- task: DotNetCoreCLI@2
inputs:
command: publish
publishWebProjects: True
arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)'
zipAfterPublish: True
To publish this archive to a web app, see Azure Web Apps deployment.
Publish symbols
You can use the PublishSymbols@2
task to publish symbols to an Azure Artifacts symbol server or a file share. For more information, see Publish symbols.
For example, to publish symbols to a file share, add the following snippet to your azure-pipelines.yml file:
- task: PublishSymbols@2
inputs:
SymbolsFolder: '$(Build.SourcesDirectory)'
SearchPattern: '**/bin/**/*.pdb'
IndexSources: true
PublishSymbols: true
SymbolServerType: 'FileShare'
SymbolsPath: '\\<server>\<shareName>'
To use the classic editor, add the Index sources and publish symbols task to your pipeline.
Troubleshooting
If your project builds successfully on your local machine but not in Azure Pipelines, explore the following potential causes and corrective actions.
- Prerelease versions of the .NET Core SDK aren't installed on Microsoft-hosted agents, and rolling out a new version of the SDK to all Azure Pipelines data centers can take a few weeks. Instead of waiting for a rollout to complete, you can use the Use .NET Core task to install the .NET Core SDK version you want on Microsoft-hosted agents.
A new version of the .NET Core SDK or Visual Studio could break the build, for example if it contains a newer version or feature of the NuGet tool. Make sure the .NET Core SDK versions and runtime on your development machine match the pipeline agent.
You can include a
dotnet --version
command-line script 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 pipeline version of the .NET Core SDK.Your builds might fail intermittently because of connection issues when you restore packages from NuGet.org. NuGet.org might be having issues, or there could be networking problems between the Azure data center and NuGet.org. You can explore whether using Azure Artifacts with upstream sources to cache the packages improves the reliability of your builds.
The credentials of the pipeline are automatically used to connect to Azure Artifacts. These credentials are typically derived from the Project Collection Build Service account. To learn more about using Azure Artifacts to cache your NuGet packages, see Connect to Azure Artifact feeds.
You might be using some logic in Visual Studio that isn't encoded in your pipeline. Azure Pipelines runs each command in a task sequentially in a new process. Examine the logs from the pipelines build to see the exact commands that ran in the build. To locate the problem, repeat the same commands in the same order on your development machine.
If you have a mixed solution that includes some .NET Core projects and some .NET Framework projects, use the NuGet task to restore packages specified in the packages.config files. Add the MSBuild or Visual Studio Build task to build the .NET Framework projects.