日常免费静态博客托管,主要有 Vercel Cloudflare-Pages Netlify OneEdge 等服务,但在国内而言,总体上 Vercel 和 Netlify 速度算是最快的,但 Netlify 近年调整了免费额度,默认只给免费用户 300 个积分,而一次构建就需要 20 积分,如果博客更新频繁,很快就用尽额度。所以综合来看,还是 Vercel 最好。
问题描述
不过,最近本博客在更换 Hugo 主题过程中,由于启用了私有仓库 Submodule 功能,导致 Vercel 那边构建一直存在问题。具体来说就是无法拉取子模块。在构建过程中报错 Warning: Failed to fetch one or more git submodules 。导致构建出来的网站,实际只有框架,而无文章内容。

一开始我以为是权限问题,但排查后发现,我在 Vercel 上启用的 Github APP 授权足够拉取私有仓库子模块。同时,我在 Cloudflare Pages 上测试构建时,也并未发现有这个故障。
后来在 Vercel 社区查询才发现,这个问题由来已久,是因为 Vercel 的 Git 集成机制较为简单,部署流程无法自动继承主仓库的认证权限到子模块,导致拉取失败。而 Cloudflare 那边功能更全面,也就不存在这个问题。
为了解决这个问题,我尝试了多种方法,包括将 Submodule 中链接由 Git 改为 https 模式,以及在 vercel.json 中指定拉取子模块等方式,但都无法实现成功拉取。
最后,我找到一个 Github 项目 beeinger/vercel-private-submodule 。这个项目只有一个 vercel-submodule-workaround.sh 脚本文件,可以通过间接方式实现目的。
解决办法
这个脚本使用起来也比较简单。
- 创建脚本文件
在项目根目录下创建脚本文件vercel-submodule-workaround.sh,或将上述项目文件下载到本地项目根目录。
修改第1、2行的 Submodule 链接和路径。比如我的项目是 hugo-content 同时在 hugo 中也使用这个路径。
| |
- 创建 PAT
在 GitHub > Settings > Developer settings > Personal access tokens > Fine-grained tokens(或 Classic tokens)创建一个 PAT,授权对子模块私有仓库的访问权限。同时在 Vercel 项目的 Settings > Environment Variables 中填入该 PAT,名称为 GITHUB_ACCESS_TOKEN。

- 设置安装命令
在 Vercel Dashboard > 项目 > Settings > General > Build & Development Settings 中设置安装命令,注意在前边添加 chmod +x。
| |

总的来说,经过这次折腾,也算是体会到云服务的便捷背后往往藏着特定场景的局限性。Vercel 虽快但子模块支持的短板让我之前多次“捉急”。而在 Github 找到这种使用脚本迂回解决方案后,也算是山重水复疑无路,柳暗花明又一村了。过程中,我都一度想放弃私有仓库的搞法,转为公开仓库。好在最终成功解决问题。
