使用Travis CI自動部署Hexo博客

自從使用GitHub Pages和Hexo來發布博客以後,不得不說方便了許多,只須要幾個簡單的命令博客就發佈了。但在不斷的使用中發現每次的發佈操做也挺耗時的。html

我通常的操做是將平時整理好的md文件放到私有的git倉庫中(感興趣可瞭解 Ubuntu-Gogs 用更簡單的方式部署、升級或遷移Gogs服務),每次發佈的時候都要先將文件 clone 到本地,而後配置一下hexo的運行環境,接着再執行 hexo s -g 來預覽和調整,最後執行 hexo d 命令將博客發佈上去,在這以前若是你沒有配置過GitHub的 SSH Key,還要花一些時間來弄權限的問題。長此以往就發現這樣操做起來實在是太繁瑣了。node

後來看到一篇文章介紹可使用Travis CI來自動部署hexo的博客,只須要將md文件 pull 到倉庫中博客就自動發佈好了。趁着這幾天工做任務不太着急,研究了一下,特紀錄在此,但願能幫到有須要的朋友。git

Travis CI 是目前新興的開源持續集成構建項目,用來構建託管在GitHub上的代碼。它提供了多種編程語言的支持,包括Ruby,JavaScript,Java,Scala,PHP,Haskell和Erlang在內的多種語言。github

配置GitHub Pages

若是你是新手或者尚未本身的 GitHub Pages 博客站點,能夠先看我以前的文章 使用GitHub搭建Hexo靜態博客 | IT範兒 瞭解如何配置,具體過程這裏再也不詳述。npm

建立 hexo 分支

由於我以前的博客源文件是存放在私有的git管理工具下,若是咱們要使用Travis CI自動部署,必須將這些博客的源碼文件放到GitHub上才能被Travis訪問到。由於 GitHub Pages 默認要求必須使用 master 分支存放靜態文件,咱們能夠在該倉庫下使用其餘分支來存放博客源碼文件,或者新建立一個倉庫來單獨保存。這裏咱們把hexo博客的源碼放在 hexo 分支下,博客的靜態文件部署在 master 分支下。編程

對於如何在GitHub上建立分支,相關操做命令以下,僅供參考:ubuntu

# 克隆項目到本地
> git clone https://github.com/Leafney/Leafney.github.io.git

# 建立並切換到 hexo 分支
> git checkout -b hexo

當切換到 hexo 分支後,由於咱們是須要用 hexo 分支來存放博客源碼文件的,因此,將 hexo 分支下的文件除 .git 目錄外所有刪除,而後將博客源碼文件拷貝到該目錄下,並 commithexo 分支.緩存

而後咱們須要將本地的 hexo 分支提交到遠程倉庫中ruby

# 提交本地hexo分支到遠程倉庫的hexo分支
> git push origin hexo:hexo

這樣咱們在GitHub的倉庫下就能看到 hexo 分支爲博客源文件,master 分支爲靜態文件。hexo

這裏須要注意一點,當咱們新增博客md文件時,獲取遠程分支時要指定分支的名稱,不然會默認獲取 master 分支:

> git pull origin hexo

設置 Travis CI

使用 GitHub帳戶登陸 Travis CI官網 ,進去後能看到已經自動關聯了 GitHub 上的倉庫。這裏咱們選擇須要啓用的項目,即 yourname/yourname.github.io

而後點擊後面的齒輪圖標進入設置界面。

若是你以前已經勾選過項目,能夠進到項目主頁中,在右上角找到 More options 選項下的 Settings 進入設置界面。


通用設置

General 區域開啓:Build only if .travis.yml is present 表示「只有當 .travis.yml 存在時才構建」 ;開啓:Build branch updates 表示 「當分支更新時構建」 兩個選項,以下:

Travis CI在自動構建完成後須要push靜態文件到倉庫的 master 分支下,而訪問GitHub的倉庫是須要權限的,下面來看看如何配置權限。

配置 Access Token

以下圖,Environment Variables 區域就是用來添加權限信息的。咱們須要填寫一個Token的名稱和值,該名稱能夠在配置文件中以 ${變量名} 來引用,該Token咱們須要從Github中獲取。


從GitHub獲取Access Token

