我们设想一个开发场景
- 我们使用ts进行开发工具包
- 当我们开发完毕后,我们进行代码合并,并打出版本tag进行版本归档
- 触发CI,进行远程构建动作
- 将构建结果发布到我们的NPM包管理当中
本文介绍在 gitlab 下面使用 CI/CD
发布前端包到 npm
的方法,让npm的包和代码仓库关联起来,同时省去手动的npm publish
动作
如果你不是适用的 gitlab
,不用担心,脚本部分仍然对你有很大帮助
对于没有使用 gitlab 的小伙伴,可以使用这篇文章做一下基础的 gitlab 搭建 在 gitlab 中玩转 CI/CD(juejin.cn)
前期准备
1. 新建代码仓库
可以参考这个仓库的代码,请把 gitlab-ci.yml 文件删除哦 ~ 点我下载
1. 生成 npm token 备用
- 登陆 npm 官网,进行token获取
新建一个token
建好的token保存下来备用,找到profile, 打开2FA
4. 将 token 设置成环境变量
首次注册需要验证邮箱npm发布报错 :403 Forbidden - PUT https://registry.npmjs.org - SegmentFault 思否
配置 CI/CD
1. 配置ci文件
一个 gitlab-ci.yml 文件如下所示, build
表示的是构建阶段的名称,是一个 stage
,script
则表示这个阶段的脚本工作,这里做了简单的 npm i
, 以及 tsc
构建工作,构建的输出目录和配置主要存在项目的 tsconfig.json
里面
image: node:latest
build:
script:
- npm install
- ./node_modules/typescript/bin/tsc -p ./tsconfig.json
保存后,你会在 CI/CD
里面看到进行中的任务
2. 指定仅分支才触发构建
上面的 CI
逻辑,会被应用于所有的分支,一旦发生提交动作,就会启动,这明显是和我们的需求不符合的,我们希望仅在打 tag
的时候才发生构建动作,因此我们需要给我们的 build
stage 增加 only
限定,让他只能对部分分支起作用
only:
- develop
- release
- master
- /^dev_[0-9]+(?:.[0-9]+)+$/ # regular expression
only
语法如上,我们可以直接写死分支或者tag的名称,也可以使用正则表达式来做匹配命中,此处我们直接写版本号通配符
only:
- /^\d+\.\d+\.\d+$/
当我们打的tag满足 1.0.0
类似的这种格式时,就会触发构建,当然也可以加上一下小尾巴,比如
only:
- /^\d+\.\d+\.\d+$/ # 这是版本
- /^\d+\.\d+\.\d+-beta-.*/ # beta版本
3. 使用 tag 号替换 package.json 的版本号
npm 上面的版本号,是根据 package.json
里面的 version
进行匹配的,因此我们在正式 publish
前,还需要修改 version
的版本号, 有的小伙伴可能会在打tag前,手动修改 package.json 文件,也无不可,这里我们直接在 CI
里面用脚本代码直接修改了, 相关的脚本如下
- file=`cat ./package.json` # 读取文件,并赋值到file变量里面
- echo ${file/\"version\":\ \"1.0.0\"/\"version\":\ \"`git describe`\"} > ./package.json
git describe
使用于获取当前的仓库描述信息,在打tag后执行的ci里面,得到的就是分支的名称,当然也可以使用 gilab 变量进行处理
echo xx > filePath
是将 xx 内容输出到指定文件之中,直接覆盖掉
${string/aa/bb}
是替换的语法,将string里面的 aa
换成 bb
,此处将 "version": "1.0.0"
替换成 "version": "tag"
部分斜杠主要用于转义,可以在本地进行测试
echo ${string/\"version\":\ \"1.0.0\"/\"version\":\ \"`git describe`\"} > ./package.json
4. 进行无用的目录清理
上传前,我们尅将我们的源码以及一些过程文件等内容清理掉
- rm -rf src # 笔者使用的工程源代码在src
- rm -rf node_modules # 依赖不需要一起上传
5. 进行 npm publish
最后,配置 token,保证 npm publish 权限
- echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc
执行发布,整个文件看起来就会像
# This file is a template, and might need editing before it works on your project.
# Official framework image. Look for the different tagged releases at:
# https://hub.docker.com/r/library/node/tags/
image: node:latest
build:
script:
- echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc
- npm install
- ./node_modules/typescript/bin/tsc -p ./tsconfig.json
- rm -rf src
- rm -rf node_modules
- string=`cat ./package.json`
- echo ${string/\"version\":\ \"1.0.0\"/\"version\":\ \"`git describe`\"} > ./package.json
- npm publish
only:
- /^v.*/ # 笔者版本打法都是 v开头
处理完后,就会看到发布的结果,注意,发布公有包的时候,需要将 package.json 里面的 private 这行删掉
进阶
-
受限于安全限制,公司的大部分包都不能直接挂到公网上面去,那么将包推到私有的包管理里面的确是有必要的,可以使用的是 A lightweight open source private npm proxy registry | Verdaccio 系统作为私有包管理,搭建完成后按上面的流程处理即可
-
理论上,我们不仅可以自动发布npm包,还可以在提交合并请求的时候,自动的从master打出一个tag,这个tag又会触发publish操作
其他
- 如果你的 runner 安装环境已经做好了npm login 的动作,那么可以不用配置token