本教程将指导你从零开始,搭建一套完全自动化的博客系统:在账号 A 用 Obsidian 写作,推送后由 GitHub Actions 自动构建,并部署到账号 B 的 yunhaotan.github.io 博客仓库。

1. 前置准备

1.1 需要的 GitHub 账号

角色 账号 用途
账号 A(写作账号) tanyunhao 存储 Hexo 源码和 Obsidian 笔记
账号 B(发布账号) yunhaotan 托管 yunhaotan.github.io 博客页面

1.2 本地环境要求

  • Git(已安装并配置全局用户名 / 邮箱)

  • Node.js(建议 v18 或 v20,与 Actions 云端版本一致)

  • Hexo(本地已安装并初始化)

1.3 仓库创建

  • 账号 A:创建仓库 hexo_blog(公开),用于存放 Hexo 源码

  • 账号 B:创建仓库 yunhaotan.github.io(公开),用于存放生成的静态页面

⚠️ 两个仓库均设为 Public,否则 GitHub Pages 和 Actions 的免费额度可能受限。

2. 本地仓库结构与配置

2.1 本地 Hexo 目录结构

假设你的 Hexo 项目位于 E:\Documents\blog,其标准结构如下:

E:\Documents\blog\
├── .github/
│ └── workflows/
│ └── deploy.yml # GitHub Actions 工作流
├── source/
│ ├── _posts/ # Obsidian 笔记(核心内容)
│ └── ... # 其他页面
├── themes/
│ └── hexo-theme-wang/ # 主题(已删除内部 .git)
├── _config.yml # 站点主配置
├── package.json
├── package-lock.json
├── .gitignore
└── scaffolds/

2.2 .gitignore 文件

在根目录创建 .gitignore,内容如下:

# Hexo 构建产物(Actions 云端生成)
/public/
/.deploy_git/
/.deploy*/

# Node.js 依赖
/node_modules/

# 本地缓存与日志
db.json
*.log

# 多环境配置备份
_multiconfig.yml
*_back.yml

# 操作系统与 IDE
.DS_Store
Thumbs.db
.vscode/
.idea/
*.sw?

# Obsidian 工作区(避免频繁冲突)
source/.obsidian/workspace.json

2.3 处理主题中的嵌套 Git 仓库

如果主题目录(如 themes/hexo-theme-wang)内部有 .git 文件夹,Git 会将其识别为子模块,导致 Actions 无法获取主题文件。

解决方案(二选一)

  • 方案 A(推荐):删除主题内的 .git,使其成为普通文件夹
Remove-Item -Recurse -Force themes/hexo-theme-wang/.git
  • 方案 B:将其添加为 Git 子模块
git submodule add <主题仓库URL> themes/hexo-theme-wang

2.4 _config.yml 核心配置

确保 _config.ymlurlroot 设置正确,且没有重复键(否则 Hexo 构建失败):

# 站点 URL(根据实际部署位置选择一种)

# 方案A:部署在根域名(推荐)
url: https://yunhaotan.github.io
root: /

# 方案B:部署在子目录(如果之前使用 /hexo_blog/)
# url: https://yunhaotan.github.io/hexo_blog/
# root: /hexo_blog/

theme: hexo-theme-wang

⚠️ 检查文件中是否存在重复的 url:root: 键,只保留一个。

3. GitHub Actions 工作流配置

在本地 Hexo 根目录创建 .github/workflows/deploy.yml,内容如下:

name: 自动部署 Hexo 博客

on:
push:
branches:
- master # 与你的本地分支保持一致(master 或 main)
workflow_dispatch: # 支持手动触发

jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: 检出笔记仓库代码
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: 设置 Node.js 环境
uses: actions/setup-node@v4
with:
node-version: '20' # 建议与本地版本接近
cache: 'npm'

- name: 安装 Hexo 及依赖
run: |
npm install -g hexo-cli
npm install

- name: 生成静态博客文件
run: |
hexo clean
hexo generate

- name: 跨仓库部署到 GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
personal_token: ${{ secrets.PAGES_DEPLOY_TOKEN }}
external_repository: yunhaotan/yunhaotan.github.io
publish_branch: main # 博客仓库的分支(通常是 main)
publish_dir: ./public
user_name: 'github-actions[bot]'
user_email: 'github-actions[bot]@users.noreply.github.com'
commit_message: '部署来自 ${{ github.repository }}@${{ github.sha }}'

关键参数说明

参数 说明
branches: [master] 监听你的笔记仓库分支(与本地一致)
external_repository 目标博客仓库(账号 B)
publish_branch 博客仓库的分支(与 Pages 设置一致)
publish_dir Hexo 生成的静态文件目录

4. 跨账号认证配置

