在GitHub Action中使用Vercel CLI传递自定义环境变量的问题
我有一个API的URL会随分支名变化,需要在部署到Vercel的Next.js前端项目中,通过GitHub Action引用这个动态生成的API URL。
Vercel仅支持preview、development、production三种环境配置变量,同一环境的所有部署会共享这些变量。但我的变量需要随分支变化,所以希望在部署/构建阶段传递变量值,可即便用了--build-env和--env参数,Vercel CLI还是一直使用preview环境的默认变量。
当前操作流程
主要步骤
- 将分支名存入
$GITHUB_ENV
# github-action.yaml name: Vercel Preview Release env: BRANCH_NAME: ${{ github.head_ref || github.ref_name }} ...
- 根据分支名和其他变量重构API URL
- name: reconstruct API URL and HASH_ID_SEED run: | NAME=$BRANCH_NAME NNAME="${NAME////-}" MNAME="${NNAME//./-}" echo "NEXT_PUBLIC_HASH_ID_SEED=$MNAME" >> "$GITHUB_ENV" echo "NEXT_PUBLIC_API_LINK=https://$PROJECT_NAME-$MNAME-api-$API_LINK_END"
- 使用
NEXT_PUBLIC_API_LINK等变量部署
- name: Deploy Project Artifacts to Vercel run: >- vercel deploy -b NEXT_PUBLIC_HASH_ID_SEED=$NEXT_PUBLIC_HASH_ID_SEED -b NEXTAUTH_SECRET=$NEXTAUTH_SECRET -b NEXT_PUBLIC_API_LINK=$NEXT_PUBLIC_API_LINK -e NEXT_PUBLIC_HASH_ID_SEED=$NEXT_PUBLIC_HASH_ID_SEED -e NEXTAUTH_SECRET=$NEXTAUTH_SECRET -e NEXT_PUBLIC_API_LINK=$NEXT_PUBLIC_API_LINK --token=${{ secrets.VERCEL_TOKEN }}
执行结果
部署无报错,生成了新的预览链接,但应用调用的API URL不正确。
其他信息
- 查阅的Vercel部署教程均要求依次执行三个命令:
vercel pull [environment] --token=<token>、vercel build --token=<token>和vercel deploy --prebuilt --token=<token>,但存在以下问题:- 无法修改环境变量,因为变量是从Vercel默认环境拉取的
- 生成的
./.vercel/.env.preview.local文件包含VERCEL_URL=""变量,与next-auth冲突
- 尝试跳过构建步骤直接部署,无报错但API URL仍错误
- 完整GitHub Action文件:
name: Vercel Preview Release env: BRANCH_NAME: ${{ github.head_ref || github.ref_name }} VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} PROJECT_NAME: ${{ secrets.PROJECT_NAME }} NEXTAUTH_SECRET: ${{ secrets.NEXTAUTH_SECRET }} API_LINK_END: ${{ secrets.API_LINK_END }} on: push: branches: - release-* - release/* jobs: Deploy-Preview: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v3 with: node-version: 16 - name: reconstruct API URL and HASH_ID_SEED run: | NAME=$BRANCH_NAME NNAME="${NAME////-}" MNAME="${NNAME//./-}" echo "NEXT_PUBLIC_HASH_ID_SEED=$MNAME" >> "$GITHUB_ENV" echo "NEXT_PUBLIC_API_LINK=https://$PROJECT_NAME-$MNAME-api-$API_LINK_END" - name: Install Vercel CLI run: npm install --global vercel@latest --immutable - name: Deploy Project Artifacts to Vercel run: >- vercel deploy -b NEXT_PUBLIC_HASH_ID_SEED=$NEXT_PUBLIC_HASH_ID_SEED -b NEXTAUTH_SECRET=$NEXTAUTH_SECRET -b NEXT_PUBLIC_API_LINK=$NEXT_PUBLIC_API_LINK -e NEXT_PUBLIC_HASH_ID_SEED=$NEXT_PUBLIC_HASH_ID_SEED -e NEXTAUTH_SECRET=$NEXTAUTH_SECRET -e NEXT_PUBLIC_API_LINK=$NEXT_PUBLIC_API_LINK --token=${{ secrets.VERCEL_TOKEN }}
预期效果
部署命令中传递的环境变量能在最终部署的应用中生效。
1. 修复环境变量注入问题
你在重构API URL的步骤中,echo "NEXT_PUBLIC_API_LINK=..."未写入$GITHUB_ENV,导致部署命令中的$NEXT_PUBLIC_API_LINK为空值或使用旧值。修改脚本如下:
- name: reconstruct API URL and HASH_ID_SEED run: | NAME=$BRANCH_NAME NNAME="${NAME////-}" MNAME="${NNAME//./-}" echo "NEXT_PUBLIC_HASH_ID_SEED=$MNAME" >> "$GITHUB_ENV" echo "NEXT_PUBLIC_API_LINK=https://$PROJECT_NAME-$MNAME-api-$API_LINK_END" >> "$GITHUB_ENV"
2. 明确指定预览环境并覆盖变量
Vercel CLI默认会加载preview环境的变量,需通过--preview明确指定预览部署,并用--build-env和--env强制覆盖变量,同时跳过交互流程:
- name: Deploy Project Artifacts to Vercel run: >- vercel deploy --preview --yes --prod=false --build-env NEXT_PUBLIC_HASH_ID_SEED=$NEXT_PUBLIC_HASH_ID_SEED --build-env NEXTAUTH_SECRET=$NEXTAUTH_SECRET --build-env NEXT_PUBLIC_API_LINK=$NEXT_PUBLIC_API_LINK --env NEXT_PUBLIC_HASH_ID_SEED=$NEXT_PUBLIC_HASH_ID_SEED --env NEXTAUTH_SECRET=$NEXTAUTH_SECRET --env NEXT_PUBLIC_API_LINK=$NEXT_PUBLIC_API_LINK --token=${{ secrets.VERCEL_TOKEN }}
3. 禁用Vercel默认环境变量(可选)
如果完全不想使用Vercel后台配置的preview环境变量,可添加--no-verify参数,阻止CLI加载远程变量,完全使用你传递的变量:
vercel deploy --preview --yes --prod=false --no-verify # 追加上述build-env和env参数
4. 检查Next.js代码中的变量使用
确保代码中直接使用process.env.NEXT_PUBLIC_API_LINK,对于Next.js 13+的App Router,注意NEXT_PUBLIC_前缀的变量可直接在客户端组件中访问,服务端组件则无限制。
内容的提问来源于stack exchange,提问作者anon

