github/githook配置前端自動化部署

前言

最早期方式: 前端寫好代碼之後本地構建, 通過服務器xftp或ftp把文件上傳到服務器進行更新

使用Git後: 服務器通過git clone的項目, 在項目的根目錄執行 git pull origin [branch] 拉去倉庫中最新的代碼

自動化部署: 通過配置WebHook及服務器後: 項目打包完成提交到代碼庫中, 服務器自動拉去git倉庫中最新的代碼

實現原理:

在github配置webhook的地方填寫服務端的url, 每次push代碼到github上, github都會向webhook中的url發送一條請求
服務端接收到請求後, 經過驗證後執行本地的bash腳本, 腳本中編寫從github拉去代碼的命令。

使用環境: Centos7.*, Node, Git
代碼庫平臺: Gitee / Github
Tips: 不同的操作環境可以進行不同的配置, 都可以實現
複製代碼流程說明

一. 配置github項目中的WebHook
二. 配置服務器, 增加Node項目, 運行項目

一. 配置WebHook
1.1 進入到代碼庫配置webhook界面

這裏以github爲例

登錄github -> 進入到repository中 -> 找到設置 -> 進入webhook

在這裏插入圖片描述
這是已經配置好的webhook

點擊新增webhook
在這裏插入圖片描述
現在github中的webhook已經配置成功了, 接下來配置服務器
二. 配置服務器
配置環境
下載git, Node環境
創建一個Node項目, 最好保存到代碼庫中
可以參考web-hook,這是一個服務端Node項目demo
使用Node編寫自動化部署腳本
參考web-hook

  1. 創建server.js監聽一個端口
    server.js
const http = require('http') // http模塊
const { spawn } = require('child_process') // 子進程, 用來執行腳本
const { PORT, SECRET } = require('./src/config') // 配置文件
const { sign } = require('./src/utils') // 工具文件
const { resultString } = require('./src/resModel') // 服務端返回JSON

const server = http.createServer((req, res) => {
  // 打印進來的請求
  console.log(`--- ${req.method} --- ${req.url} ---`)
  // 設置header爲json格式
  res.setHeader('Content-Type', 'application/json')

  if (req.method === 'POST' && req.url === '/webhook') {
    // post /webhook 都爲github發來的請求
    console.log('--- 命中webhook ---')
    // 獲取body
    let buffers = []
    req.on('data', buffer => {
      buffers.push(buffer)
    })
    req.on('end', () => {
      let body = Buffer.concat(buffers)
      // 獲取header中event的字段, github 爲push, gitee爲 Push Hook
      let event = req.headers['x-github-event'] || req.headers['x-gitee-event']
      console.log(`--- Event 名字: ${event}  ---`)
      if (req.headers['user-agent'] === 'git-oschina-hook') {
        // gitee
        console.log('--- Gitee 平臺 ---')
        // SECRET是在config.js中配置了
        if (req.headers['x-gitee-token'] === SECRET) {
          if (event === 'Push Hook') {
            console.log('--- push 任務命中 ---')
            let payload = JSON.parse(body)
            console.log(
              `--- 任務名稱: ${payload.repository.name}, 路徑: ${payload.repository.path} ---`
            )
            // 開啓子進程執行對應的腳本
            // payload.repository.path 是gitee/github傳來的repo的路徑
            // 通過path的值執行sh目錄下對應的腳本
            // 比如項目名字叫web_hook path的值就是web_hook
            // 執行的腳本就是./sh/web_hook.sh
            let child = spawn('sh', [`./sh/${payload.repository.path}.sh`])
            // 接收子進程傳來的數據
            let buffers = []
            child.stdout.on('data', buffer => {
              console.log(`--- 接受data ${buffer.toString()} ---`)
              buffers.push(buffer)
            })
            child.stdout.on('end', () => {
              let log = Buffer.concat(buffers)
              console.log(log.toString())
              console.log('自動化拉取完畢')
            })
          }
          // 返回的json, 配置在./src/resModel中
          res.end(resultString('success', 0))
        } else {
          // 其他的請求返回不允許
          return res.end(resultString('Not Allowed', 1))
        }
      } else {
        // github
        // 基本和上面的gitee一樣, 多一個校驗身份的步驟
        console.log('--- Github 平臺 ---')
        let signature = req.headers['x-hub-signature']
        // sign 方法配置在utils.js中
        if (signature !== sign(body, SECRET)) {
          return res.end(resultString('Not Allowed', 1))
        }
        if (event === 'push') {
          console.log('--- push 任務命中 ---')
          let payload = JSON.parse(body)
          console.log(payload.repository.name)
          let child = spawn('sh', [`./sh/${payload.repository.name}.sh`])
          let buffers = []
          child.stdout.on('data', buffer => {
            buffers.push(buffer)
          })
          child.stdout.on('end', () => {
            let log = Buffer.concat(buffers)
            console.log(log.toString())
            console.log('自動化拉取完畢')
          })
        }
        res.end(resultString('success', 0))
      }
    })
  }
  res.end(resultString('Not Found', 1))
})

// 監聽端口, PORT配置在config.js中
server.listen(PORT, () => {
  console.log(`web-hook listen on http://localhost:${PORT}`)
})

Tips: 接收github發送來的post參數: Webhooks | GitHub Developer Guide

建議看gitee平臺的說明(中文的, 參數差不多) Gitee

  1. 編寫sh文件
    ./sh/*.sh
#!/bin/bash
WORK_PATH="/home/wwwroot/tools/vue-back"
echo "------ 進入項目目錄 ------"
cd $WORK_PATH
echo "------ 已進項目目錄 ------"
echo "------ 開始清理代碼 防止衝突 ------"
git reset --hard origin/master
git clean -f
echo "------ 清理代碼完畢 ------"
echo "------ 拉取master分支代碼 ------"
git pull origin master
echo "------ vue-back 持續集成完畢 ------"

  1. 部署到服務器
    把寫好的這個Node項目部署到服務器
    阿里雲服務器需要手動配置開放的自定義端口號
    Node項目建議使用pm2

自動部署效果圖:
在這裏插入圖片描述
轉自https://juejin.im/post/5d9fee456fb9a04e3348c5ad

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章