老T博客

解决Vercel不支持私有submodule仓库构建问题

解决Vercel不支持私有submodule仓库构建问题

日常免费静态博客托管,主要有 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 脚本文件,可以通过间接方式实现目的。

解决办法

这个脚本使用起来也比较简单。

  1. 创建脚本文件

在项目根目录下创建脚本文件vercel-submodule-workaround.sh,或将上述项目文件下载到本地项目根目录。 修改第1、2行的 Submodule 链接和路径。比如我的项目是 hugo-content 同时在 hugo 中也使用这个路径。

 1SUBMODULE_GITHUB=github.com/user/hugo-content
 2SUBMODULE_PATH=hugo-content
 3if [ "$GITHUB_ACCESS_TOKEN" == "" ]; then
 4  echo "Error: GITHUB_ACCESS_TOKEN is empty"
 5  exit 1
 6fi
 7set -e
 8output=`git submodule status --recursive`
 9no_prefix=${output#*-} 
10COMMIT=${no_prefix% *} 
11rm -rf tmp || true 
12mkdir tmp 
13cd tmp 
14git init 
15git remote add origin https://$GITHUB_ACCESS_TOKEN@$SUBMODULE_GITHUB 
16git fetch --depth=1 origin $COMMIT 
17git checkout $COMMIT 
18cd .. 
19rm -rf tmp/.git 
20mv tmp/* $SUBMODULE_PATH/ 
21rm -rf tmp 
  1. 创建 PAT

在 GitHub > Settings > Developer settings > Personal access tokens > Fine-grained tokens(或 Classic tokens)创建一个 PAT,授权对子模块私有仓库的访问权限。同时在 Vercel 项目的 Settings > Environment Variables 中填入该 PAT,名称为 GITHUB_ACCESS_TOKEN

Vercel PAT设置
Vercel PAT设置

  1. 设置安装命令

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

1chmod +x vercel-submodule-workaround.sh && ./vercel-submodule-workaround.sh hugo-contnet

部署设置
部署设置

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

#hugo博客 #vercel #私有仓库

评论