NuGet 是 .NET 平台上最流行的包管理器之一。它可以帮助开发人员轻松地在项目中引用和管理第三方库。在开发过程中,我们往往会抽取基类类库打包发布到nuget平台或者我们自己搭建的托管中心,如果能实现自动化打包,并一键上传到Nuget中心,可以提高我们开发效率,本文我将介绍如何自动化打包 NuGet 并发布至NuGet 平台。最终目标:程序员开发好代码,在Visual Studio 解决方案中选择要发布的类库点击“打包”即可完成打包到发布一键完成。
步骤一:创建 .NET 类库项目
首先,在 Visual Studio 中创建一个 .NET 类库项目。可以选择 .NET Standard 或 .NET Core 版本。如我这类创建了一个:Enterprises.Framework.Core类库,我这类就简称他为企业类库。
步骤二:添加 NuGet 配置文件
在项目文件夹中创建一个名为 NuGet.config 的文件,并将以下内容复制到文件中:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<activePackageSource>
<add key="All" value="(Aggregate source)" />
</activePackageSource>
</configuration>
这个文件指定了 NuGet 包管理器的配置信息,包括默认的包源和活动的包源。
步骤三:编辑项目文件
Visual Studio中双击解决方案类库或者打开Enterprises.Framework.Core.csproj文件,并在xml中PropertyGroup中下面增加版本信息:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Description>Enterprises.Framework.Core</Description>
<Copyright>Enterprises.Framework.Core</Copyright>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
<Revision>$([System.DateTime]::get_Now().get_DayOfYear())</Revision>
<RevisionNum>$([System.DateTime]::get_Now().get_TimeOfDay().get_TotalMinutes().ToString('F0'))</RevisionNum>
<GitBranch></GitBranch>
<Version>1.0.$(Revision).$(RevisionNum)</Version>
</PropertyGroup>
</Project>
Revision:获取版本后缀,这类为了模拟直接采用当前所在年中的第几天;
RevisionNum:当前时间在所在的分钟数;
GitBranch:版本分支名称;
Version:打包的最终版本;
这类为了演示,本来版本号前缀采用GIT的分支名加后缀组合。
步骤三:关键步骤,项目文件增加Build Target
<Target Name="GetGitBranch" BeforeTargets="BeforeCompile">
<Exec Command="git rev-parse --abbrev-ref HEAD" ConsoleToMSBuild="true" StandardOutputImportance="High">
<Output TaskParameter="ConsoleOutput" PropertyName="GitBranch" />
</Exec>
<Message Text="get git Branch: $(GitBranch). Please don't package in master." Importance="high"></Message>
<PropertyGroup>
<PackageVersion>$(GitBranch.Substring(1,$([MSBuild]::Subtract($(GitBranch.Length), 3)))).$(Revision).$(RevisionNum)</PackageVersion>
<Version>$(GitBranch.Substring(1,$([MSBuild]::Subtract($(GitBranch.Length), 3)))).$(Revision).$(RevisionNum)</Version>
</PropertyGroup>
</Target>
<Target Name="PushNuGetPackage" AfterTargets="Pack" Condition=" '$(Configuration)' == 'Release'">
<Message Text="Push NuGet Package $(Version) to NuGet Feed" Importance="high"></Message>
<Exec Command="dotnet nuget push $(SolutionDir)$(Description)\bin\Release\$(Description).$(Version).nupkg --api-key 你的nuget密钥 --source https://api.nuget.org/v3/index.json"></Exec>
</Target>
<Target Name="PushNuGetPackageDebug" AfterTargets="Pack" Condition=" '$(Configuration)' == 'Debug'">
<Message Text=" ***** Need Release to Push NuGet Package ***** " Importance="high"></Message>
</Target>
其中,GetGitBranch Target 这个代码块中定义了一个名为 BeforeCompile 的 MSBuild 目标,它会在项目编译前执行命令,以获取 Git 分支名称并存储在 $(GitBranch) 变量中。然后重置$Version变量。
PushNuGetPackage Target 这块代码,主要执行dotnet nuget push $(SolutionDir)$(Description)\bin\Release\$(Description).$(Version).nupkg --api-key 密钥 --source https://api.nuget.org/v3/index.json 发布包到Nuget中。
完整项目文件代码如下:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Description>Enterprises.Framework.Core</Description>
<Copyright>Enterprises.Framework.Core</Copyright>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
<Revision>$([System.DateTime]::get_Now().get_DayOfYear())</Revision>
<RevisionNum>$([System.DateTime]::get_Now().get_TimeOfDay().get_TotalMinutes().ToString('F0'))</RevisionNum>
<GitBranch></GitBranch>
<Version>1.0.$(Revision).$(RevisionNum)</Version>
</PropertyGroup>
<Target Name="GetGitBranch" BeforeTargets="BeforeCompile">
<Exec Command="git rev-parse --abbrev-ref HEAD" ConsoleToMSBuild="true" StandardOutputImportance="High">
<Output TaskParameter="ConsoleOutput" PropertyName="GitBranch" />
</Exec>
<Message Text="get git Branch: $(GitBranch). Please don't package in master." Importance="high"></Message>
<PropertyGroup>
<PackageVersion>$(GitBranch.Substring(1,$([MSBuild]::Subtract($(GitBranch.Length), 3)))).$(Revision).$(RevisionNum)</PackageVersion>
<Version>$(GitBranch.Substring(1,$([MSBuild]::Subtract($(GitBranch.Length), 3)))).$(Revision).$(RevisionNum)</Version>
</PropertyGroup>
</Target>
<Target Name="PushNuGetPackage" AfterTargets="Pack" Condition=" '$(Configuration)' == 'Release'">
<Message Text="Push NuGet Package $(Version) to NuGet Feed" Importance="high"></Message>
<Exec Command="dotnet nuget push $(SolutionDir)$(Description)\bin\Release\$(Description).$(Version).nupkg --api-key nuget密钥 --source https://api.nuget.org/v3/index.json"></Exec>
</Target>
<Target Name="PushNuGetPackageDebug" AfterTargets="Pack" Condition=" '$(Configuration)' == 'Debug'">
<Message Text=" ***** Need Release to Push NuGet Package ***** " Importance="high"></Message>
</Target>
</Project>
最终效果右键类库,选择打包效果图
控制台成功输出打包结果
Nuget 官网验证上传对于包