经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » ASP.net » 查看文章
基于DotNetty实现自动发布 - 自动检测代码变化
来源:cnblogs  作者:Broadm  时间:2023/12/8 11:58:45  对本文有异议

前言

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

已完成的功能

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

image
image
image

简要说明

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

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

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

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

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

部分代码

发现解决方案

  1. private static Solution DetectSolution(string gitRepoPath)
  2. {
  3. string[] solutionFilePaths = Directory.GetFiles(gitRepoPath, "*.sln", SearchOption.AllDirectories);
  4. if (solutionFilePaths == null || solutionFilePaths.Length == 0)
  5. {
  6. throw new Exception("未找到解决方案");
  7. }
  8. string[] projectFilePaths = Directory.GetFiles(gitRepoPath, "*.csproj", SearchOption.AllDirectories);
  9. if (projectFilePaths == null || projectFilePaths.Length == 0)
  10. {
  11. throw new Exception("未找到项目");
  12. }
  13. var solutionFilePath = solutionFilePaths[0];
  14. var solutionDir = Path.GetDirectoryName(solutionFilePath);
  15. var solutionName = Path.GetFileNameWithoutExtension(solutionFilePath);
  16. var solution = new Solution
  17. {
  18. GitRepositoryPath = gitRepoPath,
  19. SolutionDir = solutionDir!,
  20. SolutionName = solutionName
  21. };
  22. foreach (var projectFilePath in projectFilePaths)
  23. {
  24. var projectDir = Path.GetDirectoryName(projectFilePath);
  25. var projectName = Path.GetFileNameWithoutExtension(projectFilePath);
  26. var webConfigFiles = Directory.GetFiles(projectDir!, "web.config", SearchOption.TopDirectoryOnly);
  27. var project = new Project
  28. {
  29. ProjectDir = projectDir!,
  30. ProjectName = projectName,
  31. IsWeb = webConfigFiles != null && webConfigFiles.Length > 0,
  32. SolutionName = solutionName,
  33. ReleaseDir = string.Empty
  34. };
  35. solution.Projects.Add(project);
  36. }
  37. return solution;
  38. }

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

  1. public static List<PatchEntryChanges> GetChangesSinceLastPublish(string repoPath, string? lastCommitId = null)
  2. {
  3. var repo = GetRepo(repoPath);
  4. //获取上次发布的提交
  5. Commit? lastCommit = null;
  6. if (!string.IsNullOrEmpty(lastCommitId))
  7. {
  8. lastCommit = repo.Lookup<Commit>(lastCommitId);
  9. if (lastCommit == null)
  10. {
  11. throw new Exception("无法获取上次发布的提交记录");
  12. }
  13. }
  14. //获取自上次提交以来的改动
  15. var diff = repo.Diff.Compare<Patch>(lastCommit?.Tree, DiffTargets.Index);
  16. return [.. diff];
  17. }

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

  1. private List<DeployFileInfo> GetPublishFiles(IEnumerable<string> changedFilePaths)
  2. {
  3. var fileInfos = new List<DeployFileInfo>(changedFilePaths.Count());
  4. foreach (string changedPath in changedFilePaths)
  5. {
  6. var fi = DeployFileInfo.Create(changedPath);
  7. if (fi.IsUnKnown) continue;
  8. fileInfos.Add(fi);
  9. }
  10. foreach (var fi in fileInfos)
  11. {
  12. fi.ChangedFileAbsolutePath = Path.Combine(GitRepositoryPath, fi.ChangedFileRelativePath);
  13. //所属项目
  14. var project = Projects
  15. .Where(a => fi.ChangedFileRelativePath.Contains(a.ProjectName, StringComparison.OrdinalIgnoreCase))
  16. .FirstOrDefault();
  17. if (project == null) continue;
  18. fi.ProjectName = project.ProjectName;
  19. if (fi.IsDLL)
  20. {
  21. fi.FileName = $"{project.ProjectName}.dll";
  22. fi.PublishFileRelativePath = $"bin\\{fi.FileName}";
  23. }
  24. else
  25. {
  26. fi.PublishFileRelativePath = fi.ChangedFileAbsolutePath.Replace(project.ProjectDir, "").TrimStart(Path.DirectorySeparatorChar);
  27. }
  28. fi.PublishFileAbsolutePath = Path.Combine(webProject!.ReleaseDir, fi.PublishFileRelativePath);
  29. //Logger.Info(fi.ToJsonString(true));
  30. }
  31. //按照 PublishFileAbsolutePath 去重
  32. return fileInfos.Distinct(new DeployFileInfoComparer()).ToList();
  33. }

设置项目发布路径

  1. private async Task OkSetProjectReleaseDir()
  2. {
  3. if (string.IsNullOrEmpty(ReleaseDir) || !Directory.Exists(ReleaseDir))
  4. {
  5. Growl.ClearGlobal();
  6. Growl.ErrorGlobal("请正确设置项目发布路径");
  7. return;
  8. }
  9. var solutionRepo = Program.AppHost.Services.GetRequiredService<SolutionRepository>();
  10. await solutionRepo.UpdateProjectReleaseDir(Id, ReleaseDir);
  11. setProjectReleaseDirDialog?.Close();
  12. Growl.SuccessGlobal("操作成功");
  13. }

总结

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

代码仓库

项目暂且就叫 OpenDeploy

欢迎大家拍砖,Star

下一步

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

原文链接:https://www.cnblogs.com/broadm/p/17884873.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号