Microsoft has good documentation for this and this article was helpful , but I still had trials finding the correct way to version the package, so I’m sharing it here (for you and me in the future).
This package had an existing .Net Framework version. I added a .Net 8 version. I fell into the trap of going for the complicated approach first. I attempted to have a condition to switch between .Net and the Framework templates. It would have been easier to start with 2 different .yml files and setup path filters in the ADO UI and I ended up here.
Side note: I have decided to not use the term “Core” anymore. “Core” was used for the new version of .Net up until .Net 5. The History of .Net explains it well.
I went through a lot of iterations (which is typical for my pipeline building experiences of the past) before I finally got the package to publish. 31 builds on the .Net pipeline to be exact.
First create the initial YAML pipeline(s) in the main branch.
Then in the ADO UI > Edit the Pipeline. In the YAML tab, you can set the YAML path and filename if you decide to change the default. In Variables, set those that can be overridden in the yml and in Triggers add Path filters as needed.
You can iterate in the branch before a PR, but choosing the run pipeline > select the branch
At Some Point Create a .nuspec file
Setup the Artifact Feed permissions for Feed Publisher (Contributor) to publish a Nuget Package. Also see . I had to read both of these and with trial and error finally got it working
Then setup branch policies to protect your main branch and require the pipeline to build and test your code before completing. Use the IsMain variable as a condition to only publish when merged into main.
# Version is set via byBuildNumber, set tne name in the yml to to 1.0.$(rev:.r), then use versioningScheme: byBuildNumber
# reference" https://stackoverflow.com/a/57553743/54288, https://learn.microsoft.com/en-us/azure/devops/pipelines/artifacts/nuget?view=azure-devops&tabs=yaml#package-versioning
name: 1.0.$(rev:r)
trigger:
- main
pool:
# I wanted to use ubuntu-latest, but couldn't get the nuget push permissions to work
vmImage: windows-latest
variables:
Name: YourNugetProject.csproj
Project: "folder/YourNugetProject.csproj"
#'https://pkgs.dev.azure.com/YourOrg/YourRepo/_packaging/YourFeed/nuget/v3/index.json'
# GUIDs copied from pipeline editor > add task > Nuget Command output
# using the url I got a "##[warning]Could not create provenance session: %s
##[warning]{"$id":"1","innerException":null,"message":"A potentially dangerous Request.Path value was detected from the client (:).","typeName":"System.Web.HttpException, System.Web","typeKey":"HttpException","errorCode":0,"eventId":0}"
PublishVstsFeed: "Guid1/Guid2"
# set in the UI Variables: BuildConfiguration: 'Release'
IsMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')]
stages:
- stage: BuildStage
jobs:
- job: Build
steps:
- task: UseDotNet@2
displayName: "Use .NET Core sdk"
inputs:
packageType: sdk
version: 8.x
performMultiLevelLookup: true
- task: DotNetCoreCLI@2
displayName: "NuGet Restore"
inputs:
command: restore
projects: "${{ variables.Project }}"
- task: DotNetCoreCLI@2
displayName: Build
inputs:
command: build
projects: "${{ variables.Project }}"
arguments: "--configuration $(BuildConfiguration)"
# https://learn.microsoft.com/en-us/azure/devops/pipelines/ecosystems/dotnet-core?view=azure-devops&tabs=yaml-editor#collect-code-coverage-metrics-with-coverlet
- task: DotNetCoreCLI@2
displayName: 'dotnet test'
inputs:
command: 'test'
projects: '**/*Tests/*.csproj'
arguments: '--configuration $(BuildConfiguration) --collect:"XPlat Code Coverage" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura'
publishTestResults: true
- task: PublishCodeCoverageResults@2
displayName: 'Publish code coverage report'
inputs:
codeCoverageTool: 'Cobertura'
summaryFileLocation: '$(Agent.TempDirectory)/**/coverage.cobertura.xml'
# versioned based on the name: set above
- task: DotNetCoreCLI@2
displayName: "Create .Net NuGet Package"
inputs:
command: pack
packagesToPack: "${{ variables.Project }}"
packDirectory: "$(Build.ArtifactStagingDirectory)/packages"
arguments: "--configuration $(BuildConfiguration)"
nobuild: true
versioningScheme: byBuildNumber
- job: Publish
dependsOn: Build
condition: eq(variables.IsMain, true)
steps:
# https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/nuget-command-v2?view=azure-pipelines
- checkout: none
- task: DownloadBuildArtifacts@0
displayName: 'Download Build Artifacts'
inputs:
artifactName: Package
downloadPath: $(Pipeline.Workspace)
- task: NuGetToolInstaller@1
displayName: 'NuGet Tool Installer'
# NuGetCommand@2 fails with [error]The task has failed because you are using Ubuntu 24.04 or later without mono installed. See https://aka.ms/nuget-task-mono for more information. So I followed https://learn.microsoft.com/en-us/azure/devops/pipelines/artifacts/nuget?view=azure-devops&tabs=yaml#publish-nuget-packages-to-a-feed-in-the-same-organization
## https://stackoverflow.com/questions/79572994/azuredevops-nugetcommand2-push-to-dotnetcorecli2-custom-nuget-push-with-vsts
# we could have used NuGetCommand@2 if using the windows-latest image
- task: NuGetAuthenticate@1
displayName: "NuGet Authenticate"
### if you got permission denied, see the note from https://learn.microsoft.com/en-us/azure/devops/pipelines/artifacts/nuget?view=azure-devops&tabs=yaml#publish-nuget-packages-to-a-feed-in-the-same-organization
### "To publish your packages to a feed using Azure Pipelines, make sure that both the Project Collection Build Service and your project's Build Service identities are granted the Feed Publisher (Contributor) role assigned in your feed settings."
### You can find the name by looking at the output from the Nuget Authenticate step above
# For ubuntu-latest, but I couldn't get beyond "Permission Denied"
# did I use nuget.exe incorrectly?
# - script: |
# nuget.exe push -Source ${{ variables.PublishVstsFeed }} -ApiKey az $(Build.ArtifactStagingDirectory)\packages\${{ variables.Name }}.$(Build.BuildNumber)*.nupkg
# displayName: 'Push Nuget Package'
# for Windows-latest
- task: NuGetCommand@2
inputs:
command: 'push'
packagesToPush: "$(Pipeline.Workspace)/Package/packages/*.nupkg"
nuGetFeedType: 'internal'
publishVstsFeed: ${{ variables.PublishVstsFeed }}
Please consider using Brave and adding me to your BAT payment ledger. Then you won't have to see ads! (when I get to $100 in Google Ads for a payout (I'm at $97.66!), I pledge to turn off ads)
Also check out my Resources Page for referrals that would help me.