gitlab-ci组件库版本号自动升级

1,695 阅读3分钟

背景

最近leader让我把现在的组件库搞一个CI自动升级版本的技术需求。笔者之前也没有接触过gitlab ci相关的东西,在几番专研(度娘)后,把这个技术需求搞定了,废话不多说直接进入主题。

版本号手动升级的问题

目前组件库使用的是三位的版本号管理, 大-中-小, 如:1.3.4,测试版本加上beta, 如1.3.4-beta。那么不自动升级版本号将会有一下问题。

  1. 每次发版本都需要发版本人手动更改版本号, 比较麻烦。
  2. 可能发版本人改版本号出错的情况, 比如从 1.3.4 跳到 1.3.6, 中间跳过了1.3.5版本。或者代码更改比较小,发版本把 1.3.4 直接修改版本号更改为 2.3.4。

gitlab ci 自动升级版本号

技术方案

  1. 使用 npm info 拿到最新线上的版本 remoteVerion。
  2. 和package.json文件中的version字段(localVerion)比较,如果 remoteVerion >= localVerion 那么小版本号自动加1, 如果 localVerion > remoteVerion则使用localVersion,
  3. 在gitlab ci的时候把比较后的版本号写入package.json中

目前实现的只是自动增加小版本号,如果需要发中版本和大版本还是需发版人手动更改。

npm info拿到最新发布过的remoteVerion版本号

const { execSync } = require('child_process');
execSync('npm info 项目名称')

获取比较后版本号

const compareVersion = function (v1, v2) {
  for(let i = 0; i < v1.length; i++) {
    const p1 = +v1[i] || 0;
    const p2 = +v2[i] || 0;
    if(p1 > p2) {
      return true
    } else if(p1 < p2) {
      return false
    }
  }
  return true
}

// 计算版本号
const calVersion = function(localVersion, remoteVersion, isBeta) {
  const v = localVersion.split(/\.|-/g).slice(0, 3);
  const rv = remoteVersion.split(/\.|-/g).slice(0, 3);
  const reg = /^[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}/;
  // 本地版本号格式错误
  const formatError = !reg.test(localVersion)
  // 线上的版本号大于或等于本地的版本号
  let isGte = compareVersion(rv, v)
  if (formatError || isGte) {
    //更新为线上的小版本号 + 1
    rv[2] = +rv[2] + 1
    return isBeta ? rv.join('.') + '-beta' :  rv.join('.');
  }
  //如果开发者手动更改版本号就用手动更改为的版本号
  return isBeta ? v.join('.') + '-beta' :  v.join('.');
}

在 gitlab ci的时候把版本号写入package.json中

// 向package.json写入版本号
const writePackageVersion = function(version) {
  const packageFilePath = path.join(__dirname, '../package.json');
  const package = JSON.parse(fs.readFileSync(packageFilePath, 'utf8'));
  package.version  = version;
  fs.writeFileSync(packageFilePath, JSON.stringify(package));
}

// localVersion package.json的version字段, remoteVersion最新发布过的版本,
// isBeta是否是测试版本
const v = calVersion(localVersion, remoteVersion, isBeta);
writePackageVersion(v)

gitlab部署成功通知到群里

可以通过process.env.GITLAB_USER_EMAIL获取当前发版人的邮箱,查到公司聊天软件向群里@的接口和字段, 在gitlab ci成功之后触发当前机器人通知即可。

// 获取发版人的邮箱
const email = process.env.GITLAB_USER_EMAIL || 'langpeng.shuai@xxx.com'

const sendText = async function(data = {}) {
  try {
    const { data: output } = await axios.post(
      'https://openapi.xxx.io/webhook/group/WYRW0PorSu-CqmQGJH8',
      data
    );
    return output;
  } catch (e) {
    console.error('xxx bot send message failed.\n', e);
  }
}

const version = isBeta ? betaVersion : releaseVersion
const content = `${version} version has published of ${packageName}`;
sendText({
  tag: 'text',
  text: {
    content,
    mentioned_email_list: [email]
  },
})

部署项目之后,就可以摸下鱼了,静静地等群里的机器人通知部署结果就好了

Snipaste_2021-12-12_20-29-01.png

结尾

发现做业务需求多了,成长会慢慢变慢, 做技术需求的好处是,可以打开新的技术面,就像做了自动升级版本这个需求,发现原来gitlab ci部署的时候还可以修改代码,做一些有趣的事情。