Witt

JavaScript Engineer, interested in DX.

github email
开源项目版本发布的最佳实践
Apr 2, 2019
2 minutes read

对于存放在 Github / Gitlab 的开源项目,视项目大小与功用也有不同的发布方式、发布内容与自动化工程化解决方案。这里以包含 package.json 的项目为例,介绍各种不同的发布方法。

Release

在发布之前我们需要先升级版本,也有少部分自动发布的脚手架中包含升级版本与 CHANGE_LOG 收集,但通常你需要自己解决这个问题。

1. 手动更改

顾名思义,打开 package.json 或者你的其他包管理文件手动改一个版本。

2. 在遵循语义化版本的基础上手动更改

所谓语义化版本即是按约定对版本号进行约束与声明,与多数人采用同一套规则来升级版本,具体规则可以参考 semver version。也就是大家熟悉的主-次-修订:

  • MAJOR: 不兼容升级
  • MINOR: 向下兼容的功能性升级
  • PATCH: 向下兼容的问题修复
  • pre-release: 先行版本

每次 Release 新版本时参考所有的修改内容决定下个版本号,再进行修改。如果你不小心修改错了,则需要发布一个新的版本来修复这个错误。当然这只是约定,如果你觉得这很繁琐不知道该怎么办可以看下文。

3. 在遵循语义化版本的基础上自动更改

自动 release 工具可以分为 本地 / CI / 机器人不同类型,本地工具大多是 CLI (也有可视化),通过命令手动帮助你改动文件与 release git tag,CI 工具则是在你每次的 PR / PUSH / 本地 Hook 触发后通过相应的规则检查,通过后自动升级版本,机器人模式在 github 很常见,通常是运行一个服务端来监听Git 事件,在合适的时机向你发起一个 PR 升级版本。(有关 robot 你可以在 probot.githubcobot.gitlab)项目中了解更多。

对于本地升级版本的方式你可以试试 done,它可以帮助你生成一个标准化的版本,在发布时自动修改 package.json,同时也支持对版本的发布信息做 hook 补充。也就是说,当你正在使用 done 时,可以不用考虑任何事情,通过一行命令发布一个版本并生成一个 Git Tag:

(what is npx)

npx done

比如当你选择 minor 版本时即是修改本地的文件并将这些信息打包成 tag,然后把这些改动与 Tag 一并推送到远程源。

4. 如何收集 CHANGE_LOG

在自动化 CHANG_LOG 之前我们需要弄明白的一件事是,即便是自动化生成也需要有数据源,如果你没有写日志也没有合适的 commit message 就无法做到自动化版本日志。

Publish

在升级版本后你还需要做一些打包工作,再把代码或包发布到指定的平台上才算完成这次发布。

1. 仅发布源代码

如果无需编译或执行脚本,发布全部的源代码是非常方便的,只需要在 Github / Gitlab 手动创建一个 Release 即可完成发布。创建的 Release 会自动附带当前的所有源码信息。

2. 自动发布源代码

在发布源码的基础上使用 release-drafter 等 gitbot,可以在 PR 被合并或指定的关键词触发时,在项目上添加一个 Release Draft,并且可以通过手动配置的方式添加版本信息。

3. 手动发布编译后包

在有些需要编译的项目中我们常会先压缩或是执行一些编译脚本,并且排除掉对生产无用的文件才发布,因为包的大小会影响用户的下载时间与使用体验。现在我们尝试在本地发布一个执行脚本后的包。以包含 package.json 文件的项目为例:

  • 你需要在升级版本后在本地手动执行一次 Build 脚本,或是在 scripts.prepublish 中指定 Build 语句。

  • files 配置项中指定可以被发布的文件、文件夹。

  • 指定 main module unpkg 或其他入口。

  • 运行 npm publish

  • 如果包属于一个组织,你需要在组织中发布公开项目则需要指定 access: npm publish --access public

4. 自动发布编译后包

你需要借助服务器来自动完成编译或运行脚本的过程,这里以 travis-ci 为例:

  • 使用 travis.rb 初始化项目并生成密钥信息。

  • 如果发布在 github 你可以在 github/token页面自行生成 token,但仍旧需要 travis.rb 进行加密。配置信息可以参考 travis-deployment,发布在 npm 则需要 npm 的登录信息。关于 travis 是如何加密你的敏感信息,可以参见这篇文章

  • 注意设定跳过 CI 的清理过程 skip_cleanup: true 与移除分支限制 branches.only

  • 当设定的触发条件 (如 Tag) 达成时,travis 会根据 .travis.yml 的配置运行相应脚本并发布指定文件至 npm 或 github。


Back to posts