前端 自动化
实践篇:源码上传,打包自动化和mongod定时备份

自动化部署是比较流行的技术,不同公司都有对自己实际场景的需求

本文通过git代码管理器的钩子hook,打包器vite钩子,oss远程上传及存储,以及shell脚本等,实现本地前后端代码的自动化部署和定时数据库的备份

本地开发git-hook推送

以往的测试阶段,修复的测试代码想上到测试分支,要么是命令行git merge,要么是ui图形工具替代git merge

用git-hook代替手动敲命令行,也可以实现从本地推到远程分支。在开发中的【提测】阶段非常实用

流程

1. 在本地拉取两个同样gitee源的文件夹:deploy_with_githook_dev 和 deploy_with_githook

2. 分别从远程切出test和dev分支

3. 在dev分支完成代码后,把往常的三步(git add,commit,push)变为两步:add+commit。

其中在commit阶段利用git-hook钩子函数post-commit完成:push:dev,origin:test被最新的dev分支merge 这两个流程:

# hook目录:/.git/hooks/post-commit

# !/bin/sh
# 在本地提交之后push,顺便merge到beta再push
# 适用于提测后的复测bug,不适用于开发,所以在开发阶段需要注释or改文件名以取消hook

# 获取分支名称
branch=`git branch --show-current`

# 先推
git push

# 当前目录deploy_with_githook_dev,进入另一个目录,属同一个gitee:origin源的项目
cd ../deploy_with_githook/


# 切换到test分支
git checkout test

# 拉取最新代码
git reset --hard
git pull

# 分支名作为变量被merge
git merge origin/$branch

# 推到gitee远程,完成同步
git push

之所以需要两份文件夹,是为了实际开发中,很有可能dev分支仍有未提交的代码,只保留一份文件夹可以用git stash暂存实现,但虽然可以加git stash实现,但也增加了复杂度。

另一处关键代码是: 如何在本目录记住当前准备汇入test分支的开发分支,用git branch --show-current实现(注意命令git branch --show-current 需要git 2.22版本以上才支持)

执行效果

可以看到几乎是同时推送到了远端的dev和test分支

前端打包后构建上传oss

对于静态化的项目,如何能在本地开发完就第一时间上传服务器?

这方面已经有插件可以完成,了解下大概的原理:

vite官方有关于插件的通用钩子说明:【 https://cn.vitejs.dev/guide/api-plugin.html#universal-hooks

closeBundle【关闭】,钩子在打包构建关闭时被调用

也就意味着在这个时候打包好的文件已经存在,剩下的就是获取文件,调用ali-oss上传即可:

export default function vitePluginAliOss (options) {
  return {
    name: 'vite-plugin-ali-oss',
    enforce: 'post',
    apply: 'build', // 表明只有build过程调用
    closeBundle: { // 关闭钩子
      sequential: true,
      order: 'post',
      async handler () {
        // 此处实现ali-oss上传
      }
    }
  }
}

// vite.config.js
export default defineConfig({
  plugins: [
      vue(), 
      vitePluginAliOss({
          region: 'oss-cn-beijing',
          accessKeyId: '',
          accessKeySecret: '',
          bucket: 'xiaweiss',
      })
  ]
})

1. npm run build 打包

2. 走vite钩子上传oss,前端完成部署

执行结果

服务端通过gitee-webhook部署

前端项目可以上传静态文件,后端代码也可以借助git实现快速部署

关键技术是:享用了gitee中的webhook,可以实现每次提交master代码后,服务器上的代码也跟随更新

码云配置:

express-api:


import { spawn } from 'child_process';

app.post("/pull-and-restart", (req, res) => {
    // 注册接收到码云的post请求,执行pull的shell,返回done
    run_cmd('sh', ['./src/server/shell/pull-and-restart.sh'], function (text) { 
        res.send("done");
    });
});
function run_cmd(cmd, args, callback = () => { }) {
  var child = spawn(cmd, args);
  child.on('error', (err) => {
    console.log('Failed to start child process 1.', err);
  });
  child.on('close', (code) => {
    console.log('子进程退出码', code);
  });
  var resp = "";
  child.stdout.on('data', function (buffer) {
    resp += buffer.toString();
  });
  child.stdout.on('end', function () { callback(resp) });
  child.stderr.on('data', (data) => {
    console.log(`stderr:${data}`)
  })
}

