Skip to main content

使用 NuGet 注册表

可以将 dotnet 命令行接口 (CLI) 配置为将 NuGet 包上传到 GitHub Packages,并使用存储在 GitHub Packages 上的包作为用于 .NET 项目的依赖项。

谁可以使用此功能?

Enterprise Managed Users 可以发布到组织的命名空间。 这些用户无法将包发布到其帐户的命名空间中,因为没有个人存储分配。 有关 Enterprise Managed Users 的其他信息,请参阅 关于 Enterprise Managed Users

NuGet 注册表的 URL

如果在 GitHub.com 访问 GitHub,则会将包发布到 https://nuget.pkg.github.com。 本文中的示例使用此 URL。

如果在另一个域中访问 GitHub(如 octocorp.ghe.com),请将“https://nuget.pkg.github.com”替换为 https://nuget.SUBDOMAIN.ghe.com,其中 SUBDOMAIN 是您的企业唯一的子域名。

向 GitHub Packages 进行认证

注意

GitHub Packages 仅支持使用 personal access token (classic) 进行身份验证。 有关详细信息,请参阅“管理个人访问令牌”。

需要访问令牌才能发布、安装和删除专用、内部和公共包。

你可以使用 personal access token (classic) 向 GitHub Packages 或 GitHub API 进行身份验证。 创建 personal access token (classic) 时,可根据需要为令牌分配不同的作用域。 有关 personal access token (classic) 的包相关作用域的详细信息,请参阅 关于 GitHub Packages 的权限

要在 GitHub Actions 工作流程内向 GitHub Packages 注册表验证,您可以使用:

  • GITHUB_TOKEN 发布与工作流存储库相关联的包。
  • 范围至少为 read:packages 的 personal access token (classic),用于安装与其他专用存储库关联的包(如果向存储库授予对包的读取访问权限,可以使用 GITHUB_TOKEN。 请参阅 配置包的访问控制和可见性)。

在 GitHub Actions 工作流中进行身份验证

此注册表支持精细权限。 对于支持精细权限的注册表,如果 GitHub Actions 工作流使用 personal access token 向注册表进行身份验证,则强烈建议更新工作流以使用 GITHUB_TOKEN。 有关如何更新通过 personal access token 向注册表进行身份验证的工作流的指南,请参阅 使用 GitHub Actions 发布和安装包

注意

GitHub Actions 工作流使用 REST API 删除和还原包的功能目前为 公共预览版,可能随时更改。

如果令牌具有对包的 admin 权限,可以在 GitHub Actions 工作流中使用 GITHUB_TOKEN,通过 REST API 来删除或还原包。 使用工作流发布包的存储库,以及已经显式连接到包的存储库,会自动获得对存储库中包的 admin 权限。

有关 GITHUB_TOKEN 的详细信息,请参阅 在工作流中使用 GITHUB_TOKEN 进行身份验证。 有关在操作中使用注册表时的最佳做法的详细信息,请参阅 安全使用指南

在 GitHub Actions 工作流中通过以下命令使用 GITHUB_TOKEN 向 GitHub Packages 进行身份验证,而不是对存储库的 nuget.config 文件中的 personal access token 进行硬编码:

dotnet nuget add source --username USERNAME --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/NAMESPACE/index.json"

NAMESPACE 替换为作为包限定范围的个人帐户或组织的名称。

USERNAME 替换为连接到已经过身份验证的源时要使用的用户名。

还可以选择为 GitHub Codespaces 和 GitHub Actions 单独授予对包的访问权限。 有关详细信息,请参阅 配置包的访问控制和可见性配置包的访问控制和可见性

使用 personal access token 进行身份验证

注意

GitHub Packages 仅支持使用 personal access token (classic) 进行身份验证。 有关详细信息,请参阅“管理个人访问令牌”。

需要访问令牌才能发布、安装和删除专用、内部和公共包。

你可以使用 personal access token (classic) 向 GitHub Packages 或 GitHub API 进行身份验证。 创建 personal access token (classic) 时,可根据需要为令牌分配不同的作用域。 有关 personal access token (classic) 的包相关作用域的详细信息,请参阅 关于 GitHub Packages 的权限

要在 GitHub Actions 工作流程内向 GitHub Packages 注册表验证,您可以使用:

  • GITHUB_TOKEN 发布与工作流存储库相关联的包。
  • 范围至少为 read:packages 的 personal access token (classic),用于安装与其他专用存储库关联的包(如果向存储库授予对包的读取访问权限,可以使用 GITHUB_TOKEN。 请参阅 配置包的访问控制和可见性)。

必须使用具有适当范围的 personal access token (classic) 才可在 GitHub Packages 中发布和安装包。 有关详细信息,请参阅“GitHub Packages 简介”。

