快速自动发布Nuget包的项目

快速自动发布Nuget包的项目

目的

  1. 在构建.net 应用中,Nuget包已经成了我们日常开发的必不可少的部分,很多基础团队可能维护着大量的基础功能包,那么这些包如何才能实现快速的自动化打包呢?
  2. 打包秘钥由于安全原因,公司只允许部分管理员才有打包上传权限。
实现流程图
graph LR 开始-->获取当前项目的版本-->获取Negut服务器版本 获取Negut服务器版本-->本地版本是否大于服务器版本 本地版本是否大于服务器版本 --Y--> 更新服务器Nuget包到最新-->结束 本地版本是否大于服务器版本 --N--> 结束

具体实现步骤

添加Nuget 包引用

  1. Buildalyzer 解析解决方案

  2. HtmlAgilityPack 解析服务器版本

  3. McMaster.Extensions.CommandLineUtils 绑定命令行参数

  4. 下面代码中的nuget地址请自行更换成私有项目

    代码

    可以根据自己需求进行调整修改,如果包在nuget中没任何版本则不会自动创建,可以根据需要调整。

`

  class Program
    {
        [Option(ShortName = "key")]
        public string ApiKey { get; set; }

        [Option(ShortName = "path")]
        public string SolutionPath { get; set; }

        static int Main(string[] args) => CommandLineApplication.Execute<Program>(args);

        public void OnExecute()
        {
            var projects = new AnalyzerManager(SolutionPath)
                .Projects
                .Select(x => new { Id = Path.GetFileNameWithoutExtension(x.Key), ProjectFile = x.Key })
                .ToList();

            var htmlWeb = new HtmlWeb();
            foreach (var project in projects)
            {
                try
                {
                    var projectXml = XDocument.Load(project.ProjectFile);
                    string codeVersion = projectXml.XPathSelectElement(@"Project/PropertyGroup/Version")?.Value;
                    if (!string.IsNullOrWhiteSpace(codeVersion))
                    {
                        var htmlDocument = htmlWeb.Load($"https://www.nuget.org//packages/{project.Id}/");
                        var versionNode = htmlDocument.DocumentNode.SelectNodes("/html/body/div[1]/section/div/article/div[3]/table/tbody[1]/tr[1]/td[2]/a");
                        if (versionNode != null && versionNode.FirstOrDefault() != null)
                        {
                            var serverVersion = versionNode.FirstOrDefault().Attributes.FirstOrDefault(item => item.Name == "title").Value;
                            if (codeVersion != serverVersion)
                            {
                                Console.WriteLine($"Project: { project.Id }  serverVersion:{ serverVersion} codeVersion { codeVersion }");
                                UpdatePackage(project.Id, project.ProjectFile, codeVersion, ApiKey);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }
        }

        void UpdatePackage(string packageId, string projectFile, string codeVersion, string apiKey)
        {
            string outputDir = Path.Combine(Path.GetDirectoryName(projectFile), "bin", "Release");
            string packageCmd = $"pack {projectFile} --include-symbols --output {outputDir}";
            RunCmd(packageCmd);
            string nugetFile = Path.Combine(outputDir, $"{packageId}.{codeVersion}.symbols.nupkg");
            string uploadCmd = $"nuget push {nugetFile} -k {apiKey} --skip-duplicate -s https://www.nuget.org/";
            RunCmd(uploadCmd);
        }

        private void RunCmd(string cmd)
        {
            var processStartInfo = new ProcessStartInfo("dotnet", cmd) { RedirectStandardOutput = true };

            var process = Process.Start(processStartInfo);
            if (process == null)
            {
                Console.WriteLine("Can not exec.");
            }
            else
            {
                Console.WriteLine("-------------Start read standard output--------------");
                using (var sr = process.StandardOutput)
                {
                    while (!sr.EndOfStream)
                    {
                        Console.WriteLine(sr.ReadLine());
                    }

                    if (!process.HasExited)
                    {
                        process.Kill();
                    }
                }
                Console.WriteLine("---------------Read end------------------");
            }
        }
    }

`

可以将以上代码加入项目中,如AutoPublishNugetPackage,编译后将可以用如下命令执行

自动发布集成Jenkins

  1. 需要提前在Jenkins执行服务器上安装nuget cli,安装方法参考如下链接 https://docs.microsoft.com/zh-cn/nuget/reference/nuget-exe-cli-reference

  2. 命令代码

`

AutoPublishNugetPackage -path XXX.sln -key $nugetapikey

`

  1. 命令可以加入jenkins命令(或其他位置定期执行或建立git hooks),从而实现自动发布的效果,$nugetapikey 为私密文件,使用构建参数如下图所示

posted @ 2021-09-24 16:49  mars.yu  阅读(154)  评论(0)    收藏  举报