笔者接手了一个npm项目,发现项目的版本、分支管控十分混乱。故打算结合CI流程来进行版本、分支的合并管控。
CI/CD
首先啥是CI/CD呢。CI/CD 是 Continuous Intergration/Continuous Deploy 的简称,翻译过来就是持续集成/持续部署。CD 也会被解释为持续交付(Continuous Delivery),但是对于软件工程师而言,最直接接触的应该是持续部署。
对于我们来说,我们可以直接理解为自动化集成/部署。
自动化部署和包版本管控
如何利用自动化部署,来进行包版本管控呢。其实很简单,发布包版本通常是怎么发布呢,敲个命令: npm publish即可,或者说对于使用Leana的项目来说,一般敲的命令是 lerna publish 。所以我们只有不允许开发者在本地敲这两个命令就可以了。
那么如何禁止开发者本地发布呢,一个是项目约束,要求开发者自觉不在本地发布包,另一个是,收归发布包的权限,这个一般是私有包仓库或者npm库去进行设置即可。
CI 配置
.npmrc
发布包版本,需要给CI Runner一个发布者的账号, 这个一般是配置在npmrc里。在这里我们需要配置的是,npm账户的公钥。
//npm.*****.io/:_authToken="************"
不过值得注意的是,把公钥直接写在项目里,这样是有暴露风险的。
另一个更加安全的方式是将这个token配置在gitlab中,通过配置的方式让ci文件读取。还有一种方式是,让ci runner通过接口去请求获取该token。笔者项目涉及人数较少,且对项目member进行了管控,所以暂时将token直接写在了npmrc中。
.gitlab-ci.yml
在写CI配置时,通常需要考虑一个问题,何时触发。通常来说,一般是选择在master分支上进行触发。而由于npm包涉及到包版本的问题,所以还需要考虑包版本如何管控的问题。笔者查阅了大量资料,大致有两种方案:
- 由开发者手动修改package.json,然后分支合并到master时,触发CI
- 开发者无需关心package.json的版本问题,开发完毕只需要合并代码,然后打上版本tag。 此时再触发CI,然后由CI读取tag版本,篡改package.json的version。
可以看到第二种方式,是很多团队管控版本的方式,由tag来管控。但是这样有一个不好的地方是,开发者在项目里看到的version是不对的,这是不好的。
所以综合下来,笔者对触发时机进行了优化。第一个是仍由master分支触发,但是触发时,对版本进行检查,如果发现版本没有进行迭代,不进行发布。
image: node:latest
before_script:
- version=`cat ./package.json | sed 's/,//g' | grep "version" | tr ":" "\n" | sed '1d' | sed 's/"//g'` | sed 's/ //g';
- latest=`npm view ***your package name***`;
- (if test "$version" = "$latest"; then exit 1;fi);
build:
script:
- npm install
- npm run build
- npm publish
only:
- master
when:
on_success
代码很简单,但是对于项目版本的维护和分支的管控,确实有十分重大的意义的。