背景
最近leader让我把现在的组件库搞一个CI自动升级版本的技术需求。笔者之前也没有接触过gitlab ci相关的东西,在几番专研
(度娘)后,把这个技术需求搞定了,废话不多说直接进入主题。
版本号手动升级的问题
目前组件库使用的是三位的版本号管理
, 大-中-小, 如:1.3.4,测试版本加上beta, 如1.3.4-beta。那么不自动升级版本号将会有一下问题。
- 每次发版本都需要发版本人手动更改版本号, 比较麻烦。
- 可能发版本人改版本号出错的情况, 比如从 1.3.4 跳到 1.3.6, 中间跳过了1.3.5版本。或者代码更改比较小,发版本把 1.3.4 直接修改版本号更改为 2.3.4。
gitlab ci 自动升级版本号
技术方案
- 使用 npm info 拿到最新线上的版本 remoteVerion。
- 和package.json文件中的version字段(localVerion)比较,如果 remoteVerion >= localVerion 那么小版本号自动加1, 如果 localVerion > remoteVerion则使用localVersion,
- 在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]
},
})
部署项目之后,就可以摸下鱼了,静静地等群里的机器人通知部署结果就好了
结尾
发现做业务需求多了,成长会慢慢变慢, 做技术需求的好处是,可以打开新的技术面,就像做了自动升级版本这个需求,发现原来gitlab ci部署的时候还可以修改代码,做一些有趣的事情。