開箱即用,Hexo博客的github+server自動部署

"Travis CI"

用了一段時間HEXO搭建我的的博客,但每次發佈文章,都須要打開電腦hexo g編譯以後,再提交到服務器上,確實挺麻煩的,和小夥伴聊完他的日誌發佈方式以後,痛定思痛,快捷發佈日誌這個問題須要解決一下了!Travis CLI搞起來!html

閒聊日誌的快捷發佈

前幾天,跟小夥伴Pipe一塊兒參加個分享會,看到他作了筆記,結束後我說你發給我呀,他說直接看我博客(《工做思惟方式簡記》)呀!個人天,寫完瞬間就發到站點去了!Pipe很是高產,去看看他的博客,用「高產似母豬」來描述都不足爲過,5月份尚未過完,發佈了7篇日誌。前端

我問他,怎麼作到那麼高產?Pipe說,第一點是他的日誌是碎片化的偏記錄的,不必定要憋出大文章才發,而後就是博客系統要方便,隨寫隨發。node

反觀個人博客,更新頻率真的很低,一方面是喜歡憋專題文章,拖着拖着,而後就沒有而後了。另外一方面也是發佈確實麻煩,電腦編輯好markdown,還要執行各類命令,最後push到github和本身的服務器,文章才能被你們看到,一開始以爲還好蠻geek的,但後來確實因爲這些門檻,有打擊到那些隨時來的寫做思緒。git

By the way,Pipe用的是jekyll,跟github的持續集成是天生的,而HEXO沒有這樣的優點。從Hexo換到Jekyll吧,也不是很麻煩,可是我在Hexo生態作了一些東西,仍是有點不捨哈。github

  • github blog:個人博客分支
  • hexo-generator-index-plus:hexo小插件,首頁排序生成器,和原生的index-generator比較顯著的區別是加了置頂功能,能夠在front-matter添加top屬性便可。
  • hexo-theme-fresh:hexo博客主題,綠色小清新,Medium風格。

"hexo-theme-fresh效果截屏"

HEXO的開發分支與生產分支

倉庫分紅2個分支,主開發開支dev,以及生產環境的gh-pages分支。
查看博客能夠經過訪問github pages,又或者直接訪問個人域名 wuyuying.com/blognpm

開發分支 dev

在個人博客裏,開發分支是dev,目錄結構就是一開始hexo init後的結構。json

- scaffolds // 頁面的模板,包括草稿(draft.md)、頁面(page.md)、文章(post.md)以及其餘自定義模板
- source // 放頁面和文章markdown文檔
- themes // 博客主題
- _config.yml // 配置文件
- package.json
- .travis.yml // 持續集成服務travis的文件

本地開發流程通常是這樣。segmentfault

// hexo server, 啓動本地服務器,預覽個人文章
hexo s 

// hexo generate,編譯文章,把 `source` 裏面的頁面和文章編譯成 `public` 裏面的html文件
hexo g

// hexo deploy,若是 _config.yml 有配置deploy的內容,執行該命令是會執行相應的部署邏輯
hexo d

HEXO的詳細科普和指令在這裏就不寫了哈,官方文檔裏都有 >> 傳送門api

生產分支 gh-pages

dev分支裏,執行了hexo g編譯以後,編譯後的靜態文件會存在public文件夾裏,而咱們就把裏面的內容挪到最終的生產環境分支gh-pages裏,也就是最終咱們看到的靜態博客。緩存

