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

前两篇博文中提到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和运行的服务分离,进程间互不影响。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/306860.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何把python文件发给别人没_如何把自己写的python程序给别人用

这里讲的给别人用&#xff0c;不是指将你的代码开源&#xff0c;也不是指给另一个程序员用。。。。。 前段时间写了个程序&#xff0c;输入URP学生系统的账号和密码&#xff0c;输出课表、绩点之类的信息&#xff0c;想给同学用&#xff0c;但是总不能叫别人也去装python吧。。…

使用WebBenchmark对webapi进行管理和性能测试

WebBenchmark是基于beetlex开发的webapi管理和性能测试软件&#xff0c;最新版本1.0.3可以独立运行在linux/windows中&#xff0c;并不再需要安装.net core运行环境。部署可以通过以下地址下载最新版本:https://github.com/IKende/WebBenchmark可以根据需要下载linux64或win64运…

三维叉乘怎么算_奇技淫巧系列:向量叉乘

​一般我们在解决立体几何题目时会选择建立坐标系&#xff0c;因为这样做比较保险也有固定套路。很多时候这些题目要求你计算某一个面的法向量&#xff08;normal vector&#xff09;&#xff0c;这在高中阶段也是有固定方法的&#xff0c;我们这里想要介绍的是一种更高级也更迅…

g++ linux intel 汇编,g++ linux

目标&#xff1a;运行C代码example&#xff1a;有func.h,func.cpp, main.cpp- .h无需编译&#xff0c;但.h中函数实现的地方需要编译(func.cpp)- 逻辑&#xff1a;cpp各自生成可执行文件(.o),再进行链接g -c func.cppg -c main.cppg main.o func.o -o test或者直接&#xff1a;…

提高python执行效率_提升Python程序运行效率的6个方法

Python是一个很酷的语言&#xff0c;因为你可以在很短的时间内利用很少的代码做很多事情。不仅如此&#xff0c;它还能轻松地支持多任务&#xff0c;比如多进程等。Python批评者有时会说Python执行缓慢。本文将尝试介绍6个技巧&#xff0c;可加速你的Python应用程序。 1.让关键…

听说容器正在吃掉整个软件世界?

过去几年&#xff0c;以 docker、kubernetes 为代表的容器技术已发展为一项通用技术&#xff0c;BAT、滴滴、京东、头条等大厂&#xff0c;都争相把容器和 k8s 项目作为技术重心&#xff0c;试图“放长线钓大鱼”。就说腾讯吧&#xff0c;目前基本所有业务都跑在云上&#xff0…

linux 短信功能,Android调用系统短信功能发送短信

Android调用系统短信功能发送短信有两种方法:第一种&#xff0c;设定发送的号码&#xff0c;和内容&#xff0c;界面没有联系人&#xff0c;群组组等按钮&#xff0c;如下图所示&#xff1a;代码如下&#xff1a;Uri smsToUri Uri.parse("smsto:114");// 联系人地址…

浅析 EF Core 5 中的 DbContextFactory

EF Core 5 中的 DbContextFactoryIntro使用过 EF Core 大多都会遇到这样一个场景&#xff0c;希望能够并行查询&#xff0c;但是如果使用同一个 DbContext 实例进行并行操作的时候就会遇到一个 InvalidOperationException 的异常&#xff0c;在 EF Core 2.x/3.x 版本中&#xf…

bcm943602cs蓝牙用不了_原来手机的蓝牙功能这么强大!除了连接耳机,还有这六大实用功能...

蓝牙是手机上的一个普通功能&#xff0c;基本上所有的手机里都有它&#xff0c;原先它的作用很有限&#xff0c;只是用来传输数据&#xff0c;但由于速度太慢&#xff0c;最后也是被软件所淘汰&#xff0c;慢慢的可以用来连接耳机&#xff0c;这也是博主用的比较多的一个功能&a…

c语言数字字母和字符串,C语言字符串用法之字符串和数字的转换

把字符串转换为数字1.考虑字符串除最后一个都是数字&#xff0c;如236\0int strToInt(const char *str){int temp 0;const char *ptr str; //ptr保存str字符串开头while(*str ! 0){temp temp * 10 (*str - 0);//根据ASCII码的数学关系把字符转换为数字str;}return temp;}2.…

数据结构——表达式求值(中序)

