基于DotNetty实现自动发布 - 实现一键打包发布

这篇具有很好参考价值的文章主要介绍了基于DotNetty实现自动发布 - 实现一键打包发布。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

上一篇,我只实现了一键检测代码变化,本篇才是真正的实现了一键打包发布

效果图

基于DotNetty实现自动发布 - 实现一键打包发布
基于DotNetty实现自动发布 - 实现一键打包发布
基于DotNetty实现自动发布 - 实现一键打包发布

客户端打包待发布文件

    /// <summary>
    /// 把多个文件添加到压缩包 (保留文件夹层级关系)
    /// </summary>
    public static async Task<ZipFileResult> CreateZipAsync(IEnumerable<ZipFileInfo> zipFileInfo)
    {
        return await Task.Run(() =>
        {
            var zipDir = EnsureZipDirCreated();
            var zipFileName = $"{DateTime.Now:yyyyMMdd_HHmmss_}{Guid.NewGuid()}.zip";
            var zipPath = Path.Combine(zipDir, zipFileName);
            using var archive = ZipFile.Open(zipPath, ZipArchiveMode.Update);
            foreach (var item in zipFileInfo)
            {
                archive.CreateEntryFromFile(item.FileAbsolutePath, item.FileRelativePath, CompressionLevel.SmallestSize);
            }
            return new ZipFileResult() { FullFileName = zipPath, FileName = zipFileName };
        });
    }

客户端封装 NettyMessage

            //读取zip字节数组,填充到 NettyMessage 的 Body
            var body = await File.ReadAllBytesAsync(zipResult.FullFileName);

            //NettyHeader
            var header = new DeployRequestHeader()
            {
                Files = PublishFiles,
                SolutionName = SolutionName,
                ProjectName = webProject!.ProjectName,
                ZipFileName = zipResult.FileName,
            };

            var nettyMessage = new NettyMessage { Header = header, Body = body };

            //创建 NettyClient
            Logger.Info("开始发送");
            using var nettyClient = new NettyClient(webProject.ServerIp, webProject.ServerPort);
            await nettyClient.SendAsync(nettyMessage);
            Logger.Info("完成发送");

            Growl.SuccessGlobal($"发布成功");

            //保存发布记录
            await solutionRepo.SaveFirstPublishAsync(SolutionId, SolutionName, lastGitCommit!.Sha);
            Growl.SuccessGlobal($"操作成功");

            quickDeployDialog?.Close();

NettyHeader 设计

具体实现是 DeployRequestHeader, 继承自 NettyHeader, 保存待发布文件集合,项目名称,解决方案名称, zip 文件名称等

/// <summary>
/// 发布请求头部
/// </summary>
public class DeployRequestHeader : NettyHeader
{
    public DeployRequestHeader() : base("Deploy/Run") { }
    public List<DeployFileInfo> Files { get; set; } = [];
    public string ProjectName { get; set; } = string.Empty;
    public string SolutionName { get; set; } = string.Empty;
    public string ZipFileName { get; set; } = string.Empty;
}

服务端处理

  • 解压 zip
  • 备份目标文件(存在才备份)
  • 替换目标文件(不存在则新建)
