随着公司的项目越来越多,测试版和正式版之间容易混淆,主要是前端是个粗心的小白(你说是吧?陈某惠),经常测试正式版无法正确的区分,导致运营中会出现各种各样的问题,为了解决此问题,突然想到了曾几何时micoya大佬透露的一些姿势,正好今天闲来无事准备来试试
配置 🔗
首先打开github,找到你的项目,点击Settings
然后新建一个webhook,填写您的api地址和密钥
Which events would you like to trigger this webhook?
选择Let me select individual events.
然后下拉选择
Pushes(Git push to a repository.)
完毕后点击 Add webhook
至此,完成了对github的webhook的配置
api接收 🔗
上述配置完成后,编写一个webapi来实现接收github的通知
[HttpPost]
[Route("/api/pull")]
public async Task<IActionResult> Post()
{
using var reader = new StreamReader(Request.Body);
var payload = await reader.ReadToEndAsync();
// 验证 GitHub 密钥
var signatureWithPrefix = Request.Headers["X-Hub-Signature-256"].ToString();
var computedSignature = ComputeSha256Hash(_gitHubSecret, payload);
if (!signatureWithPrefix.EndsWith(computedSignature))
{
return Unauthorized("Invalid signature");
}
// 解析 JSON 数据
var jsonDocument = JsonDocument.Parse(payload);
var refBranch = jsonDocument.RootElement.GetProperty("ref").GetString();
if (string.IsNullOrEmpty(refBranch))
{
return Ok("no ref");
}
//分支名称
var branche = refBranch.Split('/').Last();
//仓库名
var repositoryName = jsonDocument.RootElement.GetProperty("repository").GetProperty("name").GetString();
//克隆地址
var cloneUrl = jsonDocument.RootElement.GetProperty("repository").GetProperty("clone_url").GetString();
//私有化仓库需要在这里插入git账号和token,https:// 这里是8个长度
cloneUrl = cloneUrl.Insert(8, $"{_gitHubAccount}:{_gitHubToken}@");
//提交的消息
var commitMsg = jsonDocument.RootElement.GetProperty("head_commit").GetProperty("message").GetString();
//仅在测试版中开放
if (branche == "develop" || branche == "dev")
{
//创建文件夹
var path = $"/var/webapi/temp/{repositoryName}";
//目录存在则拉取更新
if (Directory.Exists(path))
{
//直接拉取更新
await RunCommand("git", $"pull origin {branche}", path);
}
else
{
//不存在则创建文件夹直接clone
await RunCommand("mkdir", $"-p {path}");
//拉取命令
var gitPullResult = await RunCommand("git", $"clone {cloneUrl} {path}");
}
//切换分支
var gitCheckoutResult = await RunCommand("git", $"switch {branche}", path);
// 运行 NPM 构建
var npmInstallResult = await RunCommand("npm", "install", path);
var npmBuildResult = await RunCommand("npm", "run build", path);
//删除原文件
await RunCommand("rm", "-r /var/webapi/GaoXinCashShop");
//编译后的文件覆盖
await RunCommand("mv", $"{path}/dist /var/webapi/GaoXinCashShop");
return Ok("Dev branch updated and built.");
}
return Ok("Push not on 'dev' branch, no action taken.");
}
private static string ComputeSha256Hash(string secret, string payload)
{
using var hmacSha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var hash = hmacSha256.ComputeHash(Encoding.UTF8.GetBytes(payload));
var builder = new StringBuilder();
foreach (var b in hash)
{
builder.AppendFormat("{0:x2}", b);
}
return builder.ToString();
}
private async Task<string> RunCommand(string command, string arguments, string workingDirectory = null)
{
using var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = command,
Arguments = arguments,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
WorkingDirectory = workingDirectory ?? Directory.GetCurrentDirectory()
}
};
process.Start();
var result = await process.StandardOutput.ReadToEndAsync();
process.WaitForExit();
return result;
}
上述代码需要自行修改,可以做多个项目的接收以及字典的配置
上述代码所展示的为vue2项目通过推送develop分支到github后自动实现git clone和npm构建以及覆盖更新的操作
如上代码仅供参考,推荐采用消息队列执行,否则github的推送会超时
请注意,上述代码由于采用执行的UseShellExecute为false,所以无法执行一些操作,例如包含*的,所以如果要执行一些复杂操作,要么采用UseShellExecute为true(会导致无法读取响应结果),要么自己编写代码完成
配合企业微信 🔗
git clone和npm构建完成后我们无法实时收到消息,为了解决此问题可以参考使用企业微信的群机器人推送功能
当git clone操作完成和npm编译操作完成后,可以实时推送消息到企业微信群中,这样更方便处理
提示 🔗
- 请自备一些工具,否则git无法clone
- 请自备一些工具,否则npm下载plugin会失败
什么?你不知道工具是什么?那还是别玩了!