若要使用dotnet 向 GitHub Packages 进行身份验证,请在项目目录中创建一个 nuget.config 文件,指定 GitHub Packages 作为 packageSources CLI 客户端的源。

您必须替换:

  •           将 `USERNAME` 替换为 GitHub 上的个人帐户的名称。
    
  •           将 `TOKEN` 替换为 personal access token (classic)。
    
  •           将 `NAMESPACE` 替换为作为包限定范围的个人帐户或组织的名称。
    
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
        <clear />
        <add key="github" value="https://nuget.pkg.github.com/NAMESPACE/index.json" />
    </packageSources>
    <packageSourceCredentials>
        <github>
            <add key="Username" value="USERNAME" />
            <add key="ClearTextPassword" value="TOKEN" />
        </github>
    </packageSourceCredentials>
</configuration>

发布软件包

注意

NuGet 包版本的 nupkg 存档大小必须小于 2.147 GB。

可以通过使用 nuget.config 文件进行身份验证、使用带有 GitHub personal access token (classic) 的 --api-key 命令行选项,或使用可通过 dotnet 命令行界面(CLI)直接在命令行运行的命令,将包发布到 GitHub Packages。

OWNER 替换为你的用户名或公司名称,并将 YOUR_GITHUB_PAT 替换为 personal access token。

dotnet nuget add source --username OWNER --password YOUR_GITHUB_PAT --store-password-in-clear-text --name github "https://nuget.pkg.github.com/OWNER/index.json"

NuGet 注册表将包存储在组织或个人帐户中,并支持将包与存储库关联。 可以选择是从存储库继承权限,还是独立于存储库设置精细权限。

首次发布包时,默认可见性是私有的。 若要更改可见性或设置访问权限,请参阅 配置包的访问控制和可见性。 有关将已发布的包与存储库链接的详细信息,请参阅 将仓库连接到包

如果在project的 RepositoryURL 文件中指定 __,则已发布的包将自动连接到指定的存储库。 有关详细信息,请参阅 使用 NuGet 注册表。 有关将已发布的包链接到存储库的信息,请参阅 将仓库连接到包

使用 GitHub personal access token 作为 API 密钥发布包

如果尚未为 GitHub 帐户创建可用的 personal access token,请参阅 管理个人访问令牌

  1. 创建一个新的项目。 将 PROJECT_NAME 替换为您想要为项目命名的名称。

    dotnet new console --name PROJECT_NAME
    
  2. 打包项目。

    dotnet pack --configuration Release
    
  3. 使用 personal access token 作为 API 密钥发布包。 将 PROJECT_NAME 替换为项目名称,将 1.0.0 替换为包的版本号,并将 YOUR_GITHUB_PAT 替换为 personal access token。

    dotnet nuget push "bin/Release/PROJECT_NAME.1.0.0.nupkg" --api-key YOUR_GITHUB_PAT --source "github"
    

在发布包后,您可以在 GitHub 上查看该包。 有关详细信息,请参阅“查看包”。

使用 nuget.config 文件发布包

发布时,如果你要将包链接到存储库,.csproj 文件中指定的存储库的 OWNER 必须与 nuget.config 身份验证文件中使用的 __ 匹配 。 在 .csproj 文件中指定或递增版本号,然后使用 __ 命令创建该版本的 .nuspec 文件 。 有关创建包的详细信息,请参阅 Microsoft 文档中的创建和发布包

注意

如果发布链接到存储库的包,该包会自动继承链接存储库的访问权限,链接存储库中的 GitHub Actions 工作流会自动获得对包的访问权限,除非你的组织已禁用访问权限的自动继承。 有关详细信息,请参阅“配置包的访问控制和可见性”。

  1. 向 GitHub Packages 验证。 有关详细信息,请参阅向 GitHub Packages 进行身份验证

  2. 创建一个新的项目。 将 PROJECT_NAME 替换为要给项目命名的名称。

    dotnet new console --name PROJECT_NAME
    
  3. 将项目的特定信息添加到项目的文件,该文件以 _.csproj_结尾。 请务必将

    • 1.0.0 替换为包的版本号。
    •           将 `OWNER` 替换为拥有你要向其链接包的存储库的个人帐户或组织的名称。
      
    •           将 `REPOSITORY` 替换为要将包连接到的存储库的名称。
      
    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp3.0</TargetFramework>
        <PackageId>PROJECT_NAME</PackageId>
        <Version>1.0.0</Version>
        <Authors>AUTHORS</Authors>
        <Company>COMPANY_NAME</Company>
        <PackageDescription>PACKAGE_DESCRIPTION</PackageDescription>
        <RepositoryUrl>https://github.com/OWNER/REPOSITORY</RepositoryUrl>
      </PropertyGroup>
    
    </Project>
    
  4. 打包项目。

    dotnet pack --configuration Release
    
  5. 请使用在 key 文件中指定的 __ 来发布软件包。 将 PROJECT_NAME 替换为project的名称,并将 1.0.0 替换为包的版本号。

    dotnet nuget push "bin/Release/PROJECT_NAME.1.0.0.nupkg" --source "github"
    