/// <summary>
/// 执行服务端发布
/// </summary>
/// <param name="model"></param>
public void Run(DeployRequestHeader model)
{
    Logger.Warn($"收到客户端的消息: {model.ToJsonString(true)}");

    var configs = NettyServer.AppHost.Services.GetRequiredService<IOptions<List<ProjectConfig>>>();
    var projectConfig = configs.Value.FirstOrDefault(a => a.ProjectName == model.ProjectName);
    if (projectConfig == null)
    {
        Logger.Error("请现在服务器项目的appsettings.json中配置项目信息");
        return;
    }

    var zipBytes = Request.Body;
    if (zipBytes == null || zipBytes.Length == 0)
    {
        Logger.Error("ZipBytes为空");
        return;
    }

    var zipFileName = model.ZipFileName;
    if (string.IsNullOrEmpty(zipFileName))
    {
        Logger.Error("ZipFileName为空");
        return;
    }

    //解压
    var zipDir = ZipHelper.UnZip(zipBytes, zipFileName);

    Logger.Info($"解压成功: {zipDir}");

    //备份并覆盖旧文件
    DoPublish(model.Files, zipDir, zipFileName, projectConfig);

    Logger.Info($"发布成功: {zipDir}");
}
/// <summary>
/// 备份并覆盖旧文件
/// </summary>
private static void DoPublish(List<DeployFileInfo> files, string zipDir, string zipFileName, ProjectConfig projectConfig)
{
    try
    {
        //先创建备份文件夹
        var backupDir = EnsureBackupDirCreated(zipFileName);

        //遍历每个待发布的文件,依次先备份再替换
        foreach (DeployFileInfo file in files)
        {
            //文件相对路径(相对于待发布的项目根目录,也是相对于解压后的根目录)
            var relativeFilePath = file.PublishFileRelativePath;

            //源文件路径(解压后的文件路径)
            var sourceFileName = Path.Combine(zipDir, relativeFilePath);

            //待发布的文件路径 (服务器真实文件路径)
            var destFileName = Path.Combine(projectConfig.ProjectDir, relativeFilePath);

            //服务器已存在此文件,先执行备份
            if (File.Exists(destFileName))
            {
                //备份文件路径
                var backupFileName = Path.Combine(backupDir, relativeFilePath);
                //确保创建备份文件夹
                var backupFileDir = Path.GetDirectoryName(backupFileName);
                if (!Directory.Exists(backupFileDir))
                {
                    Directory.CreateDirectory(backupFileDir!);
                }
                File.Copy(destFileName, backupFileName);
            }
            else
            {
                //服务器不存在此文件,先创建文件夹层级(比如你新加了一个页面demo.aspx,需要发布到服务器对应的位置)
                var destFileDir = Path.GetDirectoryName(destFileName);
                if (!Directory.Exists(destFileDir))
                {
                    Directory.CreateDirectory(destFileDir!);
                }
            }

            //替换服务器文件
            File.Copy(sourceFileName, destFileName, true);
        }
    }
    catch (Exception ex)
    {
        Logger.Error(ex.ToString());
    }
}

总结

至此,我已经完成了自动发布项目的主体功能,实现自动检测代码变化,自动一键打包发布, 不足的地方有: 第一次发布需要手动处理, 项目也需要手动编译,并配置输出目录,但是我相信,这些都不是问题,只要有思路,都是可以解决的,我主要分享下我的实现步骤

注意

1. 本项目目前只支持 .net framework 的单体 Web 项目
2. 客户端和服务端均是 Windows 服务器
3. 线上项目是 IIS 部署的
4. 代码可能存在 BUG,大家发现可以自行解决,或者联系我,我后面不准备继续维护这个项目,毕竟主要是学习分享用的~~~

代码仓库

项目暂且就叫 OpenDeploy

  • OpenDeploy: https://gitee.com/broadm-dotnet/OpenDeploy

欢迎大家拍砖,Star

下一步

服务端目前是控制台实现, 可以部署为 Windows 服务, 这个也很简单, 我就不发了, 大家自行实现吧, 完结~文章来源地址https://www.toymoban.com/news/detail-750464.html

