0%

[CI/CD] Hexo + GitHub Actions 自動化部署

Hexo + GitHub Actions 利用 CI/CD 自動化部署


我算是 Hexo 新手,在建立 blog 時需要多多爬文才能解決我遇到的問題或是新增功能,剛好在學校學到 CI/CD 相關概念,在這之前一直是以手動佈署的方式(每次都要打 hexo d -g)發文,一開始還沒感覺,當文章數量變多時,光是等 hexo 重新生成靜態頁面後再部署到 GitHub 太久又太麻煩,因此決定使用自動化部署流程。

因為遇到一些問題,為了幫助可能遇到也跟我一樣問題的人,寫了這篇文~

有遇到任何問題,也可以在下方留言板聯絡我!

GitHub Actions 介紹


首先介紹 GitHub Acitons 是什麼,參考自連結

原因: GitHub Actions 是 GitHub 的整合產品,不用額外申請帳號,並且很快,還可以支援 private repo!

簡單介紹

  • 目前常見的 CI/CD 服務平台是 Travis CI 跟 Jenkins

    • Travis CI 適用於開源專案,有很多 Hexo 自動化部署的參考文獻,不過不支援 GitHub private repo,所以本篇文沒有使用這個。
    • Jenkins 常用於大型專案,功能完整且有大量的 plugin,使用者也很多。
  • GitHub Actions 由 GitHub 官方在2018年10月推出的自動化流程工具,也就是 CI/CD 服務,目前已經開放公有、私有 repo 使用。

    • CI/CD: Continuous Integrataion 持續整合和 Continuous Deployment 持續部署,也就是把程式流程自動化,push 到 repo 後自動 bulid、自動跑測試、自動部署,都十分重要,由很多步驟與流程組成,而 GitHub Actions 將這些步驟稱為 Actions
      • 實作 CI/CD: 寫設定檔(通常為 yml 或 json,關於 yaml 檔後續會開一篇介紹)後,由 CI/CD 服務來進行對應的操作,就是 Infrastructire as Code(IaC) 的實踐。
      • 在寫程式時,要常注意是否遵守 DRY(Do Not Repeat Yourself) 原則,把共用的部分變成一個 module 或 function,在 CI/CD 中也是相同的概念,許多操作在不同 project 是類似的或相同的,可以提出共享。
    • 因此 GitHub Actions 可以把自己寫的 Actions 發布到公開的 Marketplace,讓別的開發者可以直接飲用,並且也能有多個版本,類似於 GitHub 或 Docker Hub。

Github Actions 基本元素

在 GitHub Actions 中,有幾個重要的元素,由大至小為:

1
Workflow > Job > Step > Action
  • Workflow: CI/CD 一次要運行的整個過程,一個 workflow 會涵蓋多個 Job、Step、Action
  • Job: 代表「任務」,一個 workflow 由多個 job 組成,相對一個 workflow 可以完成多個任務。
  • Step: 代表「步驟」,一個 job 由多個 step 組成,也就是一步一步完一個 job。
  • Action: 代表「命令」或「動作」,每個 step 可以依序執行多個命令。

GitHub Actions Workflow Config

要啟用 GitHub Actions,不用太複雜的設定,只要在專案的根目錄新增 .github/workflow/xxx.yml,push 到 GitHub 上後就會自動執行放在該路徑裡的 .yml config 檔 (workflow document 採 YAML 格式)。可以創建很多個 .yml,GitHub 就會執行多個 workflow。

Config 更多語法可以參閱官方文件
舉接下來會用到的設定檔來說:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
## 幫這個 workflow 取名,預設為 .yml 檔名
name: 'hexo deploy'

## 監聽 main 分支若有 push 行為就執行 jobs
## 也就是 workflow 的觸發條件,也有像是 schedule 等觸發條件
## Docs: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows
on:
push:
branches:
- main
## 可以有多個 jobs,原則上會平行執行,若沒有則按照順序
## job 也可以有多個 steps
jobs:
## 這邊 build 代表 job 的名稱
build:
## 指定要運行的環境
runs-on: ubuntu-latest
## 定義真正要執行的指令
## name: 方便 debug,名字可以自己定義
## uses: 直接使用其他開發者寫好的 actions
## Docs: https://github.com/actions/checkout
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Use Node.js 12.x
uses: actions/setup-node@v1
with:
node-version: "12.x"
- name: init)init ssh
run: |
...
- name: A)npm install -g hexo-cli
run: |
npm install -g hexo-cli
- name: B)npm install
run: |
npm install
- name: C) hexo d -g
run: |
hexo d -g

