ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

持续交付三:动手自动化“开发”—>“测试”

2022-01-31 16:01:51  阅读:180  来源: 互联网

标签:Console 交付 WriteLine process return 测试 自动化 var using


 

 

  前两篇博文中提到Development,QA,Staging,Production四个环境,也说明了源代码的分支和四个环境的对应关系,本篇博文聊一下,怎么把源码自动化发布到对应的环境中。

  市面上主流的DevOpt工具都支持这些功能,github,gitlab,都有CICD功能,当然,如果源码服务器是自己搭建的,也可以利用像Jenkins这类软件来实现CICD,关于这些大众工具,网上有很多教程序,这里就不主要来分享了,本例是用.net core实现一个极简的自动发布工具——《MyCICD》。

  说一下实现思路吧!

  1. clone 或 pull分支代码
  2. publish
  3. run


  是不是很简单,上代码吧

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

namespace MyCICD
{
    class Program
    {
        static void Main(string[] args)
        {
            var processIDs = new int[0];
            while (true)
            {
                if (Clone())
                {
                    if (Publish(processIDs))
                    {
                        processIDs = Run();
                    }
                }
                Thread.Sleep(30000);
            }
        }

        /// <summary>
        /// git 克隆
        /// </summary>
        /// <returns></returns>
        static bool Clone()
        {
            var gitLib = ConfigurationManager.AppSettings["GitLib"];
            var sourcePath = ConfigurationManager.AppSettings["SourcePath"];
            var sourceDir = $"{sourcePath.TrimEnd('/', '\\') }/{ Path.GetFileNameWithoutExtension(gitLib)} ";
            //存在就拉取代码,不存在就克隆
            if (Directory.Exists(sourceDir))
            {
                return Pull(sourceDir);
            }
            else
            {
                return Clone(gitLib, sourceDir);
            }
        }
        /// <summary>
        /// 克隆项目代码
        /// </summary>
        /// <param name="gitLib">git库</param>
        /// <param name="sourceDir">本地保存路径</param>
        /// <returns></returns>
        static bool Clone(string gitLib, string sourceDir)
        {
            Console.WriteLine("开始Clone");
            var processStartInfo = new ProcessStartInfo("git", $"clone {gitLib} {sourceDir}") { RedirectStandardOutput = true };

            var process = Process.Start(processStartInfo);
            if (process == null)
            {
                Console.WriteLine("请确认是否安装git");
                return false;
            }
            else
            {
                using (var output = process.StandardOutput)
                {
                    while (!output.EndOfStream)
                    {
                        Console.WriteLine(output.ReadLine());
                    }
                    if (!process.HasExited)
                    {
                        process.Kill();
                    }
                }
                Console.WriteLine($"执行时间 :{(process.ExitTime - process.StartTime).TotalMilliseconds} ms");
                Console.WriteLine("结束Clone");
                return process.ExitCode == 0;
            }
        }
        /// <summary>
        /// 拉取项目代码
        /// </summary>
        /// <param name="sourceDir">源码路径</param>
        /// <returns></returns>
        static bool Pull(string sourceDir)
        {
            Console.WriteLine("开始Fetch");
            var processStartInfo = new ProcessStartInfo("git", $"pull origin")
            {
                RedirectStandardOutput = true,
                WorkingDirectory = sourceDir,
            };

            var process = Process.Start(processStartInfo);
            using (var output = process.StandardOutput)
            {
                var resultBuilder = new StringBuilder();
                while (!output.EndOfStream)
                {
                    resultBuilder.AppendLine(output.ReadLine());
                }
                Console.WriteLine(resultBuilder);
                if (!process.HasExited)
                {
                    process.Kill();
                }
                if (resultBuilder.ToString() != "Already up to date.\r\n")
                {
                    Console.WriteLine("结束Fetch");
                    return true;
                }
                else
                {
                    Console.WriteLine("结束Fetch,远程仓库没有更新");
                    return false;
                }
            }
        }

