天津城建设计院网站,专业开发手机网站建设,如何把官网,相册管理网站模板前两篇博文中提到Development,QA,Staging,Production四个环境#xff0c;也说明了源代码的分支和四个环境的对应关系#xff0c;本篇博文聊一下#xff0c;怎么把源码自动化发布到对应的环境中。市面上主流的DevOpt工具都支持这些功能#xff0c;github,gitlab#xff0c;… 前两篇博文中提到Development,QA,Staging,Production四个环境也说明了源代码的分支和四个环境的对应关系本篇博文聊一下怎么把源码自动化发布到对应的环境中。市面上主流的DevOpt工具都支持这些功能github,gitlab都有CICD功能当然如果源码服务器是自己搭建的也可以利用像Jenkins这类软件来实现CICD关于这些大众工具网上有很多教程序这里就不主要来分享了本例是用.net core实现一个极简的自动发布工具——《MyCICD》。说一下实现思路吧clone 或 pull分支代码publishrun是不是很简单上代码吧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/returnsstatic 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 namegitLibgit库/param/// param namesourceDir本地保存路径/param/// returns/returnsstatic 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 namesourceDir源码路径/param/// returns/returnsstatic 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/returnsstatic 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 namesourcePath源码路径/param/// param nameprojects项目集/param/// returns/returnsstatic string[] GetProjectsPath(string sourcePath, string[] projects){var paths new Liststring();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/returnsstatic int[] Run(){Console.WriteLine(开始运行);var sourcePath ConfigurationManager.AppSettings[SourcePath];var publishDir ${sourcePath}/publish;var proceddIDs new Listint();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 version1.0 encodingutf-8 ?
configurationappSettings !--git库相关git库路径clone后本地何存路径--add keyGitLib valuehttps://github.com/axzxs2001/Asp.NetCoreExperiment.git/add keySourcePath valuee:/test//!--dotnet发布相关要发布的项目--add keyPublishProject valueAspNetCoreEnvironment.csproj,WebError.csproj/ /appSettings
/configuration
这个例子很简单只支持在windows下运行同时run起来的应用和MyCICD是在一个进程中一但进程关闭run的服务也就掉了还有很多需要改进如果有兴趣可以完善比如可以跑大多个平台上linux,docker,mac下也可以把MyCICD和运行的服务分离进程间互不影响。