https://juejin.im/post/5e38ec1ce51d4526c932a4fbjavascript
年前我也在自動化部署這方面下了點功夫,將本身的學習所得在自動化部署的一小步,前端搬磚的一大步這篇博客中作了分享。感謝兩位網友@_shanks
和@TomCzHen
的意見,讓我有了繼續優化部署流程的動力。本文主要是在自動化部署流程中,對版本管理和流程合理性等方面作了一些改進,配合規範的工做流,使用體驗更佳!html
更新日誌自動生成
以前我都是手動修改CHANGELOG.md
,用來記錄更新日誌,感受操做起來有點心累,也不是很規範。好在已有前人種樹,因而我就考慮利用conventional-changelog-cli
自動生成和更新CHANGELOG.md
,真的好用!前端

什麼是conventional-changelog
Generate a changelog from git metadatavue
根據git
元數據生成更新日誌,而conventional-changelog-cli
則是相關的命令行工具。java
安裝conventional-changelog-cli
npm install -g conventional-changelog-cli
複製代碼
初始化生成CHANGELOG.md
cd my-project
conventional-changelog -p angular -i CHANGELOG.md -s
複製代碼
以上命令是基於最後一次的Feature
, Fix
, Performance Improvement or Breaking Changes
等類型的commit
記錄生成或更新CHANGELOG.md
。若是你但願根據以前全部的commit
記錄生成完整的CHANGELOG.md
,那麼能夠試試下面這條命令:node
conventional-changelog -p angular -i CHANGELOG.md -s -r 0
複製代碼
工做流
代碼添加到暫存區
這一步沒有什麼特殊,平常擼代碼,而後將工做區的內容添加到暫存區。linux
git add .
複製代碼
規範commit message
一個規範的commit message通常分爲三個部分Header,Body 和 Footer。Header包含type, scope, subject等部分,分別用於描述commit類型,影響範圍,commit簡述。Body則是詳細描述,能夠分多行寫。Footer主要用於描述不兼容改動(Breaking Change)或者關閉issue(Closes #issue)。nginx
格式以下:git
<type>(<scope>): <subject> <body> <footer> 複製代碼
舉個栗子:github
feat(支持自動部署): 結合conventional-changelog,配合部署腳本完成部署任務 conventional-changelog是一個很好的工具,用於自動生成changelog,再配上自定義的部署腳本,整個部署流程就顯得更規範了 Breaking Change: 比較大的更新 Closes #315 複製代碼
其中,Header
是必需的,Body
和Footer
能夠省略。
大體瞭解規範後,就能夠上工具了,這裏咱們用到的是commitizen
。
npm install -g commitizen
複製代碼
接着在項目根目錄運行如下命令:
commitizen init cz-conventional-changelog --save --save-exact
複製代碼
運行成功後,package.json
會新增以下內容:
"devDependencies": {
"cz-conventional-changelog": "^3.1.0"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
複製代碼
git commit
這一步用git cz替代
,cz
就是指commitizen
,經過交互式命令行完成commit
操做。
PS D:\robin\frontend\spa-blog-frontend> git cz
cz-cli@4.0.3, cz-conventional-changelog@3.1.0
? Select the type of change that you're committing: feat: A new feature
? What is the scope of this change (e.g. component or file name): (press enter to skip) 支持自動部署
? Write a short, imperative tense description of the change (max 86 chars):
(37) 結合conventional-changelog,配合部署腳本完成部署任務
? Provide a longer description of the change: (press enter to skip)
? Are there any breaking changes? No
? Does this change affect any open issues? No
[master ee41f35] feat(支持自動部署): 結合conventional-changelog,配合部署腳本完成部署任務
3 files changed, 15 insertions(+), 3 deletions(-)
複製代碼
處理版本號,更新CHANGELOG
接着咱們要更新npm
包的版本號,結合npm version
和conventional-changelog
使用,能夠同時更新CHANGELOG.md
。
好的,咱們先準備好腳本:
"scripts": {
"start": "vue-cli-service serve",
"build": "vue-cli-service build",
"deploy": "node deploy",
"version": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md",
"postversion": "npm run deploy"
}
複製代碼
根據實際版本狀況選擇更新patch/minor/major
版本。假設咱們更新的是minor
版本號,那麼操做命令以下:
npm version minor -m '特性版本更新'
複製代碼
執行這條命令會更新package.json
中的version
字段,
同時會執行conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md
,更新CHANGELOG.md
。
執行完這條命令後,能夠看到CHANGELOG.md
已經被修改了。

npm鉤子觸發部署腳本
經過postversion
鉤子觸發部署腳本node deploy
,開始進行部署工做。deploy.js
文件內容以下:
const { execFile } = require('child_process'); const version = process.env.npm_package_version; execFile('deploy.sh', [version], { shell: true }, (err, stdout, stderr) => { if (err) { throw err; } console.log(stdout); }); 複製代碼
這裏利用了nodejs
的 child_process
模塊執行子進程,調用了execFile
執行了 deploy.sh
,並將npm
包版本號做爲參數傳遞給了deploy.sh
。
deploy.sh
文件內容以下:
#!/bin/bash npm run build htmldir="/usr/share/nginx/html" uploadbasedir="${htmldir}/upgrade_blog_vue_ts" appenddir=$1 uploaddir="${uploadbasedir}/${appenddir}" projectdir="/usr/share/nginx/html/blog_vue_ts" scp -r ./dist/. txcloud:${uploaddir} ssh txcloud > /dev/null 2>&1 << eeooff ln -snf ${uploaddir} ${projectdir} exit eeooff echo done 複製代碼
以上命令主要作的事情是:
npm run build
執行構建任務- 將構建獲得的
dist
文件夾中的內容經過scp
傳輸到服務器,經過版本號區分各個版本。 nginx
配置的是監聽80
端口,指向/usr/share/nginx/html/blog_vue_ts
,而我經過軟鏈接將blog_vue_ts
再次指向到upgrade_blog_vue_ts
下的版本目錄,如upgrade_blog_vue_ts/0.5.4
。每次發佈版本時,以上腳本會修改軟鏈接,指向目標版本,如upgrade_blog_vue_ts/0.6.0
,完成版本過渡。
我這裏使用了軟鏈接改進了以前的部署腳本,既能夠在服務器保留各個歷史版本文件夾,也不用考慮處理index.html
與靜態資源分離的問題。
強烈建議結合自動化部署的一小步,前端搬磚的一大步這篇文章一塊兒看。
lrwxrwxrwx 1 root root 47 Feb 3 21:35 blog_vue_ts -> /usr/share/nginx/html/upgrade_blog_vue_ts/0.6.0
複製代碼

若是要回退版本,也能夠經過修改軟鏈接的方式實現,仍是比較方便的。
推送到remote
最後別忘了把代碼push
到遠程倉庫。
git push
複製代碼
更新日誌changelog
查看也變得很方便了,修改了什麼內容一目瞭然,而且能夠直接跳轉到commit
歷史,issue
等。

番外
能夠看到,我是經過deploy.js
調用了deploy.sh
。以前本想直接在npm scripts
中調用deploy.sh
並傳入版本號參數的,可是試了幾種寫法都不行,這裏也記錄一下。
"deploy": "deploy.sh npm_package_version"
複製代碼
"deploy": "deploy.sh $npm_package_version"
複製代碼
看起來在npm scripts
中調用sh
腳本時,只能寫字面量參數,傳變量做爲參數好像行不通。
下面這種字面量參數寫法是能夠的,可是就有點呆呆的感受了,並且與自動化部署的主題不符。
"deploy": "deploy.sh 0.6.0"
複製代碼
因此我目前仍是選擇經過deploy.js
做爲中間者來調用deploy.sh
的。
結語
須要認可的是,我以上所述的部署流程是以個人我的項目爲例說明,可能不是很規範,可是也算是經過本身的理解和摸索,完整地搞了一套部署流程,並無借用jenkins
等工具。有了這段自動化部署的學習經歷後,相信學習和使用jenkins
會變得更輕鬆。接下來我會繼續優化和規範本身的部署流程,jenkins
理所固然會出如今個人計劃表中。
我是Tusi,一個創業公司前端小leader,天天依然爲寫不完的業務代碼煩惱,在打磨產品道路上沉澱技術,探索成長路線。若是你與我同樣,正在思考本身的技術成長與價值,歡迎加我微信交流探討,微信號ice_lloly。我會在公衆號猿出道和小程序Tusi博客同步博客內容,快來撩我!
