{"meta":{"title":"使用 NuGet 注册表","intro":"可以将dotnet命令行界面 (CLI) 配置为将 NuGet 包发布到GitHub Packages，并在 .NET 项目中使用存储在GitHub Packages上的包作为依赖项。","product":"GitHub Packages","breadcrumbs":[{"href":"/zh/packages","title":"GitHub Packages"},{"href":"/zh/packages/working-with-a-github-packages-registry","title":"使用 GitHub Packages 注册表"},{"href":"/zh/packages/working-with-a-github-packages-registry/working-with-the-nuget-registry","title":"NuGet 注册表"}],"documentType":"article"},"body":"# 使用 NuGet 注册表\n\n可以将dotnet命令行界面 (CLI) 配置为将 NuGet 包发布到GitHub Packages，并在 .NET 项目中使用存储在GitHub Packages上的包作为依赖项。\n\n<!-- 2148AF7B-5FF8-4B28-A808-D692FEE2225A -->\n\n## 正在对GitHub Packages进行身份验证\n\n> \\[!NOTE]\n> GitHub Packages 仅支持使用 personal access token (classic) 进行身份验证。 有关详细信息，请参阅“[管理个人访问令牌](/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)”。\n\n需要访问令牌才能发布、安装和删除专用、内部和公共包。\n\n你可以使用 personal access token (classic) 向 GitHub Packages 或 GitHub API 进行身份验证。 创建 personal access token (classic) 时，可根据需要为令牌分配不同的作用域。 有关 personal access token (classic) 的包相关作用域的详细信息，请参阅 [关于 GitHub Packages 的权限](/zh/packages/learn-github-packages/about-permissions-for-github-packages#about-scopes-and-permissions-for-package-registries)。\n\n要在 GitHub Packages 工作流程内向 GitHub Actions 注册表验证，您可以使用：\n\n* `GITHUB_TOKEN` 发布与工作流存储库相关联的包。\n* 范围至少为 `read:packages` 的 personal access token (classic)，用于安装与其他专用存储库关联的包（如果向存储库授予对包的读取访问权限，可以使用 `GITHUB_TOKEN`。 请参阅 [配置包的访问控制和可见性](/zh/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility)）。\n\n### 在 GitHub Actions 工作流中进行身份验证\n\n此注册表支持精细权限。\n对于支持细粒度权限的注册表，如果您的GitHub Actions工作流使用personal access token向注册表进行身份验证，我们强烈建议您更新工作流以使用`GITHUB_TOKEN`。 有关更新通过 personal access token 向注册表进行身份验证的工作流的指导，请参阅 [使用 GitHub Actions 发布和安装包](/zh/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#upgrading-a-workflow-that-accesses-a-registry-using-a-personal-access-token)。\n\n> \\[!NOTE]\n> GitHub Actions 工作流使用 REST API 删除和还原包的功能目前为 公开预览，可能随时更改。\n\n如果令牌对该包具有 `GITHUB_TOKEN` 权限，则可以在 GitHub Actions 工作流中使用 `admin` 通过 REST API 删除或恢复软件包。 通过工作流发布软件包的仓库，以及你已明确关联到软件包的仓库，会自动获得对该仓库中软件包的 `admin` 权限。\n\n有关 `GITHUB_TOKEN` 的详细信息，请参阅 [在工作流中使用 GITHUB\\_TOKEN 进行身份验证](/zh/actions/tutorials/authenticate-with-github_token#using-the-github_token-in-a-workflow)。 有关在操作中使用注册表时的最佳做法的详细信息，请参阅 [被入侵的运行器](/zh/actions/concepts/security/compromised-runners#cross-repository-access)。\n\n使用以下命令，在 GitHub Packages 工作流中使用 GitHub Actions 对 `GITHUB_TOKEN` 进行身份验证，而不是在仓库中的 nuget.config 文件里硬编码 personal access token：\n\n```shell\ndotnet nuget add source --username USERNAME --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github \"https://nuget.pkg.github.com/NAMESPACE/index.json\"\n```\n\n将 `NAMESPACE` 替换为个人账户或组织\n的名称，这些包的作用域属于该账户或组织。\n\n将 `USERNAME` 替换为连接到已经过身份验证的源时要使用的用户名。\n\n您还可以选择针对GitHub Codespaces和GitHub Actions分别为包授予访问权限。 有关详细信息，请参阅 [配置包的访问控制和可见性](/zh/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility#ensuring-github-codespaces-access-to-your-package) 和 [配置包的访问控制和可见性](/zh/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility#ensuring-workflow-access-to-your-package)。\n\n### 使用personal access token进行身份验证\n\n> \\[!NOTE]\n> GitHub Packages 仅支持使用 personal access token (classic) 进行身份验证。 有关详细信息，请参阅“[管理个人访问令牌](/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)”。\n\n需要访问令牌才能发布、安装和删除专用、内部和公共包。\n\n你可以使用 personal access token (classic) 向 GitHub Packages 或 GitHub API 进行身份验证。 创建 personal access token (classic) 时，可根据需要为令牌分配不同的作用域。 有关 personal access token (classic) 的包相关作用域的详细信息，请参阅 [关于 GitHub Packages 的权限](/zh/packages/learn-github-packages/about-permissions-for-github-packages#about-scopes-and-permissions-for-package-registries)。\n\n要在 GitHub Packages 工作流程内向 GitHub Actions 注册表验证，您可以使用：\n\n* `GITHUB_TOKEN` 发布与工作流存储库相关联的包。\n* 范围至少为 `read:packages` 的 personal access token (classic)，用于安装与其他专用存储库关联的包（如果向存储库授予对包的读取访问权限，可以使用 `GITHUB_TOKEN`。 请参阅 [配置包的访问控制和可见性](/zh/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility)）。\n\n必须使用具有适当范围的 personal access token (classic) 才可在 GitHub Packages 中发布和安装包。 有关详细信息，请参阅“[GitHub Packages 简介](/zh/packages/learn-github-packages/introduction-to-github-packages#authenticating-to-github-packages)”。\n\n若要使用 GitHub Packages 命令行界面（CLI）向 `dotnet` 进行身份验证，请在项目目录中创建一个 *nuget.config* 文件，将 GitHub Packages 指定为 `packageSources` CLI 客户端在 `dotnet` 下的一个源。\n\n您必须替换：\n\n* `USERNAME` 使用您在 GitHub 上的个人账户名称。\n* `TOKEN` 使用你的 personal access token (classic)。\n* `NAMESPACE`包含包所属存储库的个人帐户或组织的名称，这些帐户或组织的存储库。\n\n```xml\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n    <packageSources>\n        <clear />\n        <add key=\"github\" value=\"https://nuget.pkg.github.com/NAMESPACE/index.json\" />\n    </packageSources>\n    <packageSourceCredentials>\n        <github>\n            <add key=\"Username\" value=\"USERNAME\" />\n            <add key=\"ClearTextPassword\" value=\"TOKEN\" />\n        </github>\n    </packageSourceCredentials>\n</configuration>\n```\n\n## 发布软件包\n\n> \\[!NOTE]\n> NuGet 包版本的 `nupkg` 存档大小必须小于 2.147 GB。\n\n您可以通过使用 GitHub Packages 文件进行身份验证，将包发布到 \\_\\_；也可以将 `--api-key` 命令行选项与您的 GitHubpersonal access token (classic) 配合使用；或者使用可通过 `dotnet` 命令行界面（CLI）直接从命令行运行的命令。\n\n将 `OWNER` 替换为您的用户名或公司名称，并将 `YOUR_GITHUB_PAT` 替换为您的 personal access token。\n\n```shell\ndotnet nuget add source --username OWNER --password YOUR_GITHUB_PAT --store-password-in-clear-text --name github \"https://nuget.pkg.github.com/OWNER/index.json\"\n```\n\nNuGet 注册表将包存储在组织或个人帐户中，并支持将包与存储库关联。 可以选择是从存储库继承权限，还是独立于存储库设置精细权限。\n\n首次发布包时，默认可见性是私有的。 若要更改可见性或设置访问权限，请参阅 [配置包的访问控制和可见性](/zh/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility)。 有关将已发布的包与存储库链接的详细信息，请参阅 [将仓库连接到软件包](/zh/packages/learn-github-packages/connecting-a-repository-to-a-package)。\n\n如果在project的 `RepositoryURL` 文件中指定 \\_\\_，则已发布的包将自动连接到指定的存储库。 有关详细信息，请参阅 [使用 NuGet 注册表](/zh/packages/working-with-a-github-packages-registry/working-with-the-nuget-registry#publishing-a-package-using-a-nugetconfig-file)。 有关将已发布的包链接到存储库的信息，请参阅 [将仓库连接到软件包](/zh/packages/learn-github-packages/connecting-a-repository-to-a-package)。\n\n### 使用 GitHub personal access token 作为 API 密钥发布软件包\n\n如果您还没有可用于您在 personal access token 上的帐户的 GitHub，请参阅 [管理个人访问令牌](/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)。\n\n1. 创建一个新的项目。 将 `PROJECT_NAME` 替换为您想要为项目命名的名称。\n\n   ```shell\n   dotnet new console --name PROJECT_NAME\n   ```\n\n2. 打包项目。\n\n   ```shell\n   dotnet pack --configuration Release\n   ```\n\n3. 使用您的 personal access token 作为 API 密钥来发布包。 将 `PROJECT_NAME` 替换为项目名称，将 `1.0.0` 替换为包的版本号，并将 `YOUR_GITHUB_PAT` 替换为你的 personal access token。\n\n   ```shell\n   dotnet nuget push \"bin/Release/PROJECT_NAME.1.0.0.nupkg\" --api-key YOUR_GITHUB_PAT --source \"github\"\n   ```\n\n在发布包后，您可以在 GitHub 上查看该包。 有关详细信息，请参阅“[查看包](/zh/packages/learn-github-packages/viewing-packages)”。\n\n### 使用 nuget.config 文件发布包\n\n发布时，如果要将包链接到存储库， `OWNER`*则 .csproj* 文件中指定的存储库必须与`NAMESPACE` 身份验证文件中使用的存储库匹配\\_\\_。 在 .csproj 文件中指定或递增版本号，然后使用 \\_\\_ 命令创建该版本的 .nuspec 文件 。 有关创建包的详细信息，请参阅 Microsoft 文档中的[创建和发布包](https://docs.microsoft.com/nuget/quickstart/create-and-publish-a-package-using-the-dotnet-cli)。\n\n> \\[!NOTE]\n> 如果发布链接到存储库的包，该包会自动继承链接存储库的访问权限，链接存储库中的 GitHub Actions 工作流会自动获得对包的访问权限，除非你的组织已禁用访问权限的自动继承。 有关详细信息，请参阅“[配置包的访问控制和可见性](/zh/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility#about-inheritance-of-access-permissions)”。\n\n1. 向 GitHub Packages 验证。 有关详细信息，请参阅[向 GitHub Packages 进行身份验证](#authenticating-to-github-packages)。\n\n2. 创建一个新的项目。 将 `PROJECT_NAME` 替换为您想要为项目命名的名称。\n\n   ```shell\n   dotnet new console --name PROJECT_NAME\n   ```\n\n3. 将项目的特定信息添加到项目的文件，该文件以 \\_.csproj\\_结尾。 请务必将\n\n   * 将 `1.0.0` 替换为包的版本号。\n   * `OWNER`填写拥有您要将包链接到该存储库的个人帐户或组织的名称。\n   * `REPOSITORY` 包含要连接到包的存储库的名称。\n\n   ```xml\n   <Project Sdk=\"Microsoft.NET.Sdk\">\n\n     <PropertyGroup>\n       <OutputType>Exe</OutputType>\n       <TargetFramework>netcoreapp3.0</TargetFramework>\n       <PackageId>PROJECT_NAME</PackageId>\n       <Version>1.0.0</Version>\n       <Authors>AUTHORS</Authors>\n       <Company>COMPANY_NAME</Company>\n       <PackageDescription>PACKAGE_DESCRIPTION</PackageDescription>\n       <RepositoryUrl>https://github.com/OWNER/REPOSITORY</RepositoryUrl>\n     </PropertyGroup>\n\n   </Project>\n   ```\n\n4. 打包项目。\n\n   ```shell\n   dotnet pack --configuration Release\n   ```\n\n5. 请使用在 `key` 文件中指定的 \\_\\_ 来发布软件包。 将 `PROJECT_NAME` 替换为project的名称，并将 `1.0.0` 替换为包的版本号。\n\n   ```shell\n   dotnet nuget push \"bin/Release/PROJECT_NAME.1.0.0.nupkg\" --source \"github\"\n   ```\n\n在发布包后，您可以在 GitHub 上查看该包。 有关详细信息，请参阅“[查看包](/zh/packages/learn-github-packages/viewing-packages)”。\n\n## 将多个包发布到同一个仓库\n\n若要将多个包连接到同一存储库，请在所有 GitHub 项目文件的 `RepositoryURL` 字段中使用相同的 \\_\\_ 存储库 URL。\nGitHub 匹配基于该字段的存储库。\n\n以下示例将项目 MY\\_APP 和 MY\\_OTHER\\_APP 发布到同一存储库 ：\n\n```xml\n<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>netcoreapp3.0</TargetFramework>\n    <PackageId>MY_APP</PackageId>\n    <Version>1.0.0</Version>\n    <Authors>Octocat</Authors>\n    <Company>GitHub</Company>\n    <PackageDescription>This package adds a singing Octocat!</PackageDescription>\n    <RepositoryUrl>https://github.com/my-org/my-repo</RepositoryUrl>\n  </PropertyGroup>\n\n</Project>\n```\n\n```xml\n<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>netcoreapp3.0</TargetFramework>\n    <PackageId>MY_OTHER_APP</PackageId>\n    <Version>1.0.0</Version>\n    <Authors>Octocat</Authors>\n    <Company>GitHub</Company>\n    <PackageDescription>This package adds a dancing Octocat!</PackageDescription>\n    <RepositoryUrl>https://github.com/my-org/my-repo</RepositoryUrl>\n  </PropertyGroup>\n\n</Project>\n```\n\n## 安装软件包\n\n在项目中使用包 GitHub 类似于使用 \\_来自 nuget.org 的\\_包。将包依赖项添加到 *.csproj* 文件，并指定包名称和版本。 有关在 project 中使用 *.csproj* 文件的详细信息，请参阅 Microsoft 文档中的 [使用 NuGet 包](https://docs.microsoft.com/nuget/consume-packages/overview-and-workflow)。\n\n1. 向 GitHub Packages 验证。 有关详细信息，请参阅[向 GitHub Packages 进行身份验证](#authenticating-to-github-packages)。\n\n2. 若要使用包，请在 `ItemGroup` project 文件中添加 `PackageReference` 并配置 \\_\\_ 字段。 将 `PACKAGE_NAME` 中的 `Include=\"PACKAGE_NAME\"` 值替换为包依赖项，并将 `X.X.X` 中的 `Version=\"X.X.X\"` 值替换为要使用的包的版本：\n\n   ```xml\n   <Project Sdk=\"Microsoft.NET.Sdk\">\n\n     <PropertyGroup>\n       <OutputType>Exe</OutputType>\n       <TargetFramework>netcoreapp3.0</TargetFramework>\n       <PackageId>My-app</PackageId>\n       <Version>1.0.0</Version>\n      <Authors>Octocat</Authors>\n       <Company>GitHub</Company>\n      <PackageDescription>This package adds an Octocat!</PackageDescription>\n       <RepositoryUrl>https://github.com/OWNER/REPOSITORY</RepositoryUrl>\n     </PropertyGroup>\n\n     <ItemGroup>\n       <PackageReference Include=\"PACKAGE_NAME\" Version=\"X.X.X\" />\n     </ItemGroup>\n\n   </Project>\n   ```\n\n3. 使用 `restore` 命令安装包。\n\n   ```shell\n   dotnet restore\n   ```\n\n## 故障排除\n\n如果您在 `GITHUB_TOKEN` 工作流中使用 GitHub Packages 对 GitHub Actions 注册表进行身份验证，则该令牌无法访问运行该工作流的仓库之外的其他仓库中的私有仓库包。 若要访问与其他仓库关联的软件包，请改为生成一个具有 personal access token (classic) 范围的 `read:packages`，并将此令牌作为密钥传入。\n\n### 还原公共包时出现间歇性 403 错误\n\n如果你正在将 GitHub Packages 与 *nuget.org* 一起使用，并且在还原标准公共包（如 `Microsoft.Extensions.*`）时遇到间歇性的 403 Forbidden 错误，这可能是因为 NuGet 会针对每个包查询所有已配置的包源。 如果 GitHub Packages 身份验证暂时失败，则它可以阻止整个还原，即使对于不存在 GitHub Packages的包也是如此。\n\n若要避免这种情况，请使用 [NuGet 包源映射](https://learn.microsoft.com/nuget/consume-packages/package-source-mapping) 将包路由到特定源。\n\n替换为：\n\n* `NAMESPACE` 使用拥有您的 GitHub Packages NuGet 源的个人帐户或组织名称。\n* `PACKAGE-ID-PREFIX` 具有用于托管 GitHub Packages的包的 NuGet 包 ID 前缀。 如果使用多个前缀，请为每个前缀添加其他 `<package>` 条目。\n\n```xml\n<configuration>\n    <packageSources>\n        <add key=\"nuget.org\" value=\"https://api.nuget.org/v3/index.json\" />\n        <add key=\"github\" value=\"https://nuget.pkg.github.com/NAMESPACE/index.json\" />\n    </packageSources>\n    <packageSourceMapping>\n        <packageSource key=\"nuget.org\">\n            <package pattern=\"*\" />\n        </packageSource>\n        <packageSource key=\"github\">\n            <package pattern=\"PACKAGE-ID-PREFIX.*\" />\n        </packageSource>\n    </packageSourceMapping>\n</configuration>\n```\n\nNuGet 使用 [最具体匹配模式](https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#package-pattern-precedence)，因此匹配 `PACKAGE-ID-PREFIX.*` 的包只会从 GitHub Packages 获取，而所有其他包则从 *nuget.org* 获取。这还有助于防止依赖项混淆攻击，因为它能确保你的专用程序包只能来自你的 GitHub Packages 源。\n\n## 其他阅读材料\n\n* [删除和恢复包](/zh/packages/learn-github-packages/deleting-and-restoring-a-package)"}