Heroku流水线中无法执行Git命令的解决方案咨询
在Heroku上部署Webpack项目时自动生成BUILD_ID的替代方案
我尝试在Webpack项目的webpack.config.js中通过DefinePlugin自动生成BUILD_ID,代码如下:
BUILD_ID: JSON.stringify(childProcess.execSync("git rev-list HEAD --count").toString().trim().padStart(5, "0") + "." + childProcess.execSync("git rev-list HEAD -1 --abbrev-commit").toString().trim()),
本地运行正常,但部署到Heroku时触发以下错误:
fatal: not a git repository (or any parent up to mount point /) Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set). [webpack-cli] Failed to load '/tmp/build_88ed3d2c/webpack.config.js' config [webpack-cli] Error: Command failed: git rev-list HEAD --count fatal: not a git repository (or any parent up to mount point /)
原因是Heroku构建时并未将代码作为Git仓库克隆,导致Git命令执行失败。试过heroku-prebuild但没找到有效方案,求可行的替代方法,预期是能生成类似[提交次数].[短commit哈希]格式的BUILD_ID。
可行替代方案
方案1:利用Heroku内置环境变量
Heroku在构建阶段会自动暴露关键环境变量,可直接用来生成BUILD_ID:
HEROKU_SLUG_COMMIT: 当前构建对应的完整Git commit SHAHEROKU_RELEASE_VERSION: Heroku的版本号(格式类似v123,可提取数字部分作为提交次数替代)
修改webpack.config.js代码:
const childProcess = require('child_process'); let buildId; // 优先读取Heroku环境变量,本地保留原Git逻辑 if (process.env.HEROKU_SLUG_COMMIT) { const shortCommit = process.env.HEROKU_SLUG_COMMIT.slice(0, 7); const buildNumber = process.env.HEROKU_RELEASE_VERSION?.replace('v', '').padStart(5, '0') || '00000'; buildId = `${buildNumber}.${shortCommit}`; } else { const commitCount = childProcess.execSync("git rev-list HEAD --count").toString().trim().padStart(5, "0"); const shortCommit = childProcess.execSync("git rev-list HEAD -1 --abbrev-commit").toString().trim(); buildId = `${commitCount}.${shortCommit}`; } module.exports = { // ...其他Webpack配置 plugins: [ new webpack.DefinePlugin({ BUILD_ID: JSON.stringify(buildId) }) ] };
方案2:预构建阶段生成BUILD_ID文件
通过heroku-prebuild脚本生成包含构建信息的文件,Webpack读取该文件内容:
- 在
package.json中添加预构建脚本:
{ "scripts": { "heroku-prebuild": "echo \"$(git rev-list HEAD --count | xargs printf '%05d').$(git rev-parse --short HEAD)\" > build-id.txt", // ...其他脚本 } }
- 修改
webpack.config.js读取文件:
const fs = require('fs'); const buildId = fs.readFileSync('./build-id.txt', 'utf8').trim(); module.exports = { // ...其他Webpack配置 plugins: [ new webpack.DefinePlugin({ BUILD_ID: JSON.stringify(buildId) }) ] };
方案3:启用Heroku Dyno元数据获取完整信息
若需要更全面的Git信息,可开启Heroku Dyno元数据功能,它会暴露SOURCE_VERSION(commit SHA)等更多变量:
- 启用元数据:
heroku labs:enable runtime-dyno-metadata -a your-app-name
- 参考方案1的逻辑,使用
SOURCE_VERSION变量生成BUILD_ID即可。
内容的提问来源于stack exchange,提问作者Oritart
相关产品推荐
相关产品推荐

