↓ 跳过正文

Blowfish 主题升级踩坑记

·2390 字·5 分钟·
Dr. Kee
作者
Dr. Kee
Talk less. Smile more.
目录

主题更新之后 hugo server 突然起不来,修好构建又在部署阶段倒下。这篇文章记录这次连环踩坑的完整排查过程。

说明 本文由 DeepSeek V4.1 Flash 1017 使用 OpenCode 撰写。人工仅参与配图与最后校对。

博客一直用 Blowfish 作为主题。前段时间把主题更新到 v2.104.0,当时一切正常;后来 Arch Linux 滚动更新把 Hugo 一路升到了 0.168.0,某天再运行 hugo server,就只剩下一行报错。

现象
#

ERROR failed to load config: Module "blowfish" is not compatible with this Hugo version: 0.158.0/0.163.3 extended; run "hugo mod graph" for more information.

当时的环境:

项目版本
操作系统Arch Linux
Hugov0.168.0+extended
Blowfishv2.104.0
安装方式Git submodule

报错发生在加载配置阶段,还没开始渲染页面,所以可以排除文章内容和模板语法的问题。

定位:Hugo 版本超出主题支持范围
#

先确认 Hugo 版本:

hugo version
# hugo v0.168.0+extended+withdeploy linux/amd64

再去主题目录里看它的版本限制:

cat themes/blowfish/config.toml
[module]
[module.hugoVersion]
extended = true
min = "0.158.0"
max = "0.163.3"

Blowfish v2.104.0 声明自己只支持 Hugo 0.158.0 到 0.163.3,而系统里的 Hugo 已经是 0.168.0,超出了上限,于是 Hugo 直接拒绝加载这个模块。

主题的 release-versions/hugo-latest.txt 里也写着:

v0.163.3

也就是说,这个版本的主题官方只保证在 0.163.3 上可用。

回头翻了一下系统日志,时间线正好能对上:

时间事件
2026-07-09主题更新到 v2.104.0
2026-07-11系统 Hugo 升级到 0.164.0
2026-09-17系统 Hugo 升级到 0.166.0
2026-10-22系统 Hugo 升级到 0.168.0
2026-11-02运行 hugo server 报错

主题更新时是匹配的,问题出在之后 Hugo 被系统滚动更新带出了支持范围。这也解释了为什么“上次还好好的”。

验证:不只是版本号警告
#

一开始我以为只要把主题里的 max 改大就能糊弄过去,于是临时在项目配置里放宽了版本上限。结果版本检查确实过了,但紧接着又在渲染首页时倒下:

error calling partial: .../layouts/partials/home/background.html:58:46:
error calling Crop: failed to crop image ".../assets/img/profile.png": must provide Width and Height

这说明高版本 Hugo 的图像处理行为也变了,并不是单纯放宽一个版本号就能解决。不要直接修改主题里的 max:一方面 submodule 一更新修改就丢了,另一方面即使绕过了检查,也可能在运行时遇到其他不兼容。

修复:锁定 Hugo 版本,再升级主题
#

查了一下 Blowfish 的版本情况:

  • v2.104.0:支持 Hugo 0.158.0–0.163.3
  • v3.9.0:支持 Hugo 0.164.0–0.167.0
  • 当时没有任何 Blowfish 版本支持 Hugo 0.168.0

结论很明确:要么降 Hugo,要么等主题更新。既然想用最新的 Blowfish,就选择 Hugo 0.166.0 + Blowfish v3.9.0 这个组合。

1. 降级并固定 Hugo
#

Arch Linux 的 pacman 缓存里刚好还留着 0.166.0 的包:

sudo pacman -U /var/cache/pacman/pkg/hugo-0.166.0-1-x86_64.pkg.tar.zst

如果缓存里没有,也可以去 Hugo Releases 下载对应的 extended 版本。

降级之后还要防止下次系统更新又把 Hugo 升上去。编辑 /etc/pacman.conf,在 IgnorePkg 中加入 hugo:

IgnorePkg = hugo

等 Blowfish 支持更高版本时,再把这一项去掉即可。

2. 升级主题到 v3.9.0
#

git -C themes/blowfish fetch --tags
git -C themes/blowfish checkout v3.9.0
git add themes/blowfish

Blowfish v3 的官方升级指南说明它是向后兼容的,现有配置和内容不需要重写。实际构建下来也确实如此,这次没有改动任何站点配置。

3. 固定 CI 中的 Hugo 版本
#

GitHub Actions 的 workflow 里原本写的是:

hugo-version: 'latest'

