Vincent Ko

VK's Blog

基于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 项目,然后安装所需依赖项。

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

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

创建自动化脚本#

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

主要功能模块#

设置 Express 应用#

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

// 文件路径: 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 操作。

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(`
      <h1>Update and Push Successful!</h1>
      <h2>Most Recent Commits:</h2>
      <pre>${recentCommits.stdout}</pre>
    `)
  } catch(error) {
    console.error(`Failed to perform update operations: ${error}`)
    res.status(500).send(`<pre>Error: ${error.stderr || error.stack}</pre>`)
  }

})

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

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

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

启动 Express 服务#

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

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

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

使用 PM2 进行守护进程管理#

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

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

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

总结#

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

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。