基本原理
创建一个 Hugo 博客需要一些源文件,然后使用 hugo 命令将这些源文件编译为静态 html 文件,实际发布的博客是这些静态 html 文件
期望实现的效果是,我们在本地只需要维护这些源文件,然后在 github 中保存一份源文件,同时每当我们推送更新时,在 github 端完成 hugo 的编译过程
这样的好处时,我们无需在本地完成 hugo 编译过程,只管博客内容编辑即可,并且在机器迁移时,只需要同步这些源文件即可,可以减少同步文件的数量
为了外界能够访问到,hugo 编译的文件一定是保存在一个 public 仓库中的,根据源文件存储的仓库类型可以分为两种实现方式:
- 源文件 和 hugo 编译后文件保存在同一个 public 仓库中
- 源文件保存在一个 private 仓库中,hugo 编译后的文件保存在一个 public 仓库中
仓库设置
假设 源文件 存储在 private repository A,由 A 使用 hugo 进行编译,并且将编译后的文件推送到 public repository B
在 A 中除了增加 action 之外,还需要在 setting 中设置一个 key,具体类型和方法在 action 实现中都有说明
对于 B 来说,由于 A 推送过来的内容已经是可以直接展示的静态文件了,所以 B 直接在 setting 中设置一个 pages,选择展示 gh-pages 分支即可,实际上似乎当我们设置分支名称是 gh-pages 时,它就会自动开启 github pages,只需要稍微等一小会就可以看到效果了
action 实现
在实际实现时,难点实际就是如何使用 github action 完成 hugo 的编译
方式 1 和 方式 2 的区别只是在于,在 hugo 编译完成后,将需要发布的文件 push 到哪里
其实下面使用的 actions/checkout@v3
, peaceiris/actions-hugo@v2
, peaceiris/actions-gh-pages@v3
可以看为一种封装好的工具,比如说最后一步的文件推送,我们自己写 git 命令也一样可以实现,不过这些工具对命令进行了封装,更加易用
方式1 workflow 实现
需要注意的是,由于方式 1 只涉及到访问当前仓库,所以不需要额外权限。其中的github_token无需我们手动配置,工具会自行生成。
name: GitHub Pages
on:
push:
branches:
- main # Set a branch name to trigger deployment
pull_request:
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v3
with:
submodules: true # Fetch Hugo themes (true OR recursive)
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: 'latest'
extended: true
- name: Build
run: hugo --minify
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
方式 2 workflow 实现
peaceiris/actions-gh-pages@v3 文档 - 如何将内容推送到外部仓库
与方式 1 不同的是,此时涉及到访问外部仓库,因此需要额外权限,所需要使用的 key 就发生了变化,按理说,此时使用 deploy_key 和 personal_token 均可,但是实测只能使用 personal_token
-
personal_token的生成方法(使用到的 PERSONAL_TOKEN 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)
name: GitHub Pages
on:
push:
branches:
- main # Set a branch name to trigger deployment
pull_request:
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Get blog source files from github to machine
uses: actions/checkout@v3
with:
submodules: true # Fetch Hugo themes (true OR recursive)
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: 'latest'
extended: true
- name: Build
run: hugo --minify
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
personal_token: ${{ secrets.PERSONAL_TOKEN }}
external_repository: gaohongy/blog-test
publish_branch: gh-pages # default: gh-pages
publish_dir: ./public
这里要理解publish_branch 和 publish_dir,前者是要把文件推送到 gaohony/blog-test仓库的gh-pages分支下,后者的意思是把 hugo 编译结果中的 public 文件夹推送到gh-pages分支下
这样我们只需要向当前private仓库推送文件,actions 就可以首先完成 hugo 编译,然后把生成的文件推送到一个public仓库下
本地内容在不同仓库间迁移
假设之前的本地代码对应远程仓库A,现在期望切换到远程仓库B
只需要 git remote set-url origin <B address>
然后正常提交即可,这样操作 git log 还能够保留(因为这些内容都是存储在 .github 文件夹下的文件当中的)