jenkins-通过脚本触发构建触发器实现命令构建

256 阅读4分钟

背景

项目开发过程中,使用Jenkins进行代码自动化构建管理,这一定程度上已经解决了我们很大的问题,最原始的前端代码发布:要登录服务器,找到对应的目录,手动打包,然后再替换对应的包,这样十分繁琐,并且无法保证代码的版本。Jenkins就可以解决这一系列的繁琐操作,并且是开源的,开发人员可以获取开源项目,部署到内网服务器上,就低成本搭建了自动化构建平台。然后运维人员再进行相关的权限和发布配置,链接到我们的仓库地址,写好对应的发布脚本,就可以达到一键发布。大大提高了开发效率,也保证了代码版本的规范和实现开发过程的流水线管理。

但是使用的过程中,就会发现,还有一些重复的工作步骤的,比如我们需要不断地打开浏览器,登录Jenkins,然后点击发布按钮发布,Jenkins也是考虑到这一点,允许我们通过构建触发器一边开发一边可以触发构建,直接省略了打开浏览器=>登录=>找到对应的项目触发构建按钮等等一些列操作。

image.png 在这里,我使用的是脚本触发,我想要实现的效果是:当提交代码到远程后 运行命令 npm run curl可以默认发起Jenkins的sit、dev、uat环境的构建, 也可以选择去执行某个环境的构建,如命令npm run curl sit(仅构建sit),npm run curl sit uat(构建sit、uat),

实现步骤

  1. 在Jenkins,找到A项目各个环境的构建触发器,填写不同环境的身份验证令牌

image.png

image.png 按照提示拼接完整的URL,在Jenkins登录时,URL直接被浏览器访问也能触发构建,因此我们只要找到命令触发该链接执行就可以了。 2. 通过node的child_process模块exec函数去执行命令,简单了解一下:

`child_process`Node.js中的一个模块,用于创建和控制子进程。它提供了一组函数,可以在Node.js应用程序中执行外部命令、创建子进程,并与其进行通信。

`child_process`模块包含了四个主要的函数:

1.  `exec()`:用于执行一个shell命令,并返回其输出。它适用于执行简单的命令,但不适合处理大量输出数据。
1.  `spawn()`:启动一个子进程来执行指定的命令。它适用于执行复杂的命令,可以处理大量的输出数据。您可以通过事件处理程序来监听子进程的输出和错误。
1.  `fork()`:创建一个新的Node.js进程,并在该进程中执行指定的模块。它适用于创建多个Node.js进程,这些进程可以通过消息进行通信。
1.  `execFile()`:类似于`exec()`,但是直接执行可执行文件,而不是通过shell来执行。它适用于执行二进制文件或者不需要shell解析的命令。
  1. package.json配置执行命令,post-push.js是我们的执行脚本,放在项目根目录下
  "scripts": {
    "curl": "node post-push.js"
  },

post-push.js完整代码

/**
 * 自动化构建 sit、uat、dev 可执行命令 npm run curl
 *  默认触发三个构建环境sit、dev、uat
 * 如果可选构建,可传递参数,使用空格间隔,如npm run curl sit (仅构建sit)
 * npm run curl sit uat (仅构建sit和uat)
 */
const { exec } = require("child_process");
const jenkinsDomain = "http://XX.XX.XXX.XXX:XXX";
// Jenkins username 需修改成自己的Jenkins账号密码,本地修改,避免推远程,否则权限校验失败
const userName = "XXX";
// Jenkins password
const password = "XXXX";
// job url: token、url从Jenkins构建触发器身份验证令牌处获取,
const url = {
  dev_url: `${userName}:${password} ${jenkinsDomain}/job/dev-front/build?token=${dev对应令牌token}`,
  sit_url: `${userName}:${password} ${jenkinsDomain}/view/%E6%B5%8B%E8%AF%95/job/sit-front/build?token=?token=${sit对应令牌token}`,
  uat_url: `${userName}:${password} ${jenkinsDomain}/view/%E6%B5%8B%E8%AF%95/job/uat-front/build?token=?token=${dev对应令牌token}`,
};
let urlList = Object.values(url);
// 第一个元素是 Node.js 的可执行文件的完整路径,第二个元素是脚本文件的完整路径,后面的元素是命令行参数
const arg = process.argv.slice(2);
// 若可选构建,需重置urlList,并push进需要构建的
if (arg.length > 0) {
  urlList = [];
  for (const item of arg) {
    if (url[`${item}_url`]) {
      urlList.push(url[`${item}_url`]);
    }
  }
}
/**
 * 遍历构建数组,触发对应的url
 */
for (const item of urlList) {
  exec(`curl -u ${item}`, (error, stdout, stderr) => {
    if (error) {
      console.error(`执行错误: ${error}`);
      return;
    }
    console.error(`stderr: ${stderr}`);
  });
}

验证

image.png

去Jenkins查看,有执行记录: image.png

参考