前端多项目自动构建

Webhook 允许我们通过在Github.com订阅事件后构建后或者安装Github应用。当其中之一的事件被触发时,我们可以发送HTTP POST请求到webhook的配置URL。Webhook可以用作升级一个issue追踪,触发CI构建,升级一个后端镜像,或者甚至是部署你的生产服务器。只有想不到,没有做不到。

这里有一个常见的例子:你到github上。有一个用于他们代码POST请求webhook的文本框。你输入一个URL。现在当你上传你的代码到github上时,github将会通过HTTP POST的方法请求你所选择的包含详细信息的URL。没有更简单的方法以便与任意Web服务进行开放式集成。

作为国内的github——gitee.com,当然也是支持webhooks的。 gitee webhooks文档

基础支持

  1. 需要一台外网能访问的服务器
  2. 需要项目仓库的管理员权限

对于第一点来说,由于我这边是用公司的测试服务器,对外只开放了443端口,只能在443端口配置nginx,转发/webhoos请求到本地webhooks端口。

   location ^~ /webhooks {
        proxy_pass http://localhost:8080;
   }

webhooks配置

按照gitee文档配置好webhooks,服务器上需要起一个Node服务,监听8080端口 这里直接用了gitee码云使用webhook这篇文章里的代码

var http = require('http')  
var createHandler = require('gitee-webhook-handler')  
var handler = createHandler({ path: '/webhooks', secret: '123456' })// post 所需要用到的秘钥

function run_cmd(cmd, args, callback) {  
  var spawn = require('child_process').spawn;
  var child = spawn(cmd, args);
  var resp = "";
  child.stdout.on('data', function(buffer) { resp += buffer.toString(); });
  child.stdout.on('end', function() { callback (resp) });
}
handler.on('error', function (err) {  
  console.error('Error:', err.message)
})
handler.on('Push Hook', function (event) {  // 这个地方就是GitHub 和 Gitee 不一样的地方,需要注意  
        if (event.payload.ref === 'refs/heads/deploy') {
        run_cmd('bash', ['./deploy.sh', 'deploy', event.payload.repository.path], function(text){ console.log(text) });// 需要执行的脚本位置
        }
})

try {  
  http.createServer(function (req, res) {
    handler(req, res, function (err) {
      res.statusCode = 404
      res.end('no such location')
    })
  }).listen(8089) // 服务监听的端口,可以自行修改
}catch(err){
  console.error('Error:', err.message)
}

可以看到,这里我是使用特定分支deploy来作为是否自动构建的判断。

另外使用spawn命令时,args是以数组形式,例如直接执行shell脚本命令是

 ./deploy.sh deploy my-app

使用spwan时要这样

 spwan('bash', ['./deploy.sh', 'deploy', 'my-app'])

由于是多项目配置webhooks,所以这里路径是通过仓库信息里的event.payload.repository.path来区分的

构建脚本

由于是在测试服务器上自动构建,webhooks服务只是监听仓库的变化,构建是要自己编写脚本来进行构建的

deploy.sh

#!/bin/bash

BASE_PATH="/www"

exec 1>$BASE_PATH/webhooks/$2.log 2>&1

cd $BASE_PATH/$2

branch=$(git branch | grep $1)

git pull

if [[ -n "$branch" ]]; then  
        # 切换到构建分支
  git checkout deploy
else  
  git checkout -b deploy origin/deploy
fi

# 拉取最新代码
git pull  
# 构建
npm run build  

判断当前是否在deploy分支上,不在就切换过去

以上,服务器端全部Ok,剩下的就是项目中的配置了

项目发布命令

在项目中新增一个publish.sh

#!/bin/bash

set -e

function build_deploy() {  
    if [[ -n "$(git status --porcelain)" ]]; then
        echo "Working tree *NOT* clean. Please stash/commit your changes before any operations."
        exit 1
    fi

    current_branch="$(git symbolic-ref --short -q HEAD)"

    if [[ -n "$(git rev-parse --verify --quiet deploy)" ]]; then
        git branch -D deploy
    fi

    git checkout -b deploy

    git push -f origin deploy:deploy

    git checkout $current_branch

    git branch -D deploy

}

build_deploy [email protected]

在package.json中的scripts中新增一个命令

    "deploy": "cross-env scripts/bash/publish.sh",

cross-env这个是针对于团队中使用windows开发的

大概思路就是,发布时,会判断当前分支是否有变动,没有的话就从当前分支切一个本地deploy分支,然后强推到远程deploy分支,再切换回去,删除本地deploy分支

然后webhooks会监听到分支的Push,判断分支为deploy,执行deploy.sh

完工。

参考:

  1. gitee码云使用webhook
  2. Webhooks在API世界中的角色
  3. Webhook到底是个啥?