背景
NPM包往往承担着一些公用业务或者逻辑,NPM的上线发布的自动化是我们的目标,如果能利用Gitlab CI之类的工具来完成自动化发布latest
版本 + 生成/更新 CHANGE.LOG
+ 打tag
这一系列的操作,会令我们的上线流程省心和规范化不少
话不多说
关于gitlab ci的介绍请看官方文档
首先了解下.gitlab-ci.yml
官方文档 ,这里搬运一个官网的关于NPM的CI的示例代码:
# This specific template is located at:
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/npm.gitlab-ci.yml
publish:
image: node:latest # 表示使用的NODE镜像
stage: deploy
rules: # 触发的规则
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_REF_NAME =~ /^v\d+\.\d+\.\d+.*$/
changes:
- package.json
script: # 以下是运行脚本
# If no .npmrc is included in the repo, generate a temporary one that is configured to publish to GitLab's NPM registry
- |
if [[ ! -f .npmrc ]]; then
echo 'No .npmrc found! Creating one now. Please review the following link for more information: https://docs.gitlab.com/ee/user/packages/npm_registry/index.html#project-level-npm-endpoint-1'
{
echo "@${CI_PROJECT_ROOT_NAMESPACE}:registry=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/npm/"
echo "${CI_API_V4_URL#http*:}/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=\${CI_JOB_TOKEN}"
} >> .npmrc
fi
- echo "Created the following .npmrc:"; cat .npmrc
...
复制代码
看起来还是比较复杂,我们关注下需要用到的部分:
image
: 来指定镜像,我们如果指定了node镜像,里面其实是自带了npm
,git
等工具rules
: 用来指定触发规则,还有only
字段等也是同样的作用script
: 用来执行自定义脚本,我们的发布逻辑会写在这里variables
:$CI_COMMIT_BRANCH
,$CI_COMMIT_REF_NAME
这些都是CI内部提供的变量,可以直接使用这些值,具体见官方文档CI变量
其次,我们需要在CI内执行NPM包的发布+ 打tag
+ 生成CHANGE.LOG
然后往git仓库推送,所以我们还需要新增两个自定义的CI变量NPM_TOKEN
, GIT_PUSH_TOKEN
,具体参考官方文档添加CI变量(需要的Maintainer权限)
最后愉快的开始我们的release
分支自动发布之旅,standard-version
的使用请参考上一篇文章,以下为核心代码实现及一些注释
代码
.gitlab-ci.yml配置
image: node:12.22.0 # 指定node镜像版本
stages:
- publish # 定义了一个publish的stage
publish_job:
stage: publish # 对应上面我们定义的publish的stage
only:
- release # 只对release分支生效,我们将代码合并进去release分支会触发
script:
- npm set registry https://ucompany.xxx # 配置npm源
- git config --global user.email "uemail@com" # 配置git账号
- git config --global user.name "uname"
- echo "//npm.shopee.io/:_authToken=${NPM_TOKEN}" > ~/.npmrc # 将配置的NPM_TOKEN写入.npmrc文件
- echo "unsafe-perm = true" >> ~/.npmrc #由于ci里面用root账号发布,需要加这个
- yarn install # or npm install
- node build/publish ${CI_COMMIT_REF_NAME} ${GIT_PUSH_TOKEN} ${CI_COMMIT_MESSAGE} # 跑js代码
复制代码
publish.js 发布代码
const shell = require('shelljs') // 这个非必需,可以用node自带的
const { join } = require('path')
const publishType = 'patch' // major, minor, patch
const rootPath = process.cwd()
const pkg = require(`${join(rootPath, 'package.json')}`)
const packageName = pkg.name
const CI_COMMIT_REF_NAME = process.env.CI_COMMIT_REF_NAME
const GIT_PUSH_TOKEN = process.env.GIT_PUSH_TOKEN // 推送commit用
try {
const versionCommand = `npm run release -- --release-as ${publishType} --releaseCommitMessageFormat "chore(release): {{currentTag}} [skip ci] "`
const publishCommand = 'npm run publish --registry https://ucompany.com'
shell.exec(`${versionCommand} && ${publishCommand}`)
console.log(`${packageName}发布完成:开始推送tag和changelog...`)
const gitPushCommand = `git push https://gitlab-ci-token:${GIT_PUSH_TOKEN}@xxxxgit_address_xxxx.git/ HEAD:${CI_COMMIT_REF_NAME} --follow-tags`
shell.exec(gitPushCommand)
} catch (e) {
console.log(e)
process.exit(1)
}
复制代码
结束语
以上是关于ci自动发布的实践demo,非live环境的配置在上面省略了,可以自行定义,如有好的idea欢迎评论区交流~
感谢-_-