首页 > 其他分享 >基于DotNetty实现自动发布 - 自动检测代码变化

基于DotNetty实现自动发布 - 自动检测代码变化

时间:2023-12-08 12:00:31浏览次数:36  
标签:string 自动检测 代码 new project Path var fi DotNetty

前言

很抱歉没有实现上一篇的目标:一键发布,因为工作量超出了预期,本次只实现了 Git 代码变化检测

已完成的功能

  • 解决方案的项目发现与配置
  • 首次发布需要手动处理
  • 自动检测代码变化并解析出待发布的文件

image
image
image

简要说明

  • 只需要填写解决方案的 Git 仓储路径即可自动发现项目 (通过查找 .csproj 文件实现)

  • 自动发现 Web 项目 (通过判断项目根目录是否包含 Web.config 实现) PS: 只支持 .NET Framework

  • 需要配置 Web 项目的发布目录, 编译还需要手动执行

  • 首次发布需要手动执行, 然后保存此次发布对应的 Git 提交 ID

  • 后续发布,可以根据上次发布记录,自动解析出待待发布的文件

部分代码

发现解决方案

private static Solution DetectSolution(string gitRepoPath)
{
    string[] solutionFilePaths = Directory.GetFiles(gitRepoPath, "*.sln", SearchOption.AllDirectories);
    if (solutionFilePaths == null || solutionFilePaths.Length == 0)
    {
        throw new Exception("未找到解决方案");
    }
    string[] projectFilePaths = Directory.GetFiles(gitRepoPath, "*.csproj", SearchOption.AllDirectories);
    if (projectFilePaths == null || projectFilePaths.Length == 0)
    {
        throw new Exception("未找到项目");
    }

    var solutionFilePath = solutionFilePaths[0];
    var solutionDir = Path.GetDirectoryName(solutionFilePath);
    var solutionName = Path.GetFileNameWithoutExtension(solutionFilePath);

    var solution = new Solution
    {
        GitRepositoryPath = gitRepoPath,
        SolutionDir = solutionDir!,
        SolutionName = solutionName
    };

    foreach (var projectFilePath in projectFilePaths)
    {
        var projectDir = Path.GetDirectoryName(projectFilePath);
        var projectName = Path.GetFileNameWithoutExtension(projectFilePath);
        var webConfigFiles = Directory.GetFiles(projectDir!, "web.config", SearchOption.TopDirectoryOnly);
        var project = new Project
        {
            ProjectDir = projectDir!,
            ProjectName = projectName,
            IsWeb = webConfigFiles != null && webConfigFiles.Length > 0,
            SolutionName = solutionName,
            ReleaseDir = string.Empty
        };
        solution.Projects.Add(project);
    }
    return solution;
}

获取自上次发布以来的改动

public static List<PatchEntryChanges> GetChangesSinceLastPublish(string repoPath, string? lastCommitId = null)
{
    var repo = GetRepo(repoPath);

    //获取上次发布的提交
    Commit? lastCommit = null;
    if (!string.IsNullOrEmpty(lastCommitId))
    {
        lastCommit = repo.Lookup<Commit>(lastCommitId);
        if (lastCommit == null)
        {
            throw new Exception("无法获取上次发布的提交记录");
        }
    }

    //获取自上次提交以来的改动
    var diff = repo.Diff.Compare<Patch>(lastCommit?.Tree, DiffTargets.Index);
    return [.. diff];
}

从 Git 修改记录提取出待发布文件

private List<DeployFileInfo> GetPublishFiles(IEnumerable<string> changedFilePaths)
{
    var fileInfos = new List<DeployFileInfo>(changedFilePaths.Count());
    foreach (string changedPath in changedFilePaths)
    {
        var fi = DeployFileInfo.Create(changedPath);
        if (fi.IsUnKnown) continue;
        fileInfos.Add(fi);
    }
    foreach (var fi in fileInfos)
    {
        fi.ChangedFileAbsolutePath = Path.Combine(GitRepositoryPath, fi.ChangedFileRelativePath);

        //所属项目
        var project = Projects
            .Where(a => fi.ChangedFileRelativePath.Contains(a.ProjectName, StringComparison.OrdinalIgnoreCase))
            .FirstOrDefault();
        if (project == null) continue;

        fi.ProjectName = project.ProjectName;
        if (fi.IsDLL)
        {
            fi.FileName = $"{project.ProjectName}.dll";
            fi.PublishFileRelativePath = $"bin\\{fi.FileName}";
        }
        else
        {
            fi.PublishFileRelativePath = fi.ChangedFileAbsolutePath.Replace(project.ProjectDir, "").TrimStart(Path.DirectorySeparatorChar);
        }
        fi.PublishFileAbsolutePath = Path.Combine(webProject!.ReleaseDir, fi.PublishFileRelativePath);

        //Logger.Info(fi.ToJsonString(true));
    }
    //按照 PublishFileAbsolutePath 去重
    return fileInfos.Distinct(new DeployFileInfoComparer()).ToList();
}

