使用 Azure Pipelines 发布 NuGet 包(YAML/经典)

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

借助 Azure Pipelines,你可使用经典或 YAML 管道将 NuGet 包发布到 Azure Artifacts 源、外部源或公共注册表(如 nuget.org)。通过本文,你将了解如何:

  • 在 Azure Pipelines 中生成 NuGet 包
  • 将包发布到内部源和外部源
  • 将包发布到 NuGet.org

先决条件

创建 NuGet 包

可通过多种方式创建 NuGet 包;例如,使用 dotnet 或 nuget.exe CLI 来打包包。 如果已在使用 MSBuild 或其他任务来创建包,则可跳过本节,然后继续执行下一节中的操作。

若要创建 NuGet 包,请将以下代码片段添加到 YAML 文件。 有关更多详细信息,请参阅 NuGet 任务

- task: NuGetCommand@2
  inputs:
    command: pack
    packagesToPack: '**/*.csproj'
    packDestination: '$(Build.ArtifactStagingDirectory)'
  • packagesToPack:任务用于搜索要打包的 csproj 目录的模式。
  • packDestination:要在其中创建包的目录。 如果为空,将在源根目录中创建包。

程序包版本控制

NuGet 包会按其名称和版本号进行定义。 建议采用语义版本控制方法来有效管理包版本。 语义版本由三个数字部分组成:主要版本、次要版本和补丁版本。

修复某一 bug 后,补丁号会递增。 发布新的向后兼容功能时,将次要版本递增,并将补丁版本重置为 0。 反之,执行向后不兼容的更改时,将主要版本递增,并将次要版本和补丁版本都重置为 0。

语义版本控制还支持使用预发行标签来标记包。 具体操作时,只需追加连字符并后跟预发行版标记,例如:1.0.0-beta

Azure Pipelines 支持语义版本控制,并为 NuGet 任务提供以下配置选项:

  • 使用日期和时间(经典)| byPrereleaseNumber (YAML):包版本采用以下格式:Major.Minor.Patch-ci-datetime;其中,你可随意自定义 Major、Minor 和 Patch 的值。

  • 使用环境变量(经典)| byEnvVar (YAML):包版本将设为指定环境变量的值。

  • 使用内部版本号(经典)| byBuildNumber (YAML):包版本将设为内部版本号。 请务必将管道选项中的内部版本号格式定义为 $(BuildDefinitionName)_$(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r)。 若要在 YAML 中设置格式,请在管道的根目录处添加 name: 属性并定义格式。

以下示例演示了如何使用日期与时间版本控制来生成符合 SemVer 且采用如下格式的包:Major.Minor.Patch-ci-datetime

variables:
  Major: '1'
  Minor: '0'
  Patch: '0'

steps:
- task: NuGetCommand@2
  inputs:
    command: pack
    versioningScheme: byPrereleaseNumber
    majorVersion: '$(Major)'
    minorVersion: '$(Minor)'
    patchVersion: '$(Patch)'

注意

DotNetCoreDotNetStandard 包应与 DotNetCoreCLI@2 任务一起打包,以避免 System.InvalidCastExceptions。 有关更多详细信息,请参阅 .NET Core CLI 任务

task: DotNetCoreCLI@2
inputs:
    command: pack
    versioningScheme: byPrereleaseNumber
    majorVersion: '$(Major)'
    minorVersion: '$(Minor)'
    patchVersion: '$(Patch)'

将包发布到内部源

注意

若要使用 Azure Pipelines 将包发布到源,请确保已为项目集合生成服务和项目的生成服务标识授予已在源设置中分配的源发布者(参与者)角色。 有关更多详细信息,请参阅管理权限

steps:
- task: NuGetAuthenticate@1
  displayName: 'NuGet Authenticate'
- task: NuGetCommand@2
  displayName: 'NuGet push'
  inputs:
    command: push
    publishVstsFeed: '<projectName>/<feed>'
    allowPackageConflicts: true

将包发布到外部源

若要将包发布到外部 NuGet 源或公共注册表(例如,其他 Azure DevOps 组织或 nuget.org 中的源),则须先创建服务连接,以便向相应的服务进行身份验证:

  1. 在 Azure DevOps 项目中,导航到项目设置>服务连接>。

  2. 选择新建服务连接>NuGet>下一步

  3. 填写必填字段,完成后选择保存。 有关更多详细信息,请参阅管理服务连接

注意

NuGetAuthenticate@1 任务支持采用基本身份验证的服务连接,但不支持 Apikey 身份验证。 若要使用 ApiKey 身份验证,则须改用 NuGetCommand@2 任务

若要将 NuGet 包发布到其他组织中的源,请将以下代码片段添加到 YAML 管道:

  • 使用命令行任务和 NuGet.exe

      - task: NuGetAuthenticate@1
        inputs:
          nuGetServiceConnections: <NAME_OF_YOUR_SERVICE_CONNECTION>
    
      - script: |
          nuget push <PACKAGE_PATH> -src https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/<PROJECT_NAME>/_packaging/<FEED_NAME>/nuget/v3/index.json -ApiKey <ANY_STRING>
        displayName: "Push"          
    
  • 使用命令行任务和 dotnet

        - task: NuGetAuthenticate@1
          inputs:
            nuGetServiceConnections: <NAME_OF_YOUR_SERVICE_CONNECTION>
    
        - script: |
            dotnet build <CSPROJ_PATH> --configuration <CONFIGURATION>
            dotnet pack <CSPROJ_PATH> -p:PackageVersion=<YOUR_PACKAGE_VERSION> --output <OUTPUT_DIRECTORY> --configuration <CONFIGURATION>
            dotnet nuget push <PACKAGE_PATH> --source https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/<PROJECT_NAME>/_packaging/<FEED_NAME>/nuget/v3/index.json --api-key <ANY_STRING>
          displayName: "Build, pack and push"          
      ```
    
    

注意

必须使用 ApiKey,但在推送到 Azure Artifacts 源时可使用任意字符串。

发布到 NuGet.org

  1. 登录 nuget.org 帐户并生成 API 密钥

  2. 导航到 Azure DevOps 项目,然后选择“齿轮图标项目设置”。

  3. 选择服务连接,然后选择新建服务连接

  4. 依次选择 NuGet下一步

  5. 选择 ApiKey 作为身份验证方法,并使用以下 URL 作为源 URLhttps://api.nuget.org/v3/index.json

  6. 输入之前生成的 ApiKey,然后提供一个服务连接名称

  7. 选择授予对所有管道的访问权限,完成后选择保存。 请注意,若要选择此选项,则需要服务连接管理员角色。

steps:
- task: NuGetCommand@2
  displayName: 'NuGet push'
  inputs:
    command: push
    nuGetFeedType: external
    publishFeedCredentials: nuget.org