Hexo + GitHub Actions 自動化部署步驟


GitHub Repository

Repository 操作 說明
https://github.com/kenchen879/xxx 建立一個倉儲,把原本 hexo 的 source code 放進去 名字隨便取,可以是 private
https://github.com/kenchen879.github.io GitHub Actions 會把靜態網頁部署到這 名字固定,要是 public

生成 SSG 部署金鑰

首先在 terminal 利用 ssh-keygen 生成一組金鑰,包含私鑰(github-deploy-key)和公鑰(github-deploy-key.pub)。

名稱可以自己取

1
ssh-keygen -f github-deploy-key

在 Mac OS 下用這個指令產生金鑰會出現問題(permission denied),所以建議可以利用 GitHub 裡面產生 token,或是另外查詢 Mac 產生金鑰的方法。

設置 repo

HexoBlog (存放 source code 的 repo)

在存放 source code 的 repo 中,步驟如下
repo -> Settings -> Secrets -> Actions -> New repository secret
private
new key

Name: 可以自己取,但後面設定 config 檔時要記得這個名稱!
Value: 放剛剛產生的私鑰 github-deploy-key 的內容

kenchen879.github.io (存放靜態網頁的repo)

裡面的檔案設定好下列步驟後都不用動,會自動部署到 GitHub Pages,步驟如下
repo -> Settings -> Deploy keys -> Add deploy key

Name: 可以自己取
Value: 放剛剛產生的公鑰 github-deploy-key.pub 的內容

設定 config file

上面兩個設定好後,開啟 source code,並在根目錄下建立 .github/workflow/hexoActions.yml,就是上面說的 workflow,接下來 GitHub Actions 會抓取裡面的檔案內容執行動作。

hexoActions.yml 如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
name: 'hexo deploy'
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Use Node.js 12.x
uses: actions/setup-node@v1
with:
node-version: "12.x"
- name: init)init ssh
run: |
mkdir -p ~/.ssh/
echo "${{secrets.xxx}}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
git config --global user.name "xxx"
git config --global user.email "xxx@gmail.com"
- name: A)npm install -g hexo-cli
run: |
npm install -g hexo-cli
- name: B)npm install
run: |
npm install
- name: C) hexo d -g
run: |
hexo d -g

secrets.xxx: 剛剛在 GitHub 設定的私鑰名稱
user.name "xxx": 使用者名稱
user.email "xxx@gmail.com": 使用者電子郵件

修改在根目錄下的 _config.yml

將 http 改成 ssh 才可以,因為是從 private repo. 自動化操作的,透過 ssh 進行連接。

1
2
3
4
deploy:
type: git
repo: git@github.com:xxx/xxx.github.io.git
branch: master

branch: master: 也可以是 branch: main

刪掉 themes/next 下的 .git

這點要特別注意,如果沒有做,當 GitHub Actions 自動部署到 GitHub Pages 時,產生的頁面會都是空白!

當時我在這裡花費不少時間,因為主題 next 是 git clone 下來的,所以產生了 .git,會和 hexo 根目錄下的 .git 衝突,會使 commit 沒有把主題 push 上去而產生空白頁面。

如果仍沒有辦法,將 themes/next 先移出去,然後 commit 一次後,再將 themes/next 移回來就成功了。

GitHub Actions 流程

結論


困難與挑戰

用 GitHub Actions 這個 CI/CD 的服務聽起來很方便,而且感覺也不難,但實際在執行時會遇到種種問題:

  • workflow 的設定檔很嚴謹,要很注意縮排或是有沒有空格,可能都會出錯
  • GitHub 上公私鑰的設定名稱鑰自己記得打了什麼,在 .yml 裡就是什麼
  • 特別注意 /themes/next 下的 .git 要刪掉,不然會被空白頁面搞瘋

心得

爬了很多文,終於讓我成功使用 GitHub Actions 進行 CI/CD 嚕 ~

原因如下

  • 因為當部落格的數量越來越龐大,在本地端要產生靜態頁面(hexo g)並部署(hexo d)會花費太多時間和資源,並且我也懶得一直打 hexo g -d
  • 當有文章還不想部署時,可以先不用 push 到 repo 中,進行隱藏只給自己在本地端修改和查看。

剛好看到一篇文章,讓我學習到怎麼用 GitHub Actions 來進行 CI/CD,下篇我會針對 Cloud Native 相關知識進行補充。

謝謝各位看到最後,當你/妳需要任何的協助,歡迎在下面留言板留言(或是直接 mail 給我)~

參考