到了这里,关于基于DotNetty实现自动发布 - 实现一键打包发布的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Jenkins的环境部署,(打包、发布、部署、自动化测试)

    Jenkins的环境部署,(打包、发布、部署、自动化测试)

    一、Tomcat环境安装 1.安装JDK(Java环境) JDK下载地址:Java Downloads | Oracle 安装好后在系统环境变量里配置环境变量: ①添加JAVA_HOME 变量名:JAVA_HOME 变量值:C:Program FilesJavajdk1.8.0_181(根据自己的实际路径配置) ②添加CLASSPATH 变量名:CLASSPATH 变量值:.;%JAVA_HOME%libdt.jar;%J

    2024年01月18日
    浏览(13)
  • android 实现本地一键打包,告别繁琐的studio操作

    android 实现本地一键打包,告别繁琐的studio操作

    在实际开发项目中,我们的工程目录往往是多个app在一个工程下的,每次打包都需要手动的用studio点击Build-Generate Signed Bundle or APK-APK 选择app,签名等,甚至有的app签名还不一样,还需要手动的来回切换,非常麻烦。所以,我就考虑采用多渠道打包+shell脚本的方式,来实现一行

    2024年02月10日
    浏览(10)
  • java实现微信公众号图文、视频一键发布

    在微信开发平台申请一个测试账号(优先选择这个),如果可以使用认证过的订阅号最好,不过我们在开发阶段很多功能都是测试用的,申请一个测试账号完全够用 个人的订阅号是不可以申请认证的,所以很多微信API不可以用 二、开始开发 写在前面 项目所需依赖 所有涉及

    2024年02月15日
    浏览(8)
  • Jenkins自动构建打包发布vue项目报错Error: error:0308010C:digital envelope routines::unsupported

    错误日志: 原因: 新版本node.js使用了OpenSSL3.0对允许算法和密钥大小增加了严格的限制。 解决办法: Windows: Linux:

    2024年02月17日
    浏览(9)
  • Filebeat 自动安装部署&一键配置实现

    Filebeat 自动安装部署&一键配置实现

    Filebeat 是使用 Golang 实现的轻量型日志采集器,也是 Elasticsearch stack 里面的一员。 Filebeat本质上是一个 agent ,可以安装在各个节点上,根据配置读取对应位置的日志,并上报到相应的日志管理平台上去 平时接到将某一服务的日志接入到日志管理平台的需求 通常的做法都是:

    2023年04月08日
    浏览(10)
  • Unity 基于Jenkins自动化打包流程

    Unity 基于Jenkins自动化打包流程

    什么是Jenkins?         Jenkins是一款开源 CICD 软件,用于自动化各种任务,包括构建、测试和部署软件。Jenkins 支持各种运行方式,可通过系统包、Docker 或者通过一个独立的 Java 程序。 Jenkins的下载与安卓 直接搜索jenkins进入官网下在LTS(稳定版本)下载地址:https://www.jen

    2024年02月08日
    浏览(24)
  • 基于Jenkins自动打包并部署Tomcat环境

    基于Jenkins自动打包并部署Tomcat环境

    目录 1、配置git主机 2、配置jenkins主机 3、配置web主机 4、新建Maven项目 5、验证 Jenkins 自动打包部署结果 Jenkins 的工作原理是先将源代码从 SVN/Git 版本控制系统中拷贝一份到本地,然后根据设置的脚本调用Maven进行 build(构建)。整个系统的关键就是 build 脚本,build 脚本告诉

    2024年02月11日
    浏览(15)
  • 基于Jenkins自动打包并部署docker环境

    基于Jenkins自动打包并部署docker环境

    目录 1、安装docker-ce 2、阿里云镜像加速器 3、构建tomcat 基础镜像  4、构建一个Maven项目 实验环境 操作系统 IP地址 主机名 角色 CentOS 7.5 192.168.200.111 git git服务器 CentOS 7.5 192.168.200.112 Jenkins git客户端 jenkins服务器 CentOS 7.5 192.168.200.113 docker web服务器 在192.168.200.113上创建远程目录

    2024年02月11日
    浏览(18)
  • SpringBoot+Vue前后端分离项目在Linux系统中基于Docker打包发布,并上传镜像到阿里镜像私仓

    SpringBoot+Vue前后端分离项目在Linux系统中基于Docker打包发布,并上传镜像到阿里镜像私仓

    将打好的jar包放到咱们opt目录下的自定义文件夹内 打包成功后 –rm 代表退出之后,容器移动删除 可以看到成功启动了服务 阿里云免费私仓 创建好自己的镜像仓库后会显示操作指南 身份登录 将镜像推送到Registry 可以在镜像仓库中进行查看 拉取镜像 default.conf 1.root:设置静态

    2024年04月17日
    浏览(24)
  • Jenkins+Docker 实现一键自动化部署项目

    Jenkins+Docker 实现一键自动化部署项目

    1.安装Jenkins 注:因为Jenkins容器里的用户是Jenkins,而主机用户不是Jenkins,就算是root也一样会报错:/var/jenkins_home/copy_reference_file.log: Permission denied,这个时候就需要在主机上面给主机地址赋予访问Jenkins容器的权限,Jenkins内部用的是uid 1000的user。 -privileged=true让容器具有root权限

    2024年02月16日
    浏览(14)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包