pull-and-restart.sh文件:

WEB_PATH='./'
cd $WEB_PATH
git pull origin master
# pm2 restart 0
# 为了简单演示,命令行直接启动了3003端口, 实际为pm2 restart 0

基本流程

1. 本地开发完成,git commit

2. 码云发出web-hooks

3. express-api接收到拉取最新代码

4. 走shell拉取最新代码

5. 重启, 后端部署完成

在服务器打开项目,测试本地push的效果:

码云的webhooks也收到了服务器的返回【done】

往设计模式说,这个过程有两个订阅

1是码云监听具体项目的ssh端口有无上传git push,实现【已知用户上传代码】的订阅

2是api服务器监听码云的webhook接口调用(http-post),api实现【码云已收到最新代码】的订阅

mongodb定时备份

笔者没有遇到过删库或者误操作之前,备份的意识是薄弱的

完善的建站维护里,一定有数据备份的过程。mongodb的定时备份源自掘金博客,基本是按照的博主的流程走,但遇到了个环境不一致的问题

流程

1. 利用mongodump工具实现数据库导出备份:tar-mdb.sh

# shell
backUpFolder=/usr/local/product/mdb-tools/bin/
# 备份文件名带上日期信息,避免重名,并方便识别
dateNow=`date +%Y_%m_%d_%H%M`
backFileName=db_blog_$dateNow
# 去到备份目录,把blog数据库备份到backup文件
cd $backUpFolder
mkdir -p $backFileName
./mongodump  -d blog -o $backFileName
# 进入backup文件夹,把blog库文件打包成blog.tar
tar -zcvf $backFileName.tar.gz $backFileName
# 删掉源文件,留下tar就行
rm -rf $backFileName
# 传递node环境变量,执行上传的js
# export NODE_ENV=$backFileName@$backUpFolder && node ./md2oss.js
# 定时任务里的环境和bin/sh的环境并不一致:如果是命令行窗口,以上语句可行;而在crontab环境则用绝对路径
export NODE_ENV=$backFileName@$backUpFolder && /usr/local/product/nvm/nvm-0.39.1/versions/node/v16.13.2/bin/node /usr/local/product/node-blog/shell/md2oss.js

2. shell设置node变量为文件路径后,执行node包:ali-oss上传文件:md2oss.js

const OSS = require('ali-oss');

// 初始化OSS客户端。请将以下参数替换为您自己的配置信息。
const client = new OSS({
    region: 'oss-cn-guangzhou',
    accessKeyId: '',
    accessKeySecret: '',
    bucket: '',
  });

// 从环境变量获取需要备份的文件名和目录
// 这么写,是为了方便在 shell 脚本中执行
var params = process.env.NODE_ENV.split("@");
var fileName = params[0] + ".tar.gz";
var localFile = params[1]  + fileName;
async function uploadAndDownloadFile() {
  try {
    // 上传文件到OSS,'fileName'是OSS中的文件名,'localfile'是本地文件的路径。
    const uploadResult = await client.put(fileName, localFile);
    console.log('上传成功:', uploadResult);
    // 从OSS下载文件以验证上传成功。
  } catch (error) {
    console.error('发生错误:', error);
    // 在此处添加错误处理逻辑。
  }
}
uploadAndDownloadFile();

3. 增加定时shell,执行每日2点备份并上传:dingshi.sh

# 设置定时任务,执行命令会进去一个配置文件中去
crontab -e 
# 每天两点定时备份 数据库
00 02 ** ** ** sh /usr/local/product/node-blog/shell/tar-mdb.sh

crontab 的环境问题:简单来说,定时任务里的环境和bin/sh的环境并不一致,所以执行sh也得是绝对路径

执行结果

源码

本文涉及的源码: https://gitee.com/wxwxnzm/deploy_with_githook


日期:2024-03-21 17:18:18 | 阅读:83 | 评论:0