當咱們在github裏把github-pages服務打開,並渲染gh-pages分支,咱們就能訪問本身的博客了(https://yuyingwu.github.io/blog/)。

"看看個人博客"

Travis CI

在大體瞭解HEXO的開發流程以後,咱們能夠開始考慮,若是要實現快捷發佈,是要作什麼?
User Story但願能夠在github上寫一篇文章,提交以後,能夠直接在個人線上博客看到

在這裏,咱們用到了提供持續集成(CI, Continuous Integration)服務的Travis CI,但其實用到的不是它提供的CI服務,而更多的是經過監聽分支提交的動態,在集成成功後去執行咱們自定義的部署邏輯。

持續集成是一種軟件開發實踐,即團隊開發成員常常集成他們的工做,經過每一個成員天天至少集成一次,也就意味着天天可能會發生屢次集成。每次集成都經過自動化的構建(包括編譯,發佈,自動化測試)來驗證,從而儘早地發現集成錯誤。

噢,還有些事前準備:

  • 先在dev分支裏,建立.travis.yml
  • Travis CLI平臺上打開這個分支的CI開關

1. 編譯並同步到gh-pages

那直接上個人CI配置代碼吧。

language: node_js
node_js: stable

addons: # Travis CI建議加的,自動更新api
  apt:
    update: true

cache:
  directories: 
  - node_modules # 緩存 node_modules

install:
- npm install # 初次安裝,在CI環境中,執行安裝npm依賴

# before_script: 

script:
- hexo g # 執行 hexo generate,把文章編譯到public中

after_success: # 執行script成功後,進入到public,把裏面的代碼提交到博客的gh-pages分支
- cd ./public
- git init
- git config user.name "Yuying Wu"
- git config user.email "wuyuying1128@gmail.com"
- git add .
- git commit -m "Update site"
- git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master:gh-pages

branches:
  only:
  - dev # CI 只針對分支 dev

env:
  global: # 全局變量,上面的提交到github的命令有用到
  - GH_REF: github.com/YuyingWu/blog.git
  - secure: 
# secure是自動生成的,執行`travis encrypt 'GH_TOKEN=${your_github_personal_access_token}' --add`

相信代碼和註釋寫得很清楚了,有個地方須要進一步解釋的,github提交那part,涉及github access token的生成和加密。

  1. 生成github的Personal Access Tokens(打開分支提交的權限)
  2. 安裝Travis CLI gem install travis(若是登陸遇到環境問題,能夠看看下面參考文章裏面的解決方案)
  3. 進入到本地dev目錄下(帶有.travis.yml),執行travis login登陸,再執行travis encrypt 'GH_TOKEN=${your_github_personal_access_token}' --add加密你的personal access token(也就是後來.travis.ymlenv.global.secure的值)

.travis.yml提交以後,看看Travis CLI上,開始持續集成了哈。

"開始準備"
"after_success把代碼部署到gh-pages"

大功告成,集成以後,在github pages的頁面上也能看到文章的更新。

2. CI到個人服務器

個人服務器是DO家(Digital Ocean)的,那一開始服務器初始化的過程,你們能夠參考各個server商提供的setup文檔哈,總的來講,在本地有個服務器信任的id_rsa的ssh文件,咱們是能夠經過ssh user@ip_address登陸到服務器的。

# 這個命令會自動把 id_rsa 加密傳送到 .git 指定的倉庫對應的 travis 中去(在我本地這個文件叫qq_rsa,不是默認的id_rsa)
travis encrypt-file ~/.ssh/id_rsa --add

執行這個命令後,.travis.yml多了一行代碼:(注意把其中的轉義符\幹掉哈),也會在分支目錄下生成一個id_rsa.enc的加密文件,記得把這個文件也提交上去喲。

before_install:
- openssl aes-256-cbc -K $encrypted_3cf6c1fd150f_key -iv $encrypted_3cf6c1fd150f_iv
  -in qq_rsa.enc -out ~/.ssh/id_rsa -d

而後爲了保證在Travis裏面能正常執行,咱們處理下運行環境的rsa文件權限和輸出提示信息,before_install以下。

before_install:
- openssl aes-256-cbc -K $encrypted_3cf6c1fd150f_key -iv $encrypted_3cf6c1fd150f_iv
  -in qq_rsa.enc -out ~/.ssh/id_rsa -d
- chmod 600 ~/.ssh/id_rsa
- echo -e "Host 主機IP地址\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config

最後,在after_success裏添加拷貝目標文件到服務器目標目錄的操做,就大功告成了!

after_success
# other actions
- scp -o stricthostkeychecking=no -r ./* root@138.68.161.48:/home/wyyNode/public/blog/

參考文章


筆者 @Yuying Wu,前端愛好者 / 鼓勵師 / 新西蘭打工度假 / 鏟屎官。目前就任於某大型電商的B2B前端團隊。

感謝你讀到這裏。若是你和我同樣喜歡前端,喜歡搗騰獨立博客或者前沿技術,或者有什麼職業疑問,歡迎關注我以及各類交流哈。

獨立博客:wuyuying.com
知乎ID:@Yuying Wu
Github:Yuying Wu

相關文章
相關標籤/搜索