首页 > 其他 > 详细

记录使用 Cake 进行构建并制作 nuget 包

时间:2019-03-30 10:44:21      阅读:142      评论:0      收藏:0      [点我收藏+]

书接上一回(https://www.cnblogs.com/h82258652/p/4898983.html)?[手动狗头]

前段时间折腾了一下,总算是把我自己的图片缓存控件(https://github.com/h82258652/HN.Controls.ImageEx)发布到了 nuget 上,目前已经进入一个比较稳定的版本了,基本没有很严重的 bug 了。其实核心代码早就写完了,后期主要都在折腾持续集成以及自动构建(包含制作 nuget 包)。持续集成使用了 appveyor,园子里也有不少相关的资料,这里我就不说了。

在制作 nuget 包的过程中,我折腾了很久,最开始打算直接用 appveyor 的自动打包功能,但是在打包 UWP 的包时,打包出来的版本号一直都是 1.0.0,而 WPF 的就没这问题(这个已确认是 appveyor 的 bug,然而好久都还没有修复(lll¬ω¬))。另外包里的 dll 的版本号也不好统一控制,我发一次版本需要发 3 个 nuget 包,每个 nuget 包都有一个 dll,手动折腾版本号那不切实际的。

在经过一番调研之后,我终于发现了一个能满足我需求的工具,Cake,也叫 C# Make,是一个专门用来进行 .net 项目构建的工具。官方网站在此:https://cakebuild.net/

接下来就按着教程开始吧。

技术分享图片

这个是我项目的根目录。接下来我们在此目录运行 Powershell(可以通过左上角的文件 –> 打开 Windows Powershell 来打开)。然后输入以下命令。

Invoke-WebRequest https://cakebuild.net/download/bootstrapper/windows -OutFile build.ps1

然后敲下回车,稍微等待之后,我们的目录下就会出现一个叫 build.ps1 的文件。

技术分享图片

接下来我们在该目录创建一个叫 build.cake 的空白文件,这个文件主要就是执行构建的逻辑。

然后在宇宙最强的 IDE,Visual Studio 中进行编写脚本吧,在这里,建议各位看官先安装一个插件:

技术分享图片

安装之后,Visual Studio 就具备对 .cake 脚本的语法高亮能力(可惜还是没法有语法提示功能/(ㄒoㄒ)/~~)。

使用 Visual Studio 打开 build.cake 之后,先编写个 Hello world 热热身:

var target = Argument("target", "Default");

Task("Default")
  .Does(() =>
{
  Information("Hello World!");
});

RunTarget(target);

然后保存并运行刚才的 build.ps1。(Powershell 里输入 .\build.ps1

如果运气好的话,那么你应该和我一样碰到了这样的情况:

技术分享图片

这是由于执行 Powershell 脚本是一直比较危险的操作,所以需要更改权限。

输入如下的脚本:

技术分享图片

或者可以参考微软的官方文档来修改权限:https://docs.microsoft.com/zh-cn/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-6

接着再次执行脚本,应该就可以看见如下信息。

技术分享图片

我们的 Hello world 终于跑起来了,热身完毕,接下来开始编写构建脚本。

Cake 脚本是由一个个 Task 串联起来的,我们先定义一些变量和一个叫 Build 的 Task,用于执行构建。

var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release");
var verbosity = Argument("verbosity", Verbosity.Minimal);

var solution = "./HN.Controls.ImageEx.sln";

Task("Build")
    .Does(() =>
{
    if(IsRunningOnWindows())
    {
        // Use MSBuild
        MSBuild(solution, configurator =>
            configurator.SetConfiguration(configuration)
                .SetVerbosity(verbosity));
    }
    else
    {
        // Use XBuild
        XBuild(solution, configurator =>
            configurator.SetConfiguration(configuration)
                .SetVerbosity(verbosity));
    }
});


Task("Default")
    .IsDependentOn("Build");

RunTarget(target);

这里定义了一些变量,configuration 定义为 Release,在 Build Task 里用到,设置为使用 Release 模式。verbosity 表示编译时的信息输入,这里设置为 Minimal,以免输出过多的信息。solution 表示解决方案的路径。然后运行:

技术分享图片

这样一执行就把这个解决方案构建了一遍。

然后我们开始编写打包的 Task,命名为 Package。修改脚本如下:

var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release");
var verbosity = Argument("verbosity", Verbosity.Minimal);
var version = Argument("version", "1.0.0");

var solution = "./HN.Controls.ImageEx.sln";

Task("Build")
    .Does(() =>
{
    if(IsRunningOnWindows())
    {
        // Use MSBuild
        MSBuild(solution, configurator =>
            configurator.SetConfiguration(configuration)
                .SetVerbosity(verbosity));
    }
    else
    {
        // Use XBuild
        XBuild(solution, configurator =>
            configurator.SetConfiguration(configuration)
                .SetVerbosity(verbosity));
    }
});

Task("Package")
    .IsDependentOn("Build")
    .Does(() =>
{
    var nuGetPackSettings = new NuGetPackSettings
    {
        Version = version
    };

    var nuspecFiles = GetFiles("./src/*/*.nuspec");
    NuGetPack(nuspecFiles, nuGetPackSettings);
});

Task("Default")
    .IsDependentOn("Package");

RunTarget(target);

在这里我加了一个 version 的变量,在下面打包 nuget 包的时候会用到,统一每个 nuget 包的版本号。GetFiles("./src/*/*.nuspec") 这个则获取了源文件夹下面的项目下的 nuspec 文件(我这里一个 nuspec 对应一个 csproj,就放到同一个文件夹下了),这个文件的作用是用于描述 nuget 包如何进行打包,具体可以参考本文开头指向的上一篇文章。

执行之后,我们会得到些 nuget 包(当然对于看官你们的项目需要有 nuspec 才行啦):

技术分享图片

编译、打包都说完了。最后就是版本号的问题。nuget 包的版本在上面已经解决了,现在就是 dll 的版本号比较棘手。在我这三个项目中,WPF 和 UWP 都是传统的项目,都是有一个 AssemblyInfo.cs 的文件,然后里面通过 AssemblyVersionAttribute 来设置 dll 的版本号的。但是我这个 Core 的项目是新类型的项目,并没有 AssemblyInfo.cs 文件,版本号是在 csproj 里设置的。这难道没办法了么,最后通过万能的 Google 和 StackOverflow,我还是找到了办法。编辑 csproj 文件,并添加下面一节。

技术分享图片

这样,这个项目的版本号等信息就不会从 csproj 里面读取。我们可以添加自己的 AssemblyInfo.cs 文件进行版本号管理。

现在情况就是每个项目都有自己的 AssemblyInfo.cs 了,如何统一使用一个 AssemblyInfo.cs 文件来管理这几个项目呢?还记得 Visual Studio 有一个添加引用文件的功能么?

技术分享图片

这样几个项目都通过这种方式引用同一个 AssemblyInfo.cs 文件就行了。

最后的问题就是如何将 AssemblyInfo.cs 里的版本号跟 build.cake 脚本里的版本号保持一致。在查阅 Cake 的官方文档后,我发现有一个能生成 AssemblyInfo 的功能。修改我们的 build.cake 脚本:

var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release");
var verbosity = Argument("verbosity", Verbosity.Minimal);
var version = Argument("version", "1.0.0");

var solution = "./HN.Controls.ImageEx.sln";

Task("Version")
    .Does(() =>
{
    var file = "./src/SolutionInfo.cs";
    CreateAssemblyInfo(file, new AssemblyInfoSettings
    {
        Version = version,
        FileVersion = version,
        InformationalVersion = version
    });
});

Task("Build")
    .IsDependentOn("Version")
    .Does(() =>
{
    if(IsRunningOnWindows())
    {
        // Use MSBuild
        MSBuild(solution, configurator =>
            configurator.SetConfiguration(configuration)
                .SetVerbosity(verbosity));
    }
    else
    {
        // Use XBuild
        XBuild(solution, configurator =>
            configurator.SetConfiguration(configuration)
                .SetVerbosity(verbosity));
    }
});

Task("Package")
    .IsDependentOn("Build")
    .Does(() =>
{
    var nuGetPackSettings = new NuGetPackSettings
    {
        Version = version
    };

    var nuspecFiles = GetFiles("./src/*/*.nuspec");
    NuGetPack(nuspecFiles, nuGetPackSettings);
});

Task("Default")
    .IsDependentOn("Package");

RunTarget(target);

在 Version Task 中,会生成一个 SolutionInfo.cs 的文件,也就相当于前面的 AssemblyInfo.cs。那现在所有的项目都引用这个文件来进行统一的版本管理就行了。

 

这样就已经实现了统一版本、构建、打包的一件脚本化了。后续还可以添加上构建完之后执行单元测试以及打包后自动发布到 nuget 的功能,但我自己比较习惯打包完之后本地也测试一下(毕竟 nuget 发了就不能删),所以就暂时不折腾这功能了。

博主图片缓存控件项目的 build.cake 脚本可以参考这里:https://github.com/h82258652/HN.Controls.ImageEx/blob/master/build.cake,虽然配置好了 xunit,但是没有写单元测试就是了,ε=ε=ε=┏(゜ロ゜;)┛

这篇博文主要记录操作步骤,方便以后自己(我还有个微博的库的坑想要填……)。但也希望看完这篇博文的各位,制作一个 nuget 包并不是一件难事,马上行动把珍藏都弄一份 nuget 包,让各位 .net 开发者也机会用上吧。

记录使用 Cake 进行构建并制作 nuget 包

原文:https://www.cnblogs.com/h82258652/p/10625036.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!