尽量用代码释放双手🙌🏻

563 阅读4分钟

前言

我司之前使用的仓库工具是Gogs,并且很久都没有更新过,最近经过讨论之后决定迁移到gitlab。gitlab对很多同学来说应该是老朋友了,这里也不展开说两者的对比什么的。

老夫虽然纵横职场几年,但是这船只在水面上划动之理还是掌握的不好;这不,一百多个仓库的迁移任务交给了我,想想都知道这就是一个没有难度,只需做重复动作的任务。

话不多说,赶紧开始吧。

工作分析

一个仓库的迁移,我们前端只要关心以下步骤

  • gitlab中预先按照产品分好群组
  • 新建仓库-从url中导入-填写各种基础信息
  • 配置CI/CD
  • 配置好仓库的分支(保护分支、删除无用分支等)主要是以前没有规范好

而上面的步骤,都是重复的操作,都在gitlab网页中操作。虽然我有想过用油猴做点什么,但最终还是没想什么可以做

而唯一有想法操作的,只有生成CI/CD配置文件的这个操作。配置过CI/CD的同学应该知道,每个项目得有一个对应的文件,而配置内容的骨架是一样的,不同的就是

  • 打包命令
  • 分支情况
  • 服务器地址
  • runner(配置文件中的tags)

先放上一个例子给大家看看

 variables:
   GIT_STRATEGY: clone
 
 stages:
   - deploy
 
 deploy:
   stage: deploy
   tags:
     - node-14
   script:
     - npm install --unsafe-perm=true --allow-root
     - rm -rf ./dist
     - >
       if [ "$CI_BUILD_REF_NAME" == "test" ]; then
         echo 'test branch'
         yarn build:maintest
         scp -r ./dist/* 测试环境服务器地址
       elif [ "$CI_BUILD_REF_NAME" == "dev" ]; then
         echo 'dev branch'
         yarn build:test
         scp -r ./dist/* 开发环境服务器地址
       fi
   except:
     - master
 

只要配置好这些,那么我们push代码到仓库后就会自动构建流水。我们的服务端还实现了企微的群机器人通知,不过我个人觉得太烦了,就没有配置。

上面的这个配置文件,如果我们人工去做的话,我要搞一百多个文件,就算是粘贴复制也顶不住啊😫。所以呢,我想到了用nodejs生成

node生成yml配置文件

那又让我们分析一下用node怎么去做这个事情

  • 写好生成代码的模板,找出变量
  • 把上面的需要的变量用一个excel收集起来
  • 把收集好的数据进行处理,生成文件

一看这么多活,我怎么可能低声忍气的一个人默默的完成呢,于是我找组长要人,把第二点这个只需要劳动力的活交给他😂估计这个同事心里一万句骂我的话。我这么帅,肯定是负责写node代码的呀😎。

我的收集表长这样

image-20220510173946032

其中黄色的部分得叫运维的同事填写,因为我们前端仔是不知道这些的

这个枯燥的话就让他们先干着吧,我们来看看node的代码

吐槽

开始之前不得不吐槽一下这个shell语法和yaml语法,非常严格敏感,而且报错都是模棱两可的。当然,有我菜的原因

node代码

完整的代码-仓库地址

具体想体验的同学,点击上面的网址去玩玩吧

配置文件模板

 function getContent(item) {
   return `variables:
   GIT_STRATEGY: clone
 ​
 stages:
   - deploy
 ​
 deploy:
   stage: deploy
   tags:
     - ${item.runner}
   script:
     - npm install --unsafe-perm=true --allow-root
     - rm -rf ./dist
     - >${item.测试服务器路径 ? `\n      if [ "$CI_BUILD_REF_NAME" == "test" ]; then
         echo 'test branch'
         ${item.测试环境自定义命令 || 'npm run build:test'}
         scp -r ./dist/* ${item.测试服务器路径}${item.开发服务器路径 ? '' : '\n      fi'}` : ''}${item.开发服务器路径 ? `${item.测试服务器路径 ? '\n      elif' : '\n      if'} [ "$CI_BUILD_REF_NAME" == "dev" ]; then
         echo 'dev branch'
         ${item.开发环境自定义命令 || 'npm run build:dev'}
         scp -r ./dist/* ${item.开发服务器路径}
       fi` : ''}${item.机器人地址 ? `\n    - curl ${item.机器人地址}` : ''}
   except:
     - master
 `
 }

是不是感觉一团乱,压根就不想看,没办法,还记得上面我吐槽yaml的语法吗,他对缩进非常严格;script中的shell代码也是如此,我也因此踩了很久的坑,因为配置有没有错误,跑流水才知道。

这个函数做的事情就是将传进来的数据对应的插入位置,并返回配置文件的内容

测试环境默认的打包命令是npm run build:test,开发环境默认的打包命令是npm run build:dev

关键代码

 const fs = require("fs");
 const data = require("./dataCI");
 const child_process = require("child_process");
 const json2xls = require("json2xls");
 ​
 ​
 const newDirName = '生成好的配置文件';
 const configList = []
 // 删除文件夹
 child_process.exec(`rm -rf ./${newDirName}`, () => {
   fs.mkdir(`./${newDirName}`, () => {
     const groups = [... new Set(data.map(item => item.群组名))]
     // 按群组生成文件夹
     groups.forEach(item => fs.mkdirSync(`./${newDirName}/${item}`))
     
     data.forEach(item => {
       const ymlPath = `./${newDirName}/${item.群组名}/.${item.项目名称}-gitlab-ci.yml`
       const ymlName = `${item.群组名}/.${item.项目名称}-gitlab-ci.yml`
       fs.writeFile(ymlPath, getContent(item), 'utf-8', (error) => {
         if (error) console.log(error)
       })
       configList.push({
         '项目名称': item.项目名称,
         '配置文件地址': `http://192.168.2.123/-/raw/main/frontend/${ymlName}`
       })
     })
     toExcel(configList)
   });
 });
 // 生成对应配置文件网络路径的excel
 function toExcel(data) {
   const xls = json2xls(data);
   fs.writeFileSync(`./CICD配置网址.xlsx`, xls, "binary");
 }
 ​

我们要做的事情很简单

  • 读取dataCI,也就是收集好的项目表数据
  • 生成一个总的文件夹,我命名为生成好的配置文件
  • 群组数据去重后遍历生成以群组为名的空文件夹
  • 接着就是遍历dataCI,创建好对应路径和名称的文件,写入对应的模板数据
  • 收集好对应的网址,因为我们最后要在新仓库配置CICD,配置好这个网址就可以

新需求

当我迁移好仓库,准备继续探讨船只在水面上划动之理时,领导突然来了一句:整理一份迁移后的表给我,越详细越好。

TMD,刚建完一百多个仓库眼都花了,又搞这种东西;于是我背上电脑头也不回,明天再说😡

第二天早上我欣赏着搬好的gitlab仓库列表;看着看着,咦,gitlab的这个列表接口会不会携带着仓库的信息呢;F12一按,点开接口,我差点大喊一声

nice

全体起立,看看接口的字段

image-20220510215324988

还说啥呀兄弟们,nodejs开干啊

projectData具体看仓库哈,兄弟们,就是上面说的接口数据

 const fs = require("fs");
 const json2xls = require("json2xls");
 const originData = require("./projectData");
 ​
 function getTemplate(item) {
   return {
     '项目群组': item.group || '',
     '项目名称': item.name,
     '项目描述': item.description,
     '代码仓库地址(内网)': `http://192.xxx.x.xxx${item.relative_path}`,
     '代码仓库地址(外网)': `http://xxx.xxx.com${item.relative_path}`,
     '搬迁时间': item.created_at.slice(0, 10),
   }
 }
 ​
 const arr = originData.map((item, index) => {
   const children = item.children;
   // 分组
   if(children) {
     return children.map((child, index) => {
       child.group = item.name
       return getTemplate(child);
     })
   } else {
     return getTemplate(item)
   }
 })
 ​
 const excelData = arr.flat();
 const xls = json2xls(excelData);
 fs.writeFileSync(`./前端仓库迁移汇总.xlsx`, xls, "binary");

依然是这个套路,

  • 先整理好表头的内容(模板),并定好取值
  • 接着就是循环处理数据了,如果没有children就代表改仓库没有分类。有就再循环一次,而这个循环就会加上群组的标识group
  • 二维数组拉个平,生成excel,大功告成!

image-20220510221711041

image-20220510221729423

最后

你们说船只要怎么划,才能水的时间更久呢🤔?

点个赞支持一下吧🙏🏻

blog:gauharchan.github.io/,这是我博客地址,让我们一起在前端道路上持续发胖吧,😁