Lawtee News

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

日常免费静态博客托管,主要有 Vercel Cloudflare-Pages Netlify OneEdge 等服务,但在国内而言,总体上 Vercel 和 Netlify 速度算是最快的,但 Netlify 近年调整了免费额度,默认只给免费用户 300 个积分,而一次构建就需要 20 积分,如果博客更新频繁,很快就用尽额度。所以综合来看,还是 Vercel 最好。

n

问题描述

n

不过,最近本博客在更换 Hugo 主题过程中,由于启用了私有仓库 Submodule 功能,导致 Vercel 那边构建一直存在问题。具体来说就是无法拉取子模块。在构建过程中报错 Warning: Failed to fetch one or more git submodules 。导致构建出来的网站,实际只有框架,而无文章内容。

n

n nn nn

n 构建报错n
构建报错
n

nn

n

一开始我以为是权限问题,但排查后发现,我在 Vercel 上启用的 Github APP 授权足够拉取私有仓库子模块。同时,我在 Cloudflare Pages 上测试构建时,也并未发现有这个故障。

n

后来在 Vercel 社区查询才发现,这个问题由来已久,是因为 Vercel 的 Git 集成机制较为简单,部署流程无法自动继承主仓库的认证权限到子模块,导致拉取失败。而 Cloudflare 那边功能更全面,也就不存在这个问题。

n

为了解决这个问题,我尝试了多种方法,包括将 Submodule 中链接由 Git 改为 https 模式,以及在 vercel.json 中指定拉取子模块等方式,但都无法实现成功拉取。

n

最后,我找到一个 Github 项目 beeinger/vercel-private-submodule 。这个项目只有一个 vercel-submodule-workaround.sh 脚本文件,可以通过间接方式实现目的。

n

解决办法

n

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

n

    n

  1. 创建脚本文件
  2. n

n

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

nnnnnn

 1SUBMODULE_GITHUB=github.com/user/hugo-contentn 2SUBMODULE_PATH=hugo-contentn 3if [ "$GITHUB_ACCESS_TOKEN" == "" ]; thenn 4  echo "Error: GITHUB_ACCESS_TOKEN is empty"n 5  exit 1n 6fin 7set -en 8output=`git submodule status --recursive`n 9no_prefix=${output#*-} n10COMMIT=${no_prefix% *} n11rm -rf tmp || true n12mkdir tmp n13cd tmp n14git init n15git remote add origin https://$GITHUB_ACCESS_TOKEN@$SUBMODULE_GITHUB n16git fetch --depth=1 origin $COMMIT n17git checkout $COMMIT n18cd .. n19rm -rf tmp/.git n20mv tmp/* $SUBMODULE_PATH/ n21rm -rf tmp 
    n

  1. 创建 PAT
  2. n

n

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

n

n nn nn

n Vercel PAT设置n
Vercel PAT设置
n

nn

n

    n

  1. 设置安装命令
  2. n

n

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

nnnnnn

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

n nn nn

n 部署设置n
部署设置
n

nn

n

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