Node+Gitee WebHook實現小程序CI
發表時(shí)間:2021-1-5
發布人(rén):融晨科技
浏覽次數:92
原先我們需要(yào / yāo)用到(dào)shell腳本和(hé / huò)ide來(lái)切換分支和(hé / huò)上(shàng)傳代碼,使用CI後完全抛棄這(zhè)些步驟,達到(dào)合完PR直接上(shàng)傳到(dào)後台的(de)功能,減少了(le/liǎo)這(zhè)些細碎且無趣的(de)工作,釋放自己去做别的(de)事情。
項目路徑:github.com/chenerhong/…
因爲(wéi / wèi)我們公司目前使用的(de)是(shì)碼雲來(lái)托管代碼,所以(yǐ)這(zhè)裏我隻針對碼雲來(lái)進行講解。
我們想達到(dào)的(de)效果是(shì)合完PR到(dào)主分支(master)之(zhī)後,自動上(shàng)傳我們的(de)小程序代碼。
這(zhè)時(shí)候我們就(jiù)需要(yào / yāo)用到(dào)碼雲的(de)WebHooks功能,合并代碼之(zhī)後碼雲向我們的(de)服務器發起一個(gè)請求,服務器接收請求後執行上(shàng)傳代碼到(dào)後台的(de)動作
大(dà)概思路如下
這(zhè)時(shí)我們就(jiù)需要(yào / yāo)去配置碼雲的(de)webHooks了(le/liǎo)。
到(dào)我們的(de)項目内,點擊管理,左側有WebHooks菜單,點擊WebHooks出(chū)現以(yǐ)下樣式
然後進行如下操作:
- 在(zài)URL輸入框填入我們的(de)服務器接口地(dì / de)址,如:xxx.xxxx.com/upload
- 隻勾選Pull Request
- 點擊更新
點擊更新後跳到(dào)如下頁面,表示配置完成了(le/liǎo)
配置完WebHooks之(zhī)後,就(jiù)需要(yào / yāo)開發我們的(de)接口來(lái)接收WebHooks了(le/liǎo)。
我選擇的(de)服務端語言是(shì)Koa2,基礎的(de)服務和(hé / huò)路由我就(jiù)不(bù)詳細說(shuō)了(le/liǎo),大(dà)家自己去看文檔或者源碼喔。文章裏我就(jiù)說(shuō)一下接口的(de)内部邏輯。
具體開發前我們需要(yào / yāo)先看下微信提供的(de)CI文檔,有2點是(shì)需要(yào / yāo)我們去注意的(de)
- 密鑰:微信公衆号 -> 開發 -> 開發設置,下載代碼上(shàng)傳密鑰,放置到(dào)項目中,然後在(zài)調用CI時(shí)設置好privateKeyPath
- 白名單配置:微信公衆号 -> 開發 -> 開發設置,配置白名單(必須IP)
完成上(shàng)述步驟後就(jiù)開始根據我們之(zhī)前畫的(de)流程圖開始實現接口邏輯把!!
判斷是(shì)否是(shì)合并到(dào)master
值得一提的(de)是(shì)目前碼雲的(de)webHook的(de)推送數據格式是(shì)Request Payload,所以(yǐ)我們需要(yào / yāo)利用koa2-formidable插件對數據進行處理後就(jiù)能直接使用ctx.request.body獲取數據了(le/liǎo)
router.post('/api/upload', async ctx => {
const body = ctx.request.body
// 合并狀态并且合到(dào)master才會自動上(shàng)傳到(dào)後台
if (body.state === 'merged' && body.target_branch === 'master') {
...
}
}
複制代碼
是(shì)否存在(zài)項目
const xcxPath = path.join(process.cwd(), config[type].publicProject)
// 判斷是(shì)否存在(zài)xcx項目文件夾,沒有就(jiù)去clone,有就(jiù)pull最新代碼
if (fs.existsSync(xcxPath)) {
child_process.execSync('git pull', {
cwd: xcxPath
})
} else {
child_process.execSync(`git clone ${config[type].git}`, {
cwd: path.join(process.cwd(), config.publicRoot)
})
}
複制代碼
項目初始化和(hé / huò)上(shàng)傳
// 創建項目對象
const project = new ci.Project({
appid: config.wx.appid,
type: 'miniProgram',
projectPath: publicProject,
privateKeyPath: path.join(process.cwd(), config.publicRoot, '../wx.key'),
ignores: ['node_modules/**/*'],
})
const year = new Date().getFullYear() - 2000
const month = new Date().getMonth() + 1
const day = new Date().getDate()
// 根據年月日當版本号
const version = '2.5.' + year + (month < 10 ? '0' + month : month) + (day < 10 ? '0' + day : day);
// 上(shàng)傳
const previewResult = await ci.upload({
project,
version,
desc: body.title,
setting: {
es6: true,
minify: true,
autoPrefixWXSS: true,
minifyWXML: true,
minifyWXSS: true,
minifyJS: true
}
})
複制代碼
這(zhè)時(shí)候我們把我們的(de)代碼部署到(dào)服務器上(shàng)用PM2跑起來(lái)後,就(jiù)可以(yǐ)實現自動上(shàng)傳的(de)功能了(le/liǎo)!
但是(shì)!
上(shàng)傳完成我們是(shì)無感知的(de),所以(yǐ)也(yě)不(bù)知道(dào)什麽時(shí)候完成,這(zhè)是(shì)非常不(bù)友好的(de),那有什麽解決辦法那!
有!我們可以(yǐ)當上(shàng)傳開始和(hé / huò)完成之(zhī)後利用釘釘來(lái)通知我們,開始時(shí)釘釘通知我們開始上(shàng)傳,上(shàng)傳完成後通知我們上(shàng)傳完成,并将項目信息返回給我們,這(zhè)樣不(bù)完成了(le/liǎo)一個(gè)有反饋的(de)功能了(le/liǎo)嗎。
添加機器人(rén)之(zhī)後我們的(de)流程就(jiù)變成了(le/liǎo)這(zhè)樣
文檔:釘釘webHooks,碼雲webHook對釘釘的(de)支持,釘釘自定義機器人(rén)SDK
- 需要(yào / yāo)設置群機器人(rén)
- 群設置 -> 智能群助手 -> 添加機器人(rén) -> 自定義機器人(rén) -> 勾選安全設置加簽
- 使用access_token和(hé / huò)secret完成自定義機器人(rén)初始化
設置完這(zhè)些之(zhī)後我們我們在(zài)原先開始上(shàng)傳和(hé / huò)上(shàng)傳完成的(de)位置添加下面代碼,就(jiù)可以(yǐ)完成我們的(de)釘釘通知功能啦!!
釘釘初始化
const Robot = require("dingtalk-robot-sdk")
const robot = new Robot({
accessToken: config.robotAccessToken,
secret: config.robotSecret
});
const text = new Robot.Text('開始上(shàng)傳')
robot.send(text)
複制代碼
釘釘通知完成
const markdown = new Robot.Markdown()
.setTitle('上(shàng)傳完成!!!!')
.add(`### [上(shàng)傳完成](https://mp.weixin.qq.com)\n`)
.add(`1. version:${version}`)
.add(`2. size:${fullSize}`)
.add(`3. ${JSON.stringify(previewResult)}`)
robot.send(markdown)
作者:j果er
來(lái)源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出(chū)處。