【译】简易的NPM自动化发布

原文node

如何将NPM发布包的过程自动化,特别是当处理多个分支时,是一个大多数人都会遇到的问题,更受关注的是在CI系统中作到这些。git

当我用手动的方式作这些事情时,状况老是很糟糕,所以我一直都是使用一种高度自动化的模式来搞定它。利用CI自动化发布或从终端中手动发布对这套模式来讲都不是问题。shell

我有一段时间没有手动输入 npm publish 了,这是一个好事。npm

良好的测试乃重中之重

我对100%的测试覆盖率有着狂热的追求。这并不能完美地防范每个问题,但它确实能够防止我作一些愚蠢的事情,好比说,我觉得我知道本身在干什么。json

我首选的测试库是 tap ,但你可使用任何支持代码覆盖的测试库。若是你使用的测试库不支持开箱即用的代码覆盖测试,你也可使用 nyc 运行任何带有覆盖跟踪的 Node.js 进程。安全

运行 npm i tap -D 来安装这个测试库,并将下面的代码加入到 package.json 文件中:工具

{
  "scripts": {
    "test": "tap"
  },
  "tap": {
    "check-coverage": true
  }
}
复制代码

npm version 命令

npm version 命令会计算下一个版本号是什么,并修改你的 package.json 文件,甚至使用带标记的 tag 将其签入 Git 中。这样作的好处是,当 Git 工做目录中有未跟踪的更改时,它能够阻止版本自增,并提供一些能够在版本自增以前或以后执行其余操做的钩子脚本。post

package.json文件中的scripts部分,我添加了一个preversion脚本以便运行个人测试:测试

{
  "scripts": {
    "preversion": "npm test",
    "test": "tap"
  },
  "tap": {
    "check-coverage": true
  }
}
复制代码

如今,在版本自增以前npm会确保代码能够经过测试。若是没有经过测试(或者它的覆盖率不是100%),当前操做会失败,而且 version 命令也不能执行。加密

发布版本变动

至此,版本自增已经完成了,是时候将它分享出去了。随着 preversion 的完成,postversion 命令会在版本自增后执行操做。因此,让咱们勾选它来发布包。

{
  "scripts": {
    "postversion": "npm publish",
    "preversion": "npm test",
    "test": "tap"
  },
  "tap": {
    "check-coverage": true
  }
}
复制代码

保持Git与npm同步

推送到npm这一步已经完成了,接下来我必须记住将变动推送到git。(有不少次我都忘记了这么作,所以遇到了问题,一般来讲这是一个很差的信号。)

很是感谢npm为咱们提供了一个 publish 事件的钩子,咱们能够像这样来使用它:

{
  "scripts": {
    "postpublish": "git push origin --all; git push origin --tags",
    "postversion": "npm publish",
    "preversion": "npm test",
    "test": "tap"
  },
  "tap": {
    "check-coverage": true
  }
}
复制代码

这里执行了两个命令。第一个命令将全部的分支推送到远程,第二个将全部的标签推送到远程(包括表明新版本的标签)。

分支和分发标签 (Dist-Tags)

我偶尔会发现本身在为尚未准备好发布的新版本开发一些重要的功能。

我会在功能分支中修改脚本,经过增长一个 --tag 参数到 npm publish 命令中,将该分支放入一个分发标签中,而不是 latest 标签。

{
  "scripts": {
    "postversion": "npm publish --tag=next",
    "postpublish": "git push origin --all; git push origin --tags",
    "preversion": "npm test",
    "test": "tap"
  },
  "tap": {
    "check-coverage": true
  }
}
复制代码

如今我可让别人运行 npm install my-module@next 来尝试新的预发布版本。

另外一方面,我可能但愿为旧的版本修复 bug 或者移植功能。为了作到这一点,我基于旧的版本建立了一个 git 分支,而后在 package.json 中加入一个 legacy 标签。

{
  "scripts": {
    "postversion": "npm publish --tag=legacy",
    "postpublish": "git push origin --all; git push origin --tags",
    "preversion": "npm test",
    "test": "tap"
  },
  "tap": {
    "check-coverage": true
  }
}
复制代码

加分项:对你的版本进行签名

Git 支持用PGP签名给 commit 打标签。要让npm利用这一点,请进行以下配置:

npm config set sign-git-commit true
npm config set sign-git-tag true
复制代码

若是你以为设置 PGP 并将它与 Git 相链接太麻烦了,恭喜你,你不是一我的!我是一个老电脑迷,可我也玩不转它。此外,对于个人密钥就存在我电脑里的一个文本文件中,我老是忧心忡忡。而若是他们是被加密的,那我就必须一直输入密码,这太麻烦了。

我是Krypton的忠实粉丝。 它将你的 PGP 和 SSH 私钥存储在移动设备的安全存储库中,而后推送通知以容许它使用这些密钥执行操做。设置很是简单,而且很是易于使用,并为你提供一个硬件的双重验证。

固然,我使用 npm version 命令来完成全部的发布工做。修复bug,运行 npm version patch 。新的特性,运行 npm version minor。重大变动,运行 npm version major

若是你使用 Conventional Commits或者相似的工具,你甚至能够自动检测这是什么类型的版本,这留给做者自行练习。

这种使用 npm 脚本实现自动化的方法适用于您将要发布和提交的任何系统。在你的下一个项目中实践起来,不要太相信本身的手指 ^_^

PS: npm 配置是很是灵活的

你会注意到我在上面的发布命令中用了 --tag =。你还能够经过许多其余方式配置 npm。能够设置任何配置值(包括 npm publish 中的 tag):

  • 显式的命令,如 --tag=whatever
  • 在环境中进行配置 NPM_CONFIG_TAG=whatever
  • 在项目根目录中的 .npmrc 文件中, 如 tag = whatever
  • 在主目录的 .npmrc 文件中
  • /usr/local/etc/npmrc(某些系统中是 /usr/etc/npmrc on some systems)。

这些配置是继承式的,因此列表中位置越高的设置,优先级就越高。

对于 CI/CD 系统, 这意味着你有时能够设置环境变量来控制 npm 命令的行为,而无需改变代码或者添加文件。若是使用文件来控制更方便(举个例子,将 .npmrc 文件加入 git 中),那也能够。

相关文章
相关标签/搜索