Skip to main content

使用 NuGet 注册表

可以将dotnet命令行界面 (CLI) 配置为将 NuGet 包发布到GitHub Packages,并在 .NET 项目中使用存储在GitHub Packages上的包作为依赖项。

注意

这种包类型可能不适用于你的实例,因为站点管理员可以启用或禁用每种支持的包类型。 有关详细信息,请参阅“为企业配置包生态系统支持”。

正在对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 Packages 工作流程内向 GitHub Actions 注册表验证,您可以使用:

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

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

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

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

NAMESPACE 替换为个人账户或组织 ,且其拥有托管这些包的仓库。

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

有关 GitHub Actions 工作流中使用的 GITHUB_TOKEN 的详细信息,请参阅 在工作流中使用 GITHUB_TOKEN 进行身份验证

使用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 Packages 工作流程内向 GitHub Actions 注册表验证,您可以使用:

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

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

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

您必须替换:

  • USERNAME 使用您在 GitHub 上的个人账户名称。
  • TOKEN 使用你的 personal access token (classic)。
  • NAMESPACE包含包所属拥有托管包的存储库。
  • HOSTNAME,用于 你的 GitHub Enterprise Server 实例 的主机名。

如果实例启用了子域隔离:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
        <clear />
        <add key="github" value="https://nuget.HOSTNAME/NAMESPACE/index.json" />
    </packageSources>
    <packageSourceCredentials>
        <github>
            <add key="Username" value="USERNAME" />
            <add key="ClearTextPassword" value="TOKEN" />
        </github>
    </packageSourceCredentials>
</configuration>

如果实例禁用了子域隔离:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
        <clear />
        <add key="github" value="https://HOSTNAME/_registry/nuget/NAMESPACE/index.json" />
    </packageSources>
    <packageSourceCredentials>
        <github>
            <add key="Username" value="USERNAME" />
            <add key="ClearTextPassword" value="TOKEN" />
        </github>
    </packageSourceCredentials>
</configuration>

发布软件包

您可以通过使用 nuget.config 文件进行身份验证,将包发布到 GitHub Packages;也可以将 --api-key 命令行选项与您的 GitHubpersonal access token (classic) 配合使用;或者使用可通过 dotnet 命令行界面(CLI)直接从命令行运行的命令。

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.HOSTNAME/OWNER/index.json"

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

如果您还没有可用于您在 personal access token 上的帐户的 GitHub,请参阅 管理个人访问令牌

  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 文件发布包

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

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

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

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

    • 1.0.0 替换为包的版本号。
    • OWNER填写拥有您要将包发布到该存储库的个人帐户或组织的名称。
    • REPOSITORY 包含要连接到包的存储库的名称。
    • HOSTNAME,其主机名为 你的 GitHub Enterprise Server 实例。
    <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://HOSTNAME/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 上查看该包。 有关详细信息,请参阅“查看包”。

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

若要将多个包连接到同一存储库,请在所有 .csproj 项目文件的 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://HOSTNAME/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://HOSTNAME/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://HOSTNAME/OWNER/REPOSITORY</RepositoryUrl>
      </PropertyGroup>
    
      <ItemGroup>
        <PackageReference Include="PACKAGE_NAME" Version="X.X.X" />
      </ItemGroup>
    
    </Project>
    
  3. 使用 restore 命令安装包。

    dotnet restore
    

故障排除

如果未将 RepositoryUrl 中的 NuGet 包设置为预期的存储库,__ 则 NuGet 包可能无法推送。

如果你使用的是 nuspec 文件,请确保其中包含带有所需 typeurl 属性的 repository 元素。

如果您在 GitHub Packages 工作流中使用 GITHUB_TOKEN 对 GitHub Actions 注册表进行身份验证,则该令牌无法访问运行该工作流的仓库之外的其他仓库中的私有仓库包。 若要访问与其他仓库关联的软件包,请改为生成一个具有 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> 条目。
  • HOSTNAME,使用 你的 GitHub Enterprise Server 实例 的主机名。

如果实例启用了子域隔离:

<configuration>
    <packageSources>
        <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
        <add key="github" value="https://nuget.HOSTNAME/NAMESPACE/index.json" />
    </packageSources>
    <packageSourceMapping>
        <packageSource key="nuget.org">
            <package pattern="*" />
        </packageSource>
        <packageSource key="github">
            <package pattern="PACKAGE-ID-PREFIX.*" />
        </packageSource>
    </packageSourceMapping>
</configuration>

如果实例禁用了子域隔离:

<configuration>
    <packageSources>
        <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
        <add key="github" value="https://HOSTNAME/_registry/nuget/NAMESPACE/index.json" />
    </packageSources>
    <packageSourceMapping>
        <packageSource key="nuget.org">
            <package pattern="*" />
        </packageSource>
        <packageSource key="github">
            <package pattern="PACKAGE-ID-PREFIX.*" />
        </packageSource>
    </packageSourceMapping>
</configuration>

NuGet 使用 最具体匹配模式,因此匹配 PACKAGE-ID-PREFIX.* 的包只会从 GitHub Packages 获取,而所有其他包则从 nuget.org 获取。这还有助于防止依赖项混淆攻击,因为它能确保你的专用程序包只能来自你的 GitHub Packages 源。

其他阅读材料