在发布包后,您可以在 GitHub 上查看该包。 有关详细信息,请参阅“查看包”。

将多个包发布到同一个仓库

若要将多个包连接到同一存储库,请在所有 RepositoryURL 项目文件的 __ 字段中使用相同的 GitHub 存储库 URL。 GitHub 根据该字段匹配仓库。

以下示例将项目 MY_APP 和 MY_OTHER_APP 发布到同一存储库 :

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <PackageId>MY_APP</PackageId>
    <Version>1.0.0</Version>
    <Authors>Octocat</Authors>
    <Company>GitHub</Company>
    <PackageDescription>This package adds a singing Octocat!</PackageDescription>
    <RepositoryUrl>https://github.com/my-org/my-repo</RepositoryUrl>
  </PropertyGroup>

</Project>
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <PackageId>MY_OTHER_APP</PackageId>
    <Version>1.0.0</Version>
    <Authors>Octocat</Authors>
    <Company>GitHub</Company>
    <PackageDescription>This package adds a dancing Octocat!</PackageDescription>
    <RepositoryUrl>https://github.com/my-org/my-repo</RepositoryUrl>
  </PropertyGroup>

</Project>

安装软件包

在项目中使用来自 GitHub 的包类似于使用来自 nuget.org 的包。将包依赖项添加到 .csproj 文件,并指定包名称和版本 。 有关在 project 中使用 .csproj 文件的详细信息,请参阅 Microsoft 文档中的 使用 NuGet 包

  1. 向 GitHub Packages 验证。 有关详细信息,请参阅向 GitHub Packages 进行身份验证

  2. 若要使用包,请在 ItemGroup project 文件中添加 PackageReference 并配置 __ 字段。 将 PACKAGE_NAME 中的 Include="PACKAGE_NAME" 值替换为包依赖项,并将 X.X.X 中的 Version="X.X.X" 值替换为要使用的包的版本:

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp3.0</TargetFramework>
        <PackageId>My-app</PackageId>
        <Version>1.0.0</Version>
       <Authors>Octocat</Authors>
        <Company>GitHub</Company>
       <PackageDescription>This package adds an Octocat!</PackageDescription>
        <RepositoryUrl>https://github.com/OWNER/REPOSITORY</RepositoryUrl>
      </PropertyGroup>
    
      <ItemGroup>
        <PackageReference Include="PACKAGE_NAME" Version="X.X.X" />
      </ItemGroup>
    
    </Project>
    
  3. 使用 restore 命令安装包。

    dotnet restore
    

故障排除

如果使用 GITHUB_TOKEN 对 GitHub Actions 工作流内的 GitHub Packages 注册表进行身份验证,则令牌无法在工作流运行范围以外的其他存储库中访问基于专用存储库的包。 若要access与其他存储库关联的包,请改为使用 read:packages 范围生成 personal access token (classic) 并将此令牌作为机密传入。

还原公共包时出现间歇性 403 错误

如果在项目中同时使用 GitHub Packages 和 nuget.org,并在还原标准公共包(例如 Microsoft.Extensions.*)时遇到间歇性的 403 Forbidden 错误,这可能是因为 NuGet 会针对每个包查询所有已配置的包源。 如果 GitHub Packages 身份验证暂时失败,即使是不存在于 GitHub Packages 上的包,也可能导致整个还原过程被阻止。

若要避免这种情况,请使用 NuGet 包源映射 将包路由到特定源。

替换为:

  •           `NAMESPACE` 带有 GitHub Packages NuGet 源的个人帐户或组织名称。
    
  •           `PACKAGE-ID-PREFIX` 带有在 GitHub Packages 上托管包时使用的 NuGet 包 ID 前缀。 如果使用多个前缀,请为每个前缀添加其他 `<package>` 条目。
    
<configuration>
    <packageSources>
        <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
        <add key="github" value="https://nuget.pkg.github.com/NAMESPACE/index.json" />
    </packageSources>
    <packageSourceMapping>
        <packageSource key="nuget.org">
            <package pattern="*" />
        </packageSource>
        <packageSource key="github">
            <package pattern="PACKAGE-ID-PREFIX.*" />
        </packageSource>
    </packageSourceMapping>
</configuration>

NuGet 使用 最具体的匹配模式,因此匹配的包仅从 GitHub Packages 提取,而所有其他包则从 PACKAGE-ID-PREFIX.* 提取。这也有助于防止依赖项混淆攻击,确保您的专用包只能来自 GitHub Packages 源。

其他阅读材料

  •         [AUTOTITLE](/packages/learn-github-packages/deleting-and-restoring-a-package)