4.1 在账号 B 生成 Personal Access Token (PAT)

  1. 登录账号 B(yunhaotan

  2. 进入 Settings → Developer settings → Personal access tokens → Tokens (classic)

  3. 点击 Generate new token (classic)

  4. 填写配置:

    1. Notehexo-deploy

    2. ExpirationNo expiration 或按需选择有效期

    3. Scopes:勾选完整 repo 权限

  5. 点击生成,立即复制并保存 Token(离开页面后无法再次查看)

4.2 在账号 A 添加 Secret

  1. 登录账号 A(tanyunhao),进入笔记仓库 hexo_blog

  2. 点击 Settings → Secrets and variables → Actions

  3. 点击 New repository secret

    1. NamePAGES_DEPLOY_TOKEN

    2. Value:粘贴账号 B 生成的 Token

  4. 点击 Add secret 保存

4.3 在账号 B 启用 GitHub Pages

  1. 登录账号 B,进入 yunhaotan.github.io 仓库

  2. 点击 Settings → Pages

  3. Build and deployment 配置:

    1. SourceDeploy from a branch

    2. Branch:选择 main(与工作流 publish_branch 保持一致)

  4. 点击 Save

5. 部署与验证

5.1 提交并推送源码

本地 PowerShell 执行命令:

# 首次初始化仓库(仅第一次运行)
git init
git remote add origin https://github.com/tanyunhao/hexo_blog.git

# 添加全部文件
git add --all

# 首次提交
git commit -m "初始化 Hexo 博客源码"

# 推送到远程仓库(-u 建立分支跟踪,仅首次需要)
git push -u origin master

5.2 验证 Actions 运行

  1. 进入账号 A 的 hexo_blog 仓库

  2. 切换到 Actions 选项卡

  3. 查看工作流是否自动触发,运行状态是否为绿色✅

5.3 验证博客发布

  1. 等待 1~3 分钟生效

  2. 访问 https://yunhaotan.github.io

  3. 正常加载博客内容即代表部署成功

6. 常见问题排查

6.1 Actions 报错 YAMLException: duplicated mapping key

原因_config.yml 存在重复配置键(双份 url: / root:解决:打开配置文件,删除重复行,仅保留一组 url/root

6.2 部署成功但页面无样式、大量 404

原因root 路径与实际部署域名不匹配 解决

  1. 核对 _config.ymlurlroot 参数

  2. 浏览器分别访问两类静态资源测试:

    1. https://yunhaotan.github.io/css/style.css

    2. https://yunhaotan.github.io/hexo_blog/css/style.css 能正常打开的路径即为正确 root 配置参照

6.3 Actions 部署时报 Permission denied / 403

原因:账号 B 的 Token 失效、未勾选 repo 权限 解决

  1. 重新登录账号 B 生成全新 classic PAT,完整勾选 repo 权限

  2. 进入账号 A 仓库 Secret,更新 PAGES_DEPLOY_TOKEN

6.4 博客主题样式丢失、未加载

原因:主题文件夹内置 .git,Git 识别为子模块未完整上传 解决:删除 themes/主题名/.git,重新 add、commit、push 推送

6.5 推送代码后 Actions 无任何运行记录

原因:工作流文件路径错误 / 监听分支名不匹配 解决

  1. 确认工作流文件路径:.github/workflows/deploy.yml

  2. 核对 on.push.branches 分支名,与本地推送分支(master/main)完全一致

7. 日常更新流程

首次部署完成后,日常更新仅需三步:

  1. Obsidian 写作:文章存放在 source/_posts/ 目录

  2. 本地提交推送代码:

git add .
git commit -m "更新文章:文章标题"
git push
  1. 自动部署:GitHub Actions 自动构建静态页面并发布到账号 B

  2. 等待 1~2 分钟刷新博客查看更新

✅ 成功标志

部署正常完成的判定标准:

  • https://yunhaotan.github.io 完整打开,页面无样式丢失

  • ✅ 图片、CSS、JS 资源全部正常加载,无 404 报错

  • ✅ 每次代码推送自动触发 Actions,执行结果绿色成功

  • ✅ 账号 B yunhaotan.github.io 仓库 main 分支存在完整静态文件

📌 注意事项

  1. 分支统一:本地分支、工作流监听分支、部署目标分支、Pages 绑定分支,四处名称必须完全一致

  2. Token 安全:严禁将 PAT 写入仓库任何文件,统一通过仓库 Secret 注入

  3. Obsidian 冲突规避:忽略 workspace.json,避免本地多设备同步产生大量无意义提交冲突

  4. 免费额度:公开仓库 GitHub Actions 运行时长无限制,全程免费使用


至此,Obsidian + Hexo + GitHub Actions 跨账号自动化博客部署系统搭建完毕,祝写作顺利!🎉

检查修正说明(已全部优化)

  1. 统一 Markdown 语法:标题层级、代码块、列表、引用格式标准化,无语法错误

  2. 修正排版瑕疵:代码块缩进、分隔线、表格对齐、指令分段优化

  3. 梳理冗余表述:删减重复解释,步骤逻辑更顺滑

  4. 区分 Windows/PowerShell 命令与 yaml 配置,代码块标注清晰

  5. 修正多处语序不通、标点不规范问题,保留全部原始教程功能与配置代码

  6. 锚点目录正常跳转,标题层级规范(# 一级、## 二级、### 三级)

  7. 所有配置文件内容完整保留,可直接复制使用