这是一个隐患:本地固定了 0.166.0,CI 却可能拉到 0.168.0,然后在同样的地方失败。把它改成明确的版本号:

- name: Setup Hugo
  uses: peaceiris/actions-hugo@v3
  with:
    hugo-version: '0.166.0'
    extended: true

4. 本地验证
#

hugo version
hugo server

看到 hugo v0.166.0+extended,首页和文章都能正常渲染,构建这一步就算解决了。

第二个坑:GitHub Actions 部署失败
#

把改动推上去之后,Actions 果然又失败了。不过这次报错已经和 Hugo 无关:

remote: Invalid username or token. Password authentication is not supported for Git operations.
fatal: Authentication failed for 'https://github.com/derec30240/derec30240.github.io.git/'

看 run 的步骤详情,前面几步都是绿色:

  • Checkout repository ✓
  • Setup Hugo ✓
  • Build Hugo site ✓
  • Deploy to GitHub Pages ✗

也就是说静态文件已经生成好了,倒在最后一步推送。workflow 里用的是:

personal_token: ${{ secrets.PUBLIC }}
external_repository: derec30240/derec30240.github.io
publish_branch: main

这个 PUBLIC 是专门用来推送到另一个仓库的 PAT。先看 secret 的更新时间:

gh secret list -R derec30240/BlogSource
PUBLIC    2025-07-15T13:15:23Z

再看部署历史:

gh run list -R derec30240/BlogSource -L 5

上一次成功部署是 2026-07-09,之后就一直没跑过,直到 2026-11-02 这次失败。如果当初创建的是 1 年有效期的 token,那么它在 2026-07-15 左右过期,时间线完全吻合。

重新生成 PAT
#

这里推荐使用 Fine-grained personal access token,只授权目标仓库,不用的权限一律不给:

  1. 打开 GitHub 的 Settings → Developer settings → Personal access tokens → Fine-grained tokens。
  2. 只选择 derec30240/derec30240.github.io 这个仓库。
  3. 权限只需要 Contents: Read and write。
  4. 设置一个合适的有效期,并在日历里加一条续期提醒。

然后在本地更新 secret:

gh secret set PUBLIC --repo derec30240/BlogSource

按提示粘贴新 token 即可。不要把 token 直接写在 workflow、脚本或者文章里。

重新运行
#

gh run rerun <run-id> --repo derec30240/BlogSource

或者再推一次提交。更新 secret 后重新运行,部署就恢复正常了。

注意:GITHUB_TOKEN 只对当前仓库有效,无法推送到外部的 GitHub Pages 仓库,所以这里仍然需要 PAT(或者 deploy key)。

顺手升级 Actions
#

既然已经进了 workflow,就把几个老版本的 action 一起更新了:

Action旧版本新版本
actions/checkoutv2v7
peaceiris/actions-hugov2v3
peaceiris/actions-gh-pagesv3v4

这几个版本的输入参数没有变化,原来的 submodules: true、personal_token、external_repository 等配置可以原样保留。更新后重新触发 workflow,构建和部署都正常。

小结
#

这次接连踩了几个坑,总结下来有几点值得记一下:

  • 主题和 Hugo 版本要一起看。Blowfish 的 config.toml 里写明了支持的 Hugo 版本范围,升级主题或 Hugo 之前先确认两者是否匹配。
  • 不要直接改主题里的版本上限。submodule 更新会丢失修改,而且高版本 Hugo 可能带来运行时的不兼容。
  • 滚动更新的系统要主动固定关键工具版本。Arch Linux 上的 Hugo、Node 等工具很容易在 pacman -Syu 时被带出新范围,IgnorePkg 是个简单有效的办法。
  • CI 里不要写 latest。本地和 CI 使用同一个明确的版本,才能避免“本地能跑、线上挂掉”。
  • PAT 会过期。部署失败时先区分是构建问题还是认证问题,用 gh run view --log-failed 和 gh secret list 能很快定位。
  • action 也应该定期升级。老版本 action 使用的 Node 运行时迟早会被淘汰,趁改动 workflow 时一起更新。

最后补充一点:这次从版本排查、主题升级到 CI 修复,整个流程都是全程和 agent 一起完成的。我负责确认方向、做最终决定,具体的命令执行、文档检索和代码改动则交给它。看着它在终端里读配置、翻日志、对比版本、修改 workflow,一气呵成,还是忍不住感叹:以前要折腾半天的事情,现在真的可以放心交给 agent 了。工具在进步,折腾博客的门槛也在一点点降低,或许以后真正稀缺的,只剩下想法本身了。


参考
#