You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用AWS CDK Pipeline构建栈时遇.git/HEAD不存在错误

问题描述

使用aws-cdk-lib/pipelines通过AWS Code Pipeline构建CDK CloudFormation栈,本地执行cdk ls正常,也能成功部署流水线,但在CodeBuild阶段执行npx cdk synth时出现错误。

错误信息

[Container] 2022/12/30 09:18:36 Running command npx cdk synth
Error: .git/HEAD does not exist
    at gitHeadPath (/codebuild/output/src224694107/src/backend/node_modules/git-branch/index.js:36:11)
    at branch (/codebuild/output/src224694107/src/backend/node_modules/git-branch/index.js:14:28)
    at /codebuild/output/src224694107/src/backend/src/context/getContext.ts:11:41
    at new Promise (<anonymous>)
    at Object.exports.getContext (/codebuild/output/src224694107/src/backend/src/context/getContext.ts:9:12)
    at createStack (/codebuild/output/src224694107/src/backend/bin/template.ts:9:25)
    at Object.<anonymous> (/codebuild/output/src224694107/src/backend/bin/template.ts:18:1)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Module.m._compile (/codebuild/output/src224694107/src/backend/node_modules/ts-node/src/index.ts:1618:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
(node:179) UnhandledPromiseRejectionWarning: undefined
(Use `node --trace-warnings ...` to show where the warning was created)
(node:179) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:179) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

相关代码

CDK流水线代码

this.codePipeline = new CodePipeline(this, `${environment}-pipeline-${appName}`, {
  pipelineName: `${environment}-pipeline-${appName}`,
  selfMutation: true,
  crossAccountKeys: false,
  role: this.codePipelineRole,
  synth: new ShellStep("Deployment", {
    input: CodePipelineSource.codeCommit(this.codeRepository, environment),
    installCommands: ["npm uninstall -g aws-cdk", "npm i -g npm@latest", "npm install -g aws-cdk"],
    commands: ["cd backend", "npm ci", "npm run build", "npx cdk synth"],
    primaryOutputDirectory: "backend/cdk.out",
  }),
});

getContext函数

export const getContext = (app: App): Promise<CDKContext> => {
    return new Promise(async (resolve, reject) => {
        try {
            const currentBranch = await gitBranch();
            const environment = app.node.tryGetContext("environments").find((e: any) => e.branchName === currentBranch);
            const globals = app.node.tryGetContext("globals");
            return resolve({...globals, ...environment});
        }
        catch (error) {
            console.error("error", error);
            return reject();
        }
    })
}

Package.json依赖

"dependencies": {
    "@aws-cdk/aws-appsync-alpha": "^2.55.1-alpha.0",
    "aws-cdk-lib": "^2.58.0",
    "aws-sdk": "^2.1278.0",
    "constructs": "^10.1.204",
    "git-branch": "^2.0.1",
    "source-map-support": "^0.5.21"
  }

问题原因

本地环境是完整的Git仓库,包含.git目录,因此git-branch库可以正常读取.git/HEAD获取分支名。但AWS CodeBuild默认拉取代码时,不会包含完整的.git目录(仅获取代码文件),导致git-branch库找不到.git/HEAD文件,抛出错误。

解决方案

方案1:让CodeBuild拉取完整Git仓库

修改CodePipelineSource.codeCommit的配置,添加codeBuildCloneOutput: true参数,让CodeBuild获取完整的Git仓库(包含.git目录):

this.codePipeline = new CodePipeline(this, `${environment}-pipeline-${appName}`, {
  pipelineName: `${environment}-pipeline-${appName}`,
  selfMutation: true,
  crossAccountKeys: false,
  role: this.codePipelineRole,
  synth: new ShellStep("Deployment", {
    input: CodePipelineSource.codeCommit(this.codeRepository, environment, {
      codeBuildCloneOutput: true // 启用完整Git仓库克隆
    }),
    installCommands: ["npm uninstall -g aws-cdk", "npm i -g npm@latest", "npm install -g aws-cdk"],
    commands: ["cd backend", "npm ci", "npm run build", "npx cdk synth"],
    primaryOutputDirectory: "backend/cdk.out",
  }),
});

方案2:移除对git-branch库的依赖

既然流水线已经明确指定了分支(environment参数),可以直接将该分支名传递给getContext函数,无需通过Git仓库获取:

  1. 修改getContext函数,改为接收分支参数:
export const getContext = (app: App, branch: string): CDKContext => {
    const environmentConfig = app.node.tryGetContext("environments").find((e: any) => e.branchName === branch);
    const globals = app.node.tryGetContext("globals");
    return {...globals, ...environmentConfig};
}
  1. 在bin/template.ts中直接传入流水线使用的分支名:
// 假设environment变量在当前作用域可访问
const context = getContext(app, environment);
createStack(app, context);

此方案还可以移除package.json中的git-branch依赖,减少不必要的依赖项。


内容的提问来源于stack exchange,提问作者Luke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 22:55:27