您當前位置>首頁 » 新聞資訊 » 小(xiǎo)程序相(xiàng)關 >
Node+Gitee WebHook實現(xiàn)小(xiǎo)程€↔γ序CI
發表時(shí)間(jiān):2021-1-5
發布人(rén):葵宇科(kē)技(jì)
浏覽次數(shù):97
原先我們需要(yào)用(yòng)到(dào)shell腳本和(hé)ide來(lái)切換π♣£¥分(fēn)支和(hé)上(shàng)傳代碼,使用(yòng)CI後完全抛棄這(zhè)些±(xiē)步驟,達到(dào)合完PR直接上(shàng)傳到(dào)後台的(de)功能(né ®®↔ng),減少(shǎo)了(le)這(zhè)些(xiē)δ§細碎且無趣的(de)工(gōng)作(zuò),釋放(fàng)自(zì)己≠♠去(qù)做(zuò)别的(de)事(shì)情。
項目路(lù)徑:github.com/chenerhon×±₹g/…
因為(wèi)我們公司目前使用(yòng)的(de)是(shì)碼雲來♥ ∏(lái)托管代碼,所以這(zhè)裡(lǐ)我隻針對(duì)→¥≠碼雲來(lái)進行(xíng)講解。
我們想達到(dào)的(de)效果是(shì)合完PR到(dào)主分(fēn™₹ )支(master)之後,自(zì)動上(shàng)傳我們的(de)小(xiǎo)程序代碼。
這(zhè)時(shí)候我們就(jiù)需要(yào)用(yòng)到(dàoγ≥)碼雲的(de)WebHooks功能(néng),合并代碼之後碼雲向我們的(£Ωπ de)服務器(qì)發起一(yī)個(gè)請(qǐng)求,服務器(qì)接收請(qǐ←>∏ng)求後執行(xíng)上(shàng)傳代碼到(dào)後台的¥σ(de)動作(zuò)
大(dà)概思路(lù)如(rú)下(xià)
這(zhè)時(shí)我們就(jiù)需要(yào)去(qù)配置碼雲的(de)webHoo≥ βks了(le)。
到(dào)我們的(de)項目內(nèi),點擊管理(lǐ),左側有(yǒu)Web ±εHooks菜單,點擊WebHooks出現(xiàn)以下(xià)樣式
然後進行(xíng)如(rú)下(xià)操作(zuò):
- 在URL輸入框填入我們的(de)服務器(qì)接口地(dì)址,如(rú):xxx.xxxx.→←¥com/upload
- 隻勾選Pull Request
- 點擊更新
點擊更新後跳(tiào)到(dào)如(rú)下(xià)頁×< •面,表示配置完成了(le)
配置完WebHooks之後,就(jiù)需要(yào)開(kāi)發我們的(d≥"e)接口來(lái)接收WebHooks了(le)。
我選擇的(de)服務端語言是(shì)Koa2,基礎的(de)服務和€♣≠÷(hé)路(lù)由我就(jiù)不(bù)詳細說(shu∑•ō)了(le),大(dà)家(jiā)自(zì)己去(qù)§÷看(kàn)文(wén)檔或者源碼喔。文(wén)章(zhāng)裡(l ∞ǐ)我就(jiù)說(shuō)一(yī)下(xià)接✔δ€÷口的(de)內(nèi)部邏輯。
具體(tǐ)開(kāi)發前我們需要(yào)先看(kàn ↑¶)下(xià)微(wēi)信提供的(de)CI文(wén)檔,有(yǒu)2點是(shì)需要®≠✔&(yào)我們去(qù)注意的(de)
- 密鑰:微(wēi)信公衆号 -> 開(kāi)發 ↓π<<-> 開(kāi)發設置,下(xià)載代碼上(shàng)傳密鑰,放(✔δfàng)置到(dào)項目中,然後在調用(yòng)CI時(shí)設置好(hǎo)¥≤±privateKeyPath
- 白(bái)名單配置:微(wēi)信公衆号 -> 開(kāi)發 ->✔↕→$; 開(kāi)發設置,配置白(bái)名單(必須IP)
完成上(shàng)述步驟後就(jiù)開(kāi)<∑>始根據我們之前畫(huà)的(de)流程圖開(kāi)始實現(xiàn)接口邏輯把!!
判斷是(shì)否是(shì)合并到(dào)master
值得(de)一(yī)提的(de)是(shì)目前碼± ©雲的(de)webHook的(de)推送數(shù)據✘®♦格式是(shì)Request Payload,所以我們需要(yào)×↑÷利用(yòng)koa2-formidable插件(jiàn)對(du✔ §ì)數(shù)據進行(xíng)處理(lǐ)後就(jiù)能(néng)直接使用(yòng)ct∑<λx.request.body獲取數(shù)據了(le)←
router.post('/api/upload', async ctx => {
const body = ctx.request.body
// 合并狀态并且合到(dào)master才會(huì)自✘£♥(zì)動上(shàng)傳到(dào)後台
if (body.state === 'merged' && body.target_branch === 'master') {
...
}
}
複制(zhì)代碼
是(shì)否存在項目
const xcxPath = path.join(process.Ω∏♣cwd(), config[type].publicProject)
// 判斷是(shì)否存在xcx項目文(wén)件(↑jiàn)夾,沒有(yǒu)就(jiù)去(qù)clone,有(yǒu)就(j§↑∏iù)pull最新代碼
if (fs.existsSync(xcxPath)) {
child_pro cess.execSync('git pull', {
cwd: xcxPath
})
} else {
child_process.execSync(`git clone ${config[type].git}`, {
cwd: path.join(process.cwd(), config.pubπ✘ ™licRoot)
})
}
複制(zhì)代碼
項目初始化(huà)和(hé)上(shàng)傳
// 創建項目對(duì)象
const project = new ci.Project({
appid: config.wx.appid,
type: 'miniProgram',
projectPath: publicProject,
privateKeyPath: path.join(process.cwd(), config.publ ®♦☆icRoot, '../wx.key'),
ignores: ['node_modules/**/*'],
})
const year = new Date().getFullYear() - 2000
const month = new Date().getMonth() + 1
const day = new Date().getDate()
// 根據年(nián)月(yuè)日(rì)當版本号
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ì)代碼
這(zhè)時(shí)候我們把我們的(de)代碼部署到(dào)服務器(qì)∑>上(shàng)用(yòng)PM2跑起來(lái)後,就(jiù)±£可(kě)以實現(xiàn)自(zì)動上(shàng× ≤)傳的(de)功能(néng)了(le)!
但(dàn)是(shì)!
上(shàng)傳完成我們是(shì)無感知(zhī)的(de)¶£•≤,所以也(yě)不(bù)知(zhī)道(dào)什(shén)麽時(shí)候完成,這(zhè÷♠&)是(shì)非常不(bù)友(yǒu)好(hǎo)的(de),那(nà)>β&有(yǒu)什(shén)麽解決辦法那(nà)!
有(yǒu)!我們可(kě)以當上(shàng)傳開(kāi)始和(hé)完成之後利 ∞•用(yòng)釘釘來(lái)通(tōng)知(zhī)我們,開(kāi)始時(₽×≥ shí)釘釘通(tōng)知(zhī)我們開(kāi)始上(shàng)傳,上(shàng) ♥ §傳完成後通(tōng)知(zhī)我們上(shàng)傳↕ε完成,并将項目信息返回給我們,這(zhè)樣不(bù)完成了(le)一(y↓φ®®ī)個(gè)有(yǒu)反饋的(de)功能(néng)了(le)嗎Ω€€↓(ma)。
添加機(jī)器(qì)人(rén)之後我們的(de)流←®程就(jiù)變成了(le)這(zhè)樣
文(wén)檔:釘釘webHooks,碼雲webHook對(duì)釘釘的(de)支持,釘釘自(zì)定義機(♥δ←∏jī)器(qì)人(rén)SDK
- 需要(yào)設置群機(jī)器(qì)人(rén)×♠
- 群設置 -> 智能(néng)群助手 -> 添加機(jī)器(< qì)人(rén) -> 自(zì)定義機(jī)器(qì)人(rén)α'≠ -> 勾選安全設置加簽
- 使用(yòng)access_token和(hé)secret完成自(zì)定義 ✔ 機(jī)器(qì)人(rén)初始化(huà)
設置完這(zhè)些(xiē)之後我們我們在原先開(kāi)始上(shàng)傳和(§≥♥✔hé)上(shàng)傳完成的(de)位置添加下(xià)面δΩ★ 代碼,就(jiù)可(kě)以完成我們的(de)釘釘通(tōng)知(zhī$≥₽)功能(néng)啦!!
釘釘初始化(huà)
const Robot = require("dingtalk-robot-sdk")
const robot = new Robot({
accessToken: config.robotAccessToken,
secret: config.robotSecret
});
const text = new Robot.Text('開(kāi)始上(shàng)傳')
robot.send(text)
複制(zhì)代碼
釘釘通(tōng)知(zhī)完成
const markdown = new Robot.Markdown()
.setTitle('上(shàng)傳完成!!!!')
.add(`### [上(shàng)傳完成](https://m' π>p.weixin.qq.com)\n`)
.add(`1. version:${version}`)
.add(`2. size:${fullSize}`)
.add(`3. ${JSON.stringify(previewResult)}`)
robot.send(markdown)
作(zuò)者:j果er
來(lái)源:掘金(jīn)
著作(zuò)權歸作(zuò)者所有(yǒu)。商業(yè)轉載請(qǐn ±g)聯系作(zuò)者獲得(de)授權,非商業(yè)轉載請(qǐng)注明(míng)出處σ±≈δ。