表达式求值&#xff08;中序&#xff09; 实验二 基于栈的中缀算术表达式求值 【实验目的】 1.掌握栈的基本操作算法的实现,包括栈初始化、进栈、出栈、取栈顶元素等。 2.掌握利用栈实现中缀表达式求值的算法。 【实验内容】 问题描述 输入一个中缀算术表达式,求解表达式的值。…

msdn画圆弧函数_画直线不简单!python-matplotlib告诉你为什么

1 说明&#xff1a;1.1 python的matplotlib画直线&#xff0c;看似简单&#xff0c;其实很难&#xff0c;从简单到复杂&#xff0c;逐步深入&#xff0c;小白秒懂。1.2 内容&#xff1a;画直线&#xff0c;画圆&#xff0c;画圆点&#xff0c;动画的单摆和圆套圆&#xff0c;好…

Wifi6网络

2020年是Wifi6设备全面爆发的一年&#xff0c;华为、小米、华硕、腾达、TP-LINK、360等多家厂商相继发布了Wifi6路由产品&#xff0c;掀起了一股更换路由器的热潮。首先&#xff0c;我们先来看几个常识1、Wifi6和IPv6两个没有必然联系&#xff0c;Wifi6是一种支持802.11ax的Wif…

c语言字符串中取最大字符串,使用C语言提取子字符串及判断对称子字符串最大长度...

先来看一个使用C语言从字符串中提取子字符串的基本方法总结&#xff1a;#include /*处理中文字符*//*遍历字符串&#xff0c;非ASCII字符读取2个字节&#xff0c;ASCII读取一个字节&#xff0c;获取字符串长度*/int StrLenU(const char* string){int len 0 ;const char* p st…

数据结构——用栈解决回文字符问题

回文 回文是指正读反读均相同的字符序列,如“abba”和“abdba”均是回文&#xff0c;但“good”不是回文。试写一个算法判定给定的字符序列是否为回文。&#xff08;提示&#xff1a;将一半字符入栈。&#xff09; 所需的知识前提&#xff1a;栈 以下是顺序栈的基本算法 结构…

aspose excel中文文档_除了VBA,还有哪些编程语言可以操作Excel文件?

Excel(Microsoft office)是现在最常用的办公软件&#xff0c;主要涉及电子表格制作、数据处理、报表输出展示以及更高端的还有金融建模等&#xff1b;我们知道&#xff0c;在需要批处理多个Excel工作表以及工作簿的时候&#xff0c;需要用到一个自动化的利器&#xff1a;VBAVBA…

关于.NET5在IIS中部署的几个问题总结

本来我的系列教程已经慢慢剥离开IIS了&#xff0c;毕竟有了Docker容器以后&#xff0c;配合Nginx使用真的很不错。但是还是有很多同学使用IIS的&#xff0c;这个不可否认IIS的重要性。随着.NET的发布&#xff0c;很多小伙伴已经开始升级了&#xff0c;我也就陆陆续续收到了一些…

上海市二级c语言软件环境,上海市计算机二级C语言复习资料 word整理版.doc

上海市高等学校计算机等级考试二级(C程序设计)03年上海市高等学校计算机等级考试试卷二级 (C程序设计)(本试卷答卷时间为120分钟)试题一(28分&#xff0c;每小题4分)解答下列各小题&#xff0c;把正确的解答写在答卷纸的对应栏内。设有变量说明&#xff1a;int a5,b4,c3,r1,r2;…

数据结构——括号匹配问题

括号匹配 给定一个字符串&#xff0c;其中的字符只包含三种括号&#xff1a;花括号{ }、中括号[ ]、圆括号( )&#xff0c;即它仅由 “( ) [ ] { }” 这六个字符组成。设计算法&#xff0c;判断该字符串是否有效&#xff0c;即字符串中括号是否匹配。括号匹配要求括号必须以正…

wordpress多站点主站调用分站最新文章_企业网站SEO最新的7个优化步骤!

如果你是一个企业主&#xff0c;你有建立企业官方网站的经验&#xff0c;在2-3年的运作中&#xff0c;我相信你至少修改了一个网站&#xff0c;甚至做了一个重大的SEO策略调整。当我们开始建立一个公司的时候&#xff0c;很多时候就是认为只要我们有一个公司的网站&#xff0c;…