以前咱們在使用命令 hexo d 部署hexo博客到GitHub上時,是由於本地有 SSH key,當交給 Travis 去自動部署時咱們也須要設置可操做權限,這裏咱們使用GitHub提供的token變量來實現。

登錄 GitHub --Settings 選項,找到 Personal access tokens 頁面。

點擊右上角的 Generate new token 按鈕會生成新的token,點擊後提示輸入密碼後繼續,而後來到以下界面,取個名字(我這裏取 Travis_Token 下面的配置文件中會用到),勾選相應權限,這裏只須要 repo 下所有和 user 下的 user:email 便可。

生成完成後,將該token拷貝下來。這裏須要注意的是該token只有這個時候才能看到,當再次進入這個頁面時就只會顯示以前設置的名稱了。若是忘記了只能從新生成一個。


在Travis CI中配置

將上面獲取到的token添加到 Environment Variables 部分,值爲該 token ,而名稱即爲上面設置的 Travis_Token (請更改成我的所設置名稱)。不勾選後面的 Display value in build log . 不然會在日誌文件中暴露你的 token 信息,而日誌文件是公開可見的。

至此咱們已經配置好了要構建的倉庫和訪問的token,接下來就是如何構建的問題了。


建立 .travis.yml 文件

以前的步驟中咱們勾選了一項 Build only if .travis.yml is present,因此咱們要在博客源碼文件的 hexo 分支下新增一個 .travis.yml 配置文件,其內容以下:

language: node_js # 設置語言

node_js: stable # 設置相應版本

install:
    - npm install # 安裝hexo及插件

script:
    - hexo clean # 清除
    - hexo g # 生成

after_script:
    - cd ./public
    - git init
    - git config user.name "yourname" # 修改name
    - git config user.email "your email" # 修改email
    - git add .
    - git commit -m "Travis CI Auto Builder"
    - git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master:master # GH_TOKEN是在Travis中配置token的名稱

branches:
    only:
        - hexo #只監測hexo分支,hexo是個人分支的名稱,可根據本身狀況設置

env:
    global:
        - GH_REF: github.com/yourname/yourname.github.io.git #設置GH_REF,注意更改yourname

注意:須要將配置文件中的 GH_TOKEN 換成咱們本身設定的名稱,這裏個人配置應該是 Travis_Token- git push --force --quiet "https://${Travis_Token}@${GH_REF}" master:master # GH_TOKEN是在Travis中配置token的名稱。 還要更改 GH_REF 中咱們的博客倉庫的地址。

配置文件中的操做也很簡單,這也是網上找到的比較常見的一種配置格式了。然而,這份配置文件中卻隱藏着一個大坑。至於如何跳過去,後面再詳說。


實現自動部署

.travis.yml 配置文件修改完成後,將其提交到遠程倉庫的 hexo 分支下,此時若是以前的配置一切ok,咱們應該能在 Travis CI 的博客項目主頁頁面中看到自動構建已經在開始執行了。上面會顯示出構建過程當中的日誌信息及狀態等。


遇到的問題

問題一:提示 .travis.yml 文件格式錯誤

Travis CI 的日誌文件中,若是遇到下面的錯誤提示,那可能就是 .travis.yml 文件的格式有問題。

ERROR: An error occured while trying to parse your .travis.yml file.
Please make sure that the file is valid YAML.
http://lint.travis-ci.org can check your .travis.yml.
The log message was: Build config file had a parse error: found character that cannot start any token while scanning for the next token at line 6 column 1.

經過在github上查詢,我發現這個問題是我在配置文件中的縮進使用了 tab 鍵致使的。由於在不一樣的編輯器下,tab 鍵表示的寬度可能不一樣。

這裏建議是:不要用 tab 鍵,而是用適當的空格實現縮進


問題二:Travis CI的自動構建成功,可是構建完成後的項目沒有推送到github中
...
...
git commit -m "Travis CI Auto Builder"
git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master:master
remote: Anonymous access to Leafney/Leafney.github.io.git denied.
fatal: Authentication failed for 'https://@github.com/Leafney/Leafney.github.io.git/'

查看日誌提示是權限問題。

這裏的問題是我在 .travis.yml 配置文件中沒有把 ${GH_TOKEN} 部分換成本身在 Travis CI 中填寫的token名稱而致使的。執行時找不到token,也就無法設置權限了。


問題三:master commit 樹被清空 ☆

