剑客
关注科技互联网

Git 自动回滚 和 应用发布的二三事

昨天在朋友圈讲了一个笑话:刚写了一个自动回滚的脚本,写完后运行了一下,成功把脚本自己回滚没了。。。很多人可能关注点在笑话本身,而不是在这个“自动回滚”的脚本到底是个什么东东,今天就介绍下,顺便讲讲与其关联的一些发布应用过程中的概念。本文适用于任何 JS 语言开发的前后端项目。

本文主题结构:

  • [1] Git Tag 与 应用版本号
  • [2] 自动回滚
  • [3] 题外话:发布脚本

[1] Git Tag 与 应用版本号

所谓“自动回滚”,最重要的不是回滚这件事情本身,毕竟只是几句脚本的事情,等会我会详细介绍这几句脚本的具体内容。对于回滚来说,我要“自动”回滚到什么点?这才是问题的根本。

这就要牵扯到应用发布过程中如何制定这些“点”,也就是 Git 中的 tag (标签)。

Git Tag 本是个很简单的概念,利用它可以在 Git 流程中标记一个特殊的点,然后可以附带一些标签的属性。那在整个 Git Flow 流程中,他扮演什么样的角色呢?可能这些大家都非常熟悉了,所以说今天这篇文章是科普文。在 Git Flow 中 Tag 主要用来维护应用版本。

所以,你通常看到一个 前端(经过编译的)或者 Nodejs 项目发布之前会做以下两件事情:

  1. 修改 package.json 中的 version 信息,代表应用的版本号改变。
  2. 提交代码后,打一个 Tag,记录此次发布的 版本号 以及 发布涉及内容的简要描述。

对于 version 版本号的定义,业界有一个通用的规范,我司的定义大抵如下:

格式如 ${major}.${feature}.${patch},遵循 semver 规范的版本号
    选择需要递增的版本号
        major: 主版本号,用于断代更新或大版本发布
        feature: 特性版本号,用于向下兼容的特性新增
        patch: 修订版本号,用于 bug 修复
递增位的右侧位需要清零,如 1.1.2 => 1.2.0

这两件事情在每次发布前都必须执行,所以我们将其集成到一个交互式 npm 包中,在发布前执行一下命令,就可以自动为你更改版本号(选择此次发布的类型自动递增某部分版本号)然后为您打上一个此次发布的 tag。具体可以参见我司博客的文章: http://f2e.souche.com/blog/npm-assistor/

[2] 自动回滚

打 tag 的主要目的是什么?最最主要的作用是标记你的每次发布,然后在你发布的过程中如果出现问题了,你可以迅速知道你应该把代码回滚到何处。

通常,这个过程并不复杂,一般我们都是手动查找 上一个 发布的 tag,然后记录对应的 commit hash ,最后执行回滚命令(git reset –hard ${hash}),并且重新执行 npm install(回滚 npm 包);xxx rsync(重新同步应用代码);xxx reload(重启服务器)。

但是每次都手动搞也很烦,为什么不把整个过程都变成一句脚本?其实很简单,利用 Git 本身的命令就可以搞定整个过程。

这里不讲过程和原理,直接贴代码:

第一步:寻找上一个 tag 的内容:

# 先列出按照时间倒叙的 tag 列表,然后取出第一行
git tag -n --sort=-taggerdate | grep n1

第二步:找出此 tag 对应的 commit 的 hash

# 利用 git log 的 format 取出 hash
git log --format="%h" ${lastTag} |grep n1

第三步:回滚

get reset --hard ${lastTagHash}

第四步:回滚完代码后记得还要重新 npm install 回滚对应的包版本。

将上述四句命令封装到 bash 脚本里面即可。

[3] 题外话:发布脚本

顺带提一下我们的应用发布方式。

对于前端来说,我们一般是通过通用脚手架中的 Makefile 集成发布脚本,其实就是一句 rsync 命令,将打包后的前端代码 同步到 前端服务器上。因为我们的前端项目粒度很小,一般一个项目只有一人负责,所以在现阶段没有引入发布机的概念,每个人为各自的应用负责,包括发布也由自己控制。

对于 Nodejs 来说,要复杂一些,首先是线上机器很多,还有就是有专门的发布机,不能从开发者本地直接发布应用,另外应用发布时间点以及发布流程(gitflow,测试/预发/发布)有更严格的限制。对于发布脚本来说,我们使用的是 Fabric 来管理发布过程,Fabric 是一个 Python 库,可以通过 SSH 在多个 host 上批量执行任务。整个发布过程大概可以总结为:

+--------+   +---------+   +-------------+
| 设置环境变量 |-+-| rsync 同步代码 |-+-| pm2 gracefulReload  |
+--------+   +---------+   +-------------+

其他特点:

  1. 将 Node 本体的二进制包打包到应用中,做到环境 0 依赖。
  2. PM2 使用 node_modules 中的版本,不依赖系统版本。
  3. 通过 PM2 的 cluster 配置文件启动,设置 cluster 数量,内存上限,环境变量等。
分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址