        #region 发布项目
        /// <summary>
        /// 发布项目
        /// </summary>
        /// <returns></returns>
        static bool Publish(int[] processIDs)
        {
            Console.WriteLine("开始Publish");
            var sourcePath = ConfigurationManager.AppSettings["SourcePath"];
            var publishProject = ConfigurationManager.AppSettings["PublishProject"];
            //找出要发布的项目
            var projectPathLists = publishProject.Split(",");
            var projects = GetProjectsPath(sourcePath, projectPathLists);
            var publishDir = $"{sourcePath}/publish";
            var result = true;//如果有一个项目失败,发布就会失败
            //为了发布,关闭之前运行中的进程
            foreach (var processid in processIDs)
            {
                Process.GetProcessById(processid).Kill();
            }
            //发布项目
            foreach (var project in projects)
            {
                var processStartInfo = new ProcessStartInfo("dotnet", $"publish {project} -o {publishDir}/{Path.GetFileNameWithoutExtension(project)}") { RedirectStandardOutput = true };
                var process = Process.Start(processStartInfo);
                if (process == null)
                {
                    Console.WriteLine("请确认是否安装dotnet sdk");
                    return false;
                }
                else
                {
                    using (var output = process.StandardOutput)
                    {
                        while (!output.EndOfStream)
                        {
                            Console.WriteLine(output.ReadLine());
                        }

                        if (!process.HasExited)
                        {
                            process.Kill();
                        }
                    }
                    Console.WriteLine($"执行时间 :{(process.ExitTime - process.StartTime).TotalMilliseconds} ms");
                    if (process.ExitCode != 0)
                    {
                        Console.WriteLine($"{Path.GetFileNameWithoutExtension(project)}发布失败");
                    }
                    result = result || process.ExitCode == 0;
                }
            }
            Console.WriteLine("结束Publish");
            return result;
        }
        /// <summary>
        /// 查找项目
        /// </summary>
        /// <param name="sourcePath">源码路径</param>
        /// <param name="projects">项目集</param>
        /// <returns></returns>
        static string[] GetProjectsPath(string sourcePath, string[] projects)
        {
            var paths = new List<string>();
            foreach (var file in Directory.GetFiles(sourcePath))
            {
                if (projects.Contains(Path.GetFileName(file)))
                {
                    paths.Add(file);
                }

            }
            foreach (var dir in Directory.GetDirectories(sourcePath))
            {
                paths.AddRange(GetProjectsPath(dir, projects));
            }
            return paths.ToArray();
        }
        #endregion
        
        #region 运行项目
        /// <summary>
        /// 运行项目
        /// </summary>
        /// <returns></returns>
        static int[] Run()
        {
            Console.WriteLine("开始运行");
            var sourcePath = ConfigurationManager.AppSettings["SourcePath"];
            var publishDir = $"{sourcePath}/publish";
            var proceddIDs = new List<int>();
            foreach (var projectPath in Directory.GetDirectories(publishDir))
            {
                var processStartInfo = new ProcessStartInfo("dotnet", $"{Path.GetFileNameWithoutExtension(projectPath)}.dll")
                {
                    RedirectStandardOutput = true,
                    WorkingDirectory = projectPath,
                };
                var process = Process.Start(processStartInfo);
                proceddIDs.Add(process.Id);
            }
            Console.WriteLine("结束运行");
            return proceddIDs.ToArray();
        }
        #endregion
    }
}

  App.config配置文件

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>    
    <!--git库相关:git库路径,clone后本地何存路径-->
    <add key="GitLib" value="https://github.com/axzxs2001/Asp.NetCoreExperiment.git"/>
    <add key="SourcePath" value="e:/test/"/>
    <!--dotnet发布相关:要发布的项目-->
    <add key="PublishProject" value="AspNetCoreEnvironment.csproj,WebError.csproj"/>    
  </appSettings>
</configuration>

  这个例子很简单,只支持在windows下运行,同时run起来的应用和MyCICD是在一个进程中,一但进程关闭,run的服务也就掉了,还有很多需要改进,如果有兴趣,可以完善,比如可以跑大多个平台上(linux,docker,mac)下,也可以把MyCICD和运行的服务分离,进程间互不影响。

 

  想要更快更方便的了解相关知识,可以关注微信公众号 

 

 

 

标签:Console,交付,WriteLine,process,return,测试,自动化,var,using
来源: https://www.cnblogs.com/axzxs2001/p/15858331.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有