博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
持续交付三:动手自动化“开发”—>“测试”
阅读量:4035 次
发布时间:2019-05-24

本文共 7791 字,大约阅读时间需要 25 分钟。

前两篇博文中提到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);            }        }        ///         /// git 克隆        ///         /// 
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); } } ///         /// 克隆项目代码 /// /// git库 /// 本地保存路径 ///
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; } } ///         /// 拉取项目代码 /// /// 源码路径 ///
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 发布项目 /// /// 发布项目 /// ///
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; } /// /// 查找项目 /// /// 源码路径 /// 项目集 ///
static string[] GetProjectsPath(string sourcePath, string[] projects) { var paths = new List
(); 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 运行项目 ///
/// 运行项目 /// ///
static int[] Run() { Console.WriteLine("开始运行"); var sourcePath = ConfigurationManager.AppSettings["SourcePath"]; var publishDir = $"{sourcePath}/publish"; var proceddIDs = new List
(); 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配置文件

    

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

转载地址:http://xakdi.baihongyu.com/

你可能感兴趣的文章
面试---刷牛客算法题
查看>>
Android下调用收发短信邮件等(转载)
查看>>
Android中电池信息(Battery information)的取得
查看>>
SVN客户端命令详解
查看>>
Android/Linux 内存监视
查看>>
Linux系统信息查看
查看>>
用find命令查找最近修改过的文件
查看>>
Android2.1消息应用(Messaging)源码学习笔记
查看>>
在android上运行native可执行程序
查看>>
Phone双模修改涉及文件列表
查看>>
android UI小知识点
查看>>
Android之TelephonyManager类的方法详解
查看>>
android raw读取超过1M文件的方法
查看>>
ubuntu下SVN服务器安装配置
查看>>
MPMoviePlayerViewController和MPMoviePlayerController的使用
查看>>
CocoaPods实践之制作篇
查看>>
[Mac]Mac 操作系统 常见技巧
查看>>
苹果Swift编程语言入门教程【中文版】
查看>>
捕鱼忍者(ninja fishing)之游戏指南+游戏攻略+游戏体验
查看>>
iphone开发基础之objective-c学习
查看>>