若是你按照上面的 travis.yml 配置文件的設置去自動構建你的博客,你會發現 master 分支的提交記錄只有當前提交的這一條,並且不管操做多少次,也僅僅只有一條。這還真的是一個大坑呀!

好比下面這位網友的站點: GitHub - hhstore/hhstore.github.io: 我的技術博客master 分支下就只有一條提交記錄。


.travis.yml 部分配置內容:

after_script:
  - cd ./public
  - git init
  - git config user.name "yourname"
  - git config user.email "your email"
  - git add .
  - git commit -m "update"
  - git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master:master

仔細查看上面的配置文件,咱們發現每次都是將 public 目錄下的文件從新生成了一個git項目,而後強制覆蓋提交到了 master 分支下,這就是問題的所在。

爲了解決這個問題,我將配置文件改成了以下的內容:

after_script:
    - git clone https://${GH_REF} .deploy_git
    - cd .deploy_git
    - git checkout master
    - cd ../
    - mv .deploy_git/.git/ ./public/
    - cd ./public
    - git config user.name "yourname"
    - git config user.email "your email"
    - git add .
    - git commit -m "Travis CI Auto Builder"
    - git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master:master

after_script 部分,我先將博客項目 clone 到本地的 .deploy_git 目錄下(目錄名可自定義),而後切換到 master 分支,將 master 分支下的 .git 目錄拷貝到了 public 目錄下,接着繼續後面的 commit 操做。

這裏算是採用了一種 換位 的方式。以前咱們經過git管理文件時並不會改動 .git 目錄,而只是更改文件。但在這種狀況下,咱們須要提交的是 public 目錄下的新文件。這樣,就會保留以前的提交記錄了。


附上我在使用的配置文件內容:

language: node_js # 設置語言

node_js: stable # 設置相應版本

cache:
    apt: true
    directories:
        - node_modules # 緩存不常常更改的內容

before_install:
    - npm install hexo-cli -g

install:
    - npm install # 安裝hexo及插件

script:
    - hexo clean # 清除
    - hexo g # 生成

after_script:
    - git clone https://${GH_REF} .deploy_git
    - cd .deploy_git
    - git checkout master
    - cd ../
    - mv .deploy_git/.git/ ./public/
    - cd ./public
    - git config user.name "yourname"
    - git config user.email "your email"
    - git add .
    - git commit -m "Travis CI Auto Builder"
    - git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master:master

branches:
    only:
        - hexo # 只監測hexo分支

env:
    global:
        - GH_REF: github.com/yourname/yourname.github.io.git #設置GH_REF,注意更改爲本身的倉庫地址

注意上面配置文件中的某些參數改成本身的。


問題四:使用 x-oauth-basic

在網上看到一位網友解決 「master commit 樹被清空」 的問題時採用了另一種方法,即在 after_script 部分調用執行 hexo d 命令來發布。這樣的方式遇到的問題是須要設置 SSH Key 或者必須得到權限才能進行 push 操做。

有一種受權的方式是經過https使用OAuth驗證的方式將token添加到url中來提交。即須要更改 _config.yml 中的以下部分:

## Docs: https://hexo.io/docs/deployment.html
deploy:
  type: git
  repository: git@github.com:Leafney/Leafney.github.io.git
  branch: master

爲:

## Docs: https://hexo.io/docs/deployment.html
deploy:
  type: git
  repository: https://<token>:x-oauth-basic@github.com/owner/repo.git
  branch: master

而這樣一來 token 就暴露在配置文件中了。因此還須要在操做命令中使用替換的方式只在自動部署時更改該token。

這裏僅作介紹,更詳細可訪問:


問題五:git branch 分支操做相關命令
# 查看本地全部分支(分之名稱前面帶*表示當前分支)
> git branch

# 查看遠程全部分支
> git branch -r

# 建立分支 blog
> git branch blog

# 切換到 blog 分支
> git checkout blog

# 建立並切換到新分支
> git checkout -b blog

# 刪除分支
> git branch -d blog

# 提交本地test分支做爲遠程的test分支
> git push origin test:test

# 合併分支(將名稱爲[blog]的分支與當前分支合併)
> git merge blog

# 獲取遠程指定分支
> git pull origin blog

相關參考


該文章同步發表在:

相關文章
相關標籤/搜索