Git 自動回滾 和 應用發布的二三事
本文首發於:大搜車前端博客
昨天在朋友圈講了一個笑話:剛寫了一個自動回滾的腳本,寫完後運行了一下,成功把腳本自己回滾沒了。。。很多人可能關注點在笑話本身,而不是在這個「自動回滾」的腳本到底是個什麼東東,今天就介紹下,順便講講與其關聯的一些發布應用過程中的概念。本文適用於任何 JS 語言開發的前後端項目。
本文主題結構:
- [1] Git Tag 與 應用版本號
- [2] 自動回滾
- [3] 題外話:發布腳本
[1] Git Tag 與 應用版本號
所謂「自動回滾」,最重要的不是回滾這件事情本身,畢竟只是幾句腳本的事情,等會我會詳細介紹這幾句腳本的具體內容。對於回滾來說,我要「自動」回滾到什麼點?這才是問題的根本。
這就要牽扯到應用發布過程中如何制定這些「點」,也就是 Git 中的 tag (標籤)。
Git Tag 本是個很簡單的概念,利用它可以在 Git 流程中標記一個特殊的點,然後可以附帶一些標籤的屬性。那在整個 Git Flow 流程中,他扮演什麼樣的角色呢?可能這些大家都非常熟悉了,所以說今天這篇文章是科普文。在 Git Flow 中 Tag 主要用來維護應用版本。
所以,你通常看到一個 前端(經過編譯的)或者 Nodejs 項目發布之前會做以下兩件事情:
- 修改 package.json 中的 version 信息,代表應用的版本號改變。
- 提交代碼後,打一個 Tag,記錄此次發布的 版本號 以及 發布涉及內容的簡要描述。
對於 version 版本號的定義,業界有一個通用的規範,我司的定義大抵如下:
格式如 ${major}.${feature}.${patch},遵循 semver 規範的版本號n 選擇需要遞增的版本號n major: 主版本號,用於斷代更新或大版本發布n feature: 特性版本號,用於向下兼容的特性新增n patch: 修訂版本號,用於 bug 修復n遞增位的右側位需要清零,如 1.1.2 => 1.2.0n
這兩件事情在每次發布前都必須執行,所以我們將其集成到一個互動式 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 列表,然後取出第一行ngit tag -n --sort=-taggerdate | grep n1 n
第二步:找出此 tag 對應的 commit 的 hash
# 利用 git log 的 format 取出 hashngit log --format="%h" ${lastTag} |grep n1 n
第三步:回滾
get reset --hard ${lastTagHash} n
第四步:回滾完代碼後記得還要重新 npm install 回滾對應的包版本。
將上述四句命令封裝到 bash 腳本裡面即可。
[3] 題外話:發布腳本
順帶提一下我們的應用發布方式。
對於前端來說,我們一般是通過通用腳手架中的 Makefile 集成發布腳本,其實就是一句 rsync 命令,將打包後的前端代碼 同步到 前端伺服器上。因為我們的前端項目粒度很小,一般一個項目只有一人負責,所以在現階段沒有引入發布機的概念,每個人為各自的應用負責,包括發布也由自己控制。
對於 Nodejs 來說,要複雜一些,首先是線上機器很多,還有就是有專門的發布機,不能從開發者本地直接發布應用,另外應用發布時間點以及發布流程(gitflow,測試/預發/發布)有更嚴格的限制。對於發布腳本來說,我們使用的是 Fabric 來管理髮布過程,Fabric 是一個 Python 庫,可以通過 SSH 在多個 host 上批量執行任務。整個發布過程大概可以總結為:
+--------+ +---------+ +-------------+n| 設置環境變數 |-+-| rsync 同步代碼 |-+-| pm2 gracefulReload |n+--------+ +---------+ +-------------+n
其他特點:
- 將 Node 本體的二進位包打包到應用中,做到環境 0 依賴。
- PM2 使用 node_modules 中的版本,不依賴系統版本。
- 通過 PM2 的 cluster 配置文件啟動,設置 cluster 數量,內存上限,環境變數等。
想了解更多關於 Nodejs 的信息,請關注我的 Live :小芋頭君 的 Live -- 全棧工程師養成指南
推薦閱讀:
※Git由淺入深之細說變基(rebase)
※Git 工作流指南
※Oh shit, Git! 快速解決Git最常見問題
※Git 初學者攻略
※Git由淺入深之存儲原理