TIP
gitee部署网站自动更新是giteePagePro的功能,需要付费,怎么来实现自动更新?
这是部署在服务器的,也可以部署在本地来实现自动更新giteePage本地版。
- node^16+
- centos8
利用puppeteer实现, 配合webhook
实现。如果部署在自己服务器可看利用webhook实现自动化部署前端或node项目
安装必要包
bash
mkdir webhook
cd webhook
yarn init
yarn add git-webhook-handler puppeteer
编写js
bash
vim updateGiteePage.js
js
const puppeteer = require('puppeteer');
/**
* @param usename gitee用户名
* @param password gitee密码
* @param giteePageUrl giteePage更新的那个页面
*/
async function updateGiteePage(username, password, giteePageUrl) {
const browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
const page = await browser.newPage();
await page.goto('https://gitee.com/login');
// 1. 选中账号控件
let accountElements = await page.$x('//*[@id="user_login"]') // 此处使用 xpath 寻找控件,下同
// 2. 填入账号
await accountElements[0].type(username)
// 3. 选中密码控件
let pwdElements = await page.$x('//*[@id="user_password"]')
// 4. 填入密码
await pwdElements[0].type(password)
// 5. 点击登录
let loginButtons = await page.$x('//*[@id="new_user"]/div/div/div/div[4]/input')
await loginButtons[0].click()
// 6. 等待登录成功
await page.waitForTimeout(3000)
// 前往giteePage的页面
await page.goto(giteePageUrl);
console.log('已到达pages页面')
await page.waitForTimeout(1000)
// 7. 点击更新按钮,并弹出确认弹窗
let updateButtons = await page.$x('//form[@id="pages-branch"]/div[6]')
// 7.1. 监听步骤 7 中触发的确认弹框,并点击确认
await page.on('dialog', async dialog => {
console.log('更新')
dialog.accept();
})
await updateButtons[0].click()
// 8. 轮询并确认是否更新完毕
while (true) {
await page.waitForTimeout(2000)
try {
// 8.1 获取更新状态标签
deploying = await page.$x('//*[@id="pages_deploying"]')
if (deploying.length > 0) {
console.log('更新中...')
} else {
console.log('更新完毕')
break;
}
} catch (error) {
break;
}
}
await page.waitForTimeout(500);
// 10.更新完毕,关闭浏览器
browser.close();
}
module.exports = updateGiteePage;
bash
vim index.js
js
// index.js
const http = require('http')
const createHandler = require('git-webhook-handler')
const updateGiteePage = require('./updateGiteePage');
// secret 自行填写 随机字符串
const handler = createHandler({ path: '/webhook', secret: '12345678' })
// gitee 用户名 密码
const username = '用户名';
const password = '密码';
// giteePage仓库 更新的那个页面路径
// 如:https://gitee.com/wangshiting/wangshiting/pages
const giteePageUrl = 'gitee page url';
handler.on('error', function (err) {
console.error('Error:', err.message);
})
handler.on('push', function (event) {
console.log('Received a push event for %s to %s',
event.payload.repository.name,
event.payload.ref,
event.payload.head_commit.message);
var message = event.payload.head_commit.message;
// 如果commit message中包含[ci-build]才构建项目,避免每次push都来build
// 条件可自行修改
if(/\[ci\-build\]/g.test(message)) {
// update
updateGiteePage(username, password, giteePageUrl);
} else {
console.log(/\[ci\-build\]/g.test(message));
}
})
// 端口8688 自行修改
http.createServer(function (req, res) {
handler(req, res, function (err) {
res.statusCode = 404;
res.end('no such location');
})
}).listen(8688);
使用pm2启动webhook
bash
pm2 start /home/projects/webhook/index.js --name webhook
gitee添加webhook
注意
- 可以向不用pm2启动,直接用node启动先测试下
- 只有commit message中包含
[ci-build]
才构建项目 - 报错缺少包,查看缺包
- 一定要微信关注gitee并绑定账号,不然会需要短信验证码
监听多个webhook
利用仓库名做区分,这次这个执行shell命令
js
const http = require('http')
const spawn = require('child_process').spawn;
const createHandler = require('git-webhook-handler')
const updateGiteePage = require('./updateGiteePage');
function runCommand( cmd, args, callback ) {
var child = spawn( cmd, args )
var response = ''
child.stdout.on('data', function( buffer ){ response += buffer.toString(); })
child.stdout.on('end', function(){ callback( response ) })
}
// secret 自行填写 随机字符串
const handler = createHandler({ path: '/webhook', secret: 'xxx' });
// gitee 用户名 密码
const username = 'xxx';
const password = 'xxx';
// giteePage仓库 更新的那个页面路径
const giteePageUrl = ''; // https://gitee.com/wangshiting/wangshiting/pages
// 端口8688 自行修改
http.createServer(function (req, res) {
handler(req, res, function (err) {
res.statusCode = 404;
res.end('no such location');
})
}).listen(8688);
handler.on('error', function (err) {
console.error('Error:', err.message);
})
handler.on('push', function (event) {
console.log('Received a push event for %s to %s',
event.payload.repository.name,
event.payload.ref,
event.payload.head_commit.message);
var message = event.payload.head_commit.message;
// 如果commit message中包含[ci-build]才构建项目,避免每次push都来build
if(/\[ci\-build\]/g.test(message)) {
// update
switch(event.payload.repository.name) {
case 'xxx':
updateGiteePage(username, password, giteePageUrl);
break;
case 'xxxx':
runCommand('sh',['./xxx.sh'], function(res){});
break;
default:;
}
} else {
console.log(/\[ci\-build\]/g.test(message));
}
});
sh
#!/bin/bash
# 进入项目目录
echo '进入项目根目录>>>>'
cd /home/projects/xxx
# 拉取最新代码
echo '拉取最新代码>>>>'
git pull
# 重启pm2
pm2 restart xxx
echo '部署完成'