基于Node.js 与 PM2 实现 Git 操作流程自动化

背景

因为仓库迁移，流水线权限问题，导致流水线所用仓库无法直接在页面提 PR。 所以，合作方的同学修改涉及到 SaaS 后端代码需要发布，每次都要前端在本地进行一次代码合并，非常的繁琐和低效，因为目前每次拉取的仓库和分支是固定的，所以想到用 Node 写一个脚本，通过调用接口实现代码的自动拉取。

技术栈选择

由于目前的需求非常简单，就是简单的同步，实际就是以下命令行的运行：

git checkout dev

git pull --no-rebase

git pull bkop dev_databus --no-rebase

git push
基于此，主要采取了以下几个关键技术：

Node.js: 作为服务端运行的 JavaScript 运行时环境。

Express: 一个快速、无开箱即用的 Web 应用框架，为我们的 API 服务提供支撑。

Child Process: 用于执行 shell 命令。

PM2: 一个具有内建负载均衡功能的 Node 应用的进程管理器。

解决方案概述

目录结构与依赖安装

首先创建项目目录，并在其中初始化一个新的 npm 项目，然后安装所需依赖项。

Copy
mkdir git-auto-pilot && cd $_
npm init -y
npm install express child-process-promise

这里使用了 child-process-promise 库来替代原生的 exec 函数，以提高错误处理的优雅性，并且支持 Promise 语法。

创建自动化脚本

接下来是实现自动化逻辑的核心部分 —— 编写一个简单的 Express 应用程序，并通过 HTTP 接口触发一系列 Git 操作。

主要功能模块

设置 Express 应用

引入所需的模块开始，并设置基本的 Express 应用。

Copy
// 文件路径: index.js
const express = require('express')
const cp = require('child-process-promise')
const path = require('path')

const app = express()
const directory = 'xxx' // 文件路径

更新操作的 GET 路由

定义 /update 路由来执行所有的 Git 操作。

Copy
app.get('/update', async (req, res) => {
try {
await executeGitCommand('checkout dev')
await executeGitCommand('pull --no-rebase')
await executeGitCommand('pull bkop dev_databus --no-rebase')
await executeGitCommand('push')

const recentCommits = await executeGitCommand('log -n 5 --pretty=format:"%h %s"')

res.send(`
Update and Push Successful!
Most Recent Commits:
${recentCommits.stdout}
`)
} catch(error) {
console.error(`Failed to perform update operations: ${error}`)
res.status(500).send(` Error: ${error.stderr || error.stack} `)
}

})

function executeGitCommand(command) {
const fullCommand = `git ${command}`
console.log(`Executing command: ${fullCommand} in ${directory}`)

return cp.exec(fullCommand, {cwd: directory})
}

在这个路由中，将 git 的操作按顺序执行，并在每个命令中都进行了异常捕获以确保程序的健壮性。

启动 Express 服务

最后一步是启动应用监听端口。

Copy
const PORT = process.env.PORT || 30035;

app.listen(PORT, () =>
console.log(`Server is running at http://localhost:${PORT}/`)
);

使用 PM2 进行守护进程管理

为了让应用程序能够在后台稳定运行，使用 PM2 来管理。这样，就不用必须保持终端的开启

Copy
pm2 start index.js --name "git-auto-pilot"

现在，即使关闭终端或者重启机器，这个服务也会被 PM2 自动复活。

总结

用 Node 和 PM2 的组合，可以写很多简单、实用的自动化脚本。目前这个脚本还无法处理遇到冲突的情况，但是足以解决我大部分问题，节省了很多去手动合并代码的问题。