.Net C# 解放自己从部署服务开始( 类似 jenkins,等发布工具)
主要面对的环境是测试环境,你需要把服务整到测试环境去,但是,测试环境,没有自动化这一套,但是,你又不得不去干这件事情,主要是 ,这件事情是重复的,可以被程序替代的。
我做出来的时候,跟网友讨论,他们说可以用jenkins来部署啊,githook啥的来部署啊,第一么,我对它们稍微熟悉,第二么,我想用c#实现的服务来搞,加深自己对自动化发布这件事情的深入。
好了。现在说下他们的架构吧。
【新版本 脑图】

【老版本 脑图】

脑图也根据群友的沟通改了一版,大家可以说说哪种好,我可以尽量参考(简单化的框架设计的话)。
基本就是这个架构了
环境不用说,都是我们常见的一个环境。
架构么,
先从客户端开始讲:
客户端的职责就是按照我自己的一个配置情况,对其进行git 拉取代码,然后 VS生成代码,最后,发布到服务端
/// <summary>
/// 类型
/// </summary>
public enum ProjectType
{
/// <summary>
/// dotNet
/// </summary>
DotNet
}
这个下面是按照项目走的,这个就是dotnet项目。项目的类型已经固定。

这个是具体的类型需要干的事情

比如 dotnet 整个命令可能需要干这些事情.
为啥不直接用git pull呢,因为 git pull 是内部调用的其他的命令,导致 输出捕获不到。
不利于及时发现问题。
以下是具体任务的结构,ID 用来跟踪服务的处理情况,CMDName用于关联处理命令的具体前置任务,路径是用来作为工作目录过去执行命令的,服务信息是,如果这个服务需要启动,那么,可能有一个或者多个服务会被启动,那么它自己就会先关闭,然后,覆盖文件,然后,启动。
在覆盖文件的时候,有一条配置文件是不用覆盖甚至复制的。
最后,修改记录是否完成。用于客户端提示。

用到的压缩工具是.net 自带的 zipfile
方法如下:
public class ZipFileHelper
{
public static ZipFileHelper Instance = new ZipFileHelper();
public CompressType CompressType { get { return CompressType.System; } }
public bool CompressDirectory(string directoryName, string CompressFile, string password = "")
{
try
{
ZipFile.CreateFromDirectory(directoryName, CompressFile, CompressionLevel.Fastest, true);
return true;
}
catch (Exception)
{
}
return false;
}
public bool Decompression(string CompressFile, string targetAddress, string password = "")
{
try
{
ZipFile.ExtractToDirectory(CompressFile, targetAddress, true);
return true;
}
catch (Exception)
{
}
return false;
}
}
用来请求服务端的方法如下
using (var client = new HttpClient())
{
HttpResponseMessage response = client.GetAsync(url).Result;
if (response.IsSuccessStatusCode)
{
var result = response.Content.ReadAsStringAsync().Result;
return !string.IsNullOrEmpty(result);
}
}
using (var client = new HttpClient())
{
client.Timeout = new TimeSpan(0, 10, 0);
var multipartFormDataContent = new MultipartFormDataContent()
{
{
new ByteArrayContent(File.ReadAllBytes(R7zPath)), // 文件流
"files", // 对应 服务器 WebAPI 的传入参数
Path.GetFileName(R7zPath) // 上传的文件名称
}
};
HttpResponseMessage response = client.PostAsync(url, multipartFormDataContent).Result;
if (response.IsSuccessStatusCode)
{
var result = response.Content.ReadAsStringAsync().Result;
}
}
服务端的职责是:
收到客户端上传来的压缩文件,解压压缩文件,获取任务信息,根据任务来对内容进行,具体的操作。
接口大致的样子
[HttpPost]
public IActionResult Upload(List<IFormFile> files)
{
}
用 Process.GetProcessesByName(name) 来获取具体的进程,另外用 Process.MainModule.FileName 来判断是否与启动的exe地址一致。
另外一个重要的点是,在文件的保存上,IFormFile保存的时候,我这边经常会提示,被另外一个进程使用。
所以,我采用的方式是
//保存文件
var stream = formFile.OpenReadStream();
// 把 Stream 转换成 byte[]
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
// 设置当前流的位置为流的开始
stream.Seek(0, SeekOrigin.Begin);
// 把 byte[] 写入文件
FileStream fs = new(RFilePath, FileMode.Create);
BinaryWriter bw = new(fs);
bw.Write(bytes);
bw.Close();
fs.Close();
核心代码已经全部晒出来了。做出来应该不是啥子问题呦!
最后看下效果


最后,只花费了28秒,但是,然我手动操作,最少得 5-10分钟,才能操作一次,毕竟,打开远程服务器,拉代码,编译,复制项目到远程,开启和关闭相关服务,服务越多,越慢。眼花缭乱的。
所以,这还是很客观的,现在业务部分一声吼,我只需要双击,就搞定了。

浙公网安备 33010602011771号