我的方案由以下兩個核心部分:
- 博客源倉庫,對博客配置及所有文章 .md 源文件進行版本管理,配合 GitHub Action 進行自動化部署,自動生成靜態站點推送到 GitHub Pages 博客發布倉庫。
- GitHub Pages 博客發布倉庫,使用 GitHub Pages 實現網站部署,可以通過域名 CNAME 解析使用自定義域名。
使用 Hugo 搭建博客#
Hugo 是用 Go 實現的博客工具,採用 Markdown 進行文章編輯,生成靜態站點文件,支持豐富的主題配置,也可以通過 js 嵌入像是評論系統等插件,高度定制化。除了 Hugo 外,還有 Gatsby、Jekyll、Hexo、Ghost 等選擇,實現和使用都差不多,可以根據自己的偏好進行選擇。
安裝 Hugo#
我使用的是 macOS,所以使用官方推薦的 homebrew 方式進行 hugo 程序的安裝,其他系統可參考官方文檔。
brew install hugo
完成後,使用以下命令進行驗證 (查看版本號):
hugo version
創建 Hugo 網站#
hugo new site blog-demo
配置主題#
創建我們的站點後,需要進行主題配置,Hugo 社區有很豐富的主題,可以通過官網 Themes 菜單選擇自己喜歡的風格,查看預覽效果,選擇後可以進入主題項目倉庫,一般都會有很詳細的安裝及配置說明。下面我就以我目前在使用的 smol 這個主題為例,演示一下配置流程。
cd blog-demo
git clone [email protected]:colorchestra/smol.git themes/smol
cd themes/smol
rm -rf .git
初始化主題基礎配置後,我們可以在 config.toml 文件中進行站點細節配置,具體配置項參考主題說明文檔。
參考 config.toml 內容
theme = "smol"
發布新文章#
hugo new posts/blog-test.md
本地調試站點#
進行本地實時調試預覽。
hugo server
運行服務後,我們可以通過瀏覽器 http://localhost:1313 地址訪問我們的本地預覽網頁。
GITHUB PAGES 倉庫#
GitHub Pages 倉庫建立完成後,可以在設置中配置自己註冊的自定義域名來指向 GitHub Pages 生成的網址。此外,需要將博客站點配置文件 config.toml 中的 baseURL 改為自己的自定義域名。
GitHub Pages 發布博客#
我們現在已經可以通過自定義域名來訪問我們的 GitHub Pages 頁面了,目前因為項目倉庫是空的,訪問後會報 404 頁面。
Hugo 生成的靜態網站通過 GitHub Pages 服務進行托管,因此我們需要上傳 Hugo 生成的靜態網頁文件至 GitHub Page 項目倉庫。
手動發布#
hugo
cd public
Hugo 默認會將生成的靜態網頁文件存放在 public/ 目錄下,我們可以通過將 public/ 目錄初始化為 git 倉庫並關聯我們的 clin003/blog_html 遠程倉庫來推送我們的網頁靜態文件。
git init
git remote add origin [email protected]:baicaime/meBlog
git add .
git commit -m "debug"
git push origin main
推送到 GitHub Pages 倉庫,稍等幾分鐘即可通過我們的自定義域名來訪問我們的博客站點了,和
hugo server
本地調試完全一致。
自動發布#
因為我們的博客基於 GitHub 與 GitHub Pages,可以通過官方提供的 GitHub Action 進行 CI 自動發布。
GitHub Action 是一個持續集成和持續交付 (CI/CD) 平台,可用於自動執行構建、測試和部署管道,可以通過簡單的配置即可直接使用。
配置在倉庫目錄
.github/workflows
下,以 .yml 為後綴。我的 GitHub Action 配置為
deploy.yml
自動發布示例配置如下:
name: Deploy Hugo site to Pages
on:
push:
branches: [ "main" ]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
defaults:
run:
shell: bash
env:
NAME: BLOG_push
# 推送目標倉庫 格式 用戶名/倉庫名
TARGET_REPOSITORY_NAME: baicaime/meBlog
# 同步臨時目錄(可選)
CLONE_DIR: tmp_public
# 構建臨時目錄(可選)
BUILD_DIR: tmp_build
# 配置git用戶名
GIT_USERNAME: baicaime
jobs:
# This workflow contains a single job called "build"
build:
runs-on: ubuntu-latest
env:
HUGO_VERSION: 0.117.0
steps:
- name: Install Hugo CLI
run: |
wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
&& sudo dpkg -i ${{ runner.temp }}/hugo.deb
- uses: actions/checkout@v3
- name: Build with Hugo
env:
# For maximum backward compatibility with Hugo modules
HUGO_ENVIRONMENT: production
HUGO_ENV: production
run: |
hugo \
--minify \
--baseURL "${{ steps.pages.outputs.base_url }}/" \
-d ${{ env.BUILD_DIR }}
- name: Git Config
run: |
git config --global user.email "[email protected]"
git config --global user.name "${{ env.GIT_USERNAME }}"
echo "配置git完成"
- name: Git clone
run: |
echo "同步目標倉庫(開始)"
git clone --depth 1 https://github.com/${{ env.TARGET_REPOSITORY_NAME }}.git ${{ env.CLONE_DIR }} &> /dev/null
echo "同步目標倉庫(完成)"
- name: Git push
run: |
cp -rf ${{ env.BUILD_DIR }}/* ${{ env.CLONE_DIR }}/
cd ${{ env.CLONE_DIR }}
echo "${{ github.event.head_commit.message }} `date +%FT%T%z`" > _pub_time.html
git add .
git commit --message "Update ${{ env.NAME }} from ${{ env.TARGET_REPOSITORY_NAME }} ${{ github.event.head_commit.message }}"
git push -f -q https://oauth2:${{ secrets.GIT_TOKEN }}@github.com/${{ env.TARGET_REPOSITORY_NAME }}.git main
echo "git push ${{ env.TARGET_REPOSITORY_NAME }} (完成)"
on 表示 GitHub Action 觸發條件,我設置了 push 和 workflow_dispatch 兩個條件:
- push,當這個項目倉庫發生推送動作後,執行 GitHub Action
- workflow_dispatch,可以在 GitHub 項目倉庫的 Action 工具欄進行手動調用
jobs 表示 GitHub Action 中的任務,我們設置了一個 build 任務,
runs-on 表示 GitHub Action 運行環境,我們選擇了 ubuntu-latest。
build 任務包含了 Install Hugo CLI 、Checkout、Build with Hugo、Git Config、Git clone 和 Git push 六個主要步驟,
其中 run 是執行的命令,uses 是 GitHub Action 中的一個插件,我們使用了 actions/checkout 這個插件。
其中 Checkout 步驟中,可以在 with 中配置 submodules 值為 true 同步博客源倉庫的子模塊(比如主題模塊,由於我們沒有使用子模塊方式安裝 hugo 主題,所以不需要這個參數)。
需要將上述 deploy.yml 中:#
TARGET_REPOSITORY_NAME 改為自己的 GitHub Pages 倉庫,如我的設置為 baicaime/meBlog
GIT_USERNAME 改為自己 GitHub Pages 倉庫的用戶名
因為我們需要從博客倉庫推送到外部 GitHub Pages 倉庫,需要特定權限,要在 GitHub 賬戶下 Setting - Developer setting - Personal access tokens 下創建一個 Token。
權限需要:
Contents read/write
配置後複製生成的 Token(注:只會出現一次),然後在博客源倉庫的
Settings - secrets and variables - Actions
中添加
GIT_TOKEN
環境變量為剛才的 Token,這樣 GitHub Action 就可以獲取到 Token 了。
推送測試#
完成上述配置後,推送代碼至倉庫,即可觸發 GitHub Action,自動生成博客頁面並推送至 GitHub Pages 倉庫。
GitHub Pages 倉庫更新後,又會自動觸發官方頁面部署 CI,實現網站發布。
現在每當我們本地通過熟悉的 Markdown 語法完成博客內容編輯後,只需要推送代碼,等待幾分鐘,即可通過我們的自定義域名訪問更新後的網站。
以上就是我通過 Hugo 與 GitHub Action 實現的博客自動部署系統,我自己的實現倉庫在 baicaime/meBlog 倉庫中