设置项目发布路径

private async Task OkSetProjectReleaseDir()
{
    if (string.IsNullOrEmpty(ReleaseDir) || !Directory.Exists(ReleaseDir))
    {
        Growl.ClearGlobal();
        Growl.ErrorGlobal("请正确设置项目发布路径");
        return;
    }

    var solutionRepo = Program.AppHost.Services.GetRequiredService<SolutionRepository>();
    await solutionRepo.UpdateProjectReleaseDir(Id, ReleaseDir);

    setProjectReleaseDirDialog?.Close();

    Growl.SuccessGlobal("操作成功");
}

总结

本篇主要实现了 Git 代码变化的自动检测

代码仓库

项目暂且就叫 OpenDeploy

欢迎大家拍砖,Star

下一步

计划下一步,实现一键发布,把待发布的文件一次性打包通过 DotNetty 发送到服务器

标签:string,自动检测,代码,new,project,Path,var,fi,DotNetty
From: https://www.cnblogs.com/broadm/p/17884873.html

相关文章

  • 编代码遇到的问题-1
    题目是CP1201第一次代码是#include<stdio.h>#include<stdlib.h>intmain(){inta=0,m,n,i;scanf("%d,%d",&m,&n);if((m+1)%i==0&&(n+1)%i==0&&i<m+1&&i<n+1){a=i;}prin......
  • SAP数据一键拉取!利用零代码ETL工具快速实现数据同步
    当我们谈到SAP数据读取以及提取、转换、加载(ETL)工作时,选择适当的方法和工具对于企业来说至关重要。本文将为您介绍如何通过SAP函数读取数据,并推荐一些强大的ETL工具,以帮助您更好地处理和整合SAP数据。如何解锁SAP数据的力量?SAP系统在现代企业中扮演着关键的角色,管理着财务、供......
  • 代码混淆技术探究与工具选择
    引言在软件开发中,保护程序代码的安全性是至关重要的一环。代码混淆(Obfuscatedcode)作为一种常见的保护手段,通过将代码转换成难以理解的形式来提升应用被逆向破解的难度。本文将介绍代码混淆的概念、方法以及常见的代码混淆工具。 正文什么是代码混淆?代码混淆是指将计算机程......
  • day8、9字符串代码随想录
    第四章字符串●344.反转字符串●541.反转字符串II●卡码网:54.替换数字●151.翻转字符串里的单词●卡码网:55.右旋转字符串1反转字符串编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组char[]的形式给出。不要给另外的数组分配额外的空间,你必须......
  • 代码中公用生成使用token方法
    生成使用token引入pom<dependency>     <groupId>com.auth0</groupId>     <artifactId>java-jwt</artifactId>     <version>3.14.0</version>   </dependency>添加工具类packagecom.mashibing.interin......
  • MISBoot低代码开发平台、拖拉拽打造绚丽大屏报表!
    在当今数字化时代,大屏报表已成为企业管理和决策的重要工具之一。然而,传统的开发方式往往需要专业的编码技能和繁琐的配置过程,限制了许多企业的快速实现以及灵活性。为了解决这一问题,MISBoot低代码开发平台推出了全新的可视化大屏报表模块,以拖拉拽配置、无需编码的方式,为企业提供了......
  • 小程序建立用户与数据的联系,运行代码后报错如何解决?
    要解决小程序建立用户与数据联系后出现的报错,您可以按照以下步骤进行排查和解决:检查报错信息:仔细阅读报错信息,了解出错的位置和具体的错误提示。这可以帮助您定位问题所在。检查代码逻辑:仔细检查您的代码逻辑,特别是涉及用户与数据关联的部分。确保代码中没有语法错误、逻辑错误或者......
  • 墨者学院—Webmin未经身份验证的远程代码执行漏洞
    一、概述Webmin是目前功能最强大的基于Web的Unix系统管理工具。管理员通过浏览器访问Webmin的各种管理功能并完成相应的管理动作。据统计,互联网上大约有13w台机器使用Webmin。当用户开启Webmin密码重置功能后,攻击者可以通过发送POST请求在目标系统中执行任意命令,且无需身份验......
  • UEFI代码中执行UEFI shell命令
    在UEFI代码中执行UEFIshell命令,类似于linux下C代码执行system("command")系统调用。MyUefiShell.inf内容如下:[Defines]INF_VERSION=1.25......
  • 拉取镜像代码
    #检测是否含有yq命令echo-e"正在将内容输出至$Images_File文件中,请稍等..."#获取Harbor中所有的项目(Projects)Project_List=$(curl-u${Harbor_User}:${Harbor_Passwd}-H"Content-Type:application/json"-XGET"${Harbor_Schema}://${Harbor_Address}/api/v2.0/......