首页 > 解决方案 > AWS CodeBuild 通过 CDK 失败并显示“/codebuild/output/tmp/script.sh: 4: [[: not found”

问题描述

CDK 管道很简单:

    source0 = CodePipelineSource.connection("some-owner/some-repo-2", "master",
        connection_arn="arn:aws:codestar-connections:us-east-1:<123456789012>:connection/<some-uuid>"
    )

    pipeline = CodePipeline(self, "Abcdef",
        synth=ShellStep("Synth",
            input=CodePipelineSource.connection("some-owner/some-repo-1", "master",
                connection_arn="arn:aws:codestar-connections:us-east-1:<123456789012>:connection/<some-uuid>"
            ),
            additional_inputs={
                "../some-repo-2": source0,
            },
            commands=[
                "npm install -g aws-cdk",
                "pip install -r requirements.txt",
                "cdk synth"
            ]
        )
    )

这会生成 Cfn 模板,其中某处有一个 CodeBuild BuildSpec,它断言为 指定的输出目录additional_inputs必须尚未退出。为此,它使用:

"BuildSpec": "{\n  \"version\": \"0.2\",\n  \"phases\": {\n    \"install\": {\n      \"commands\": [\n        \"[[ ! -d \\\"../some-repo-2\\\" ]] || { echo 'additionalInputs: \\\"../some-repo-2\\\" must not exist yet. If you want to merge multiple artifacts, use a \\\"cp\\\" command.'; exit 1; } && ln -s -- \\\"$CODEBUILD_SRC_DIR_some_owner_some_repo_2_Source\\\" \\\"../some-repo-2\\\"\"\n      ]\n    },\n    \"build\": {\n      \"commands\": [\n        \"npm install -g aws-cdk\",\n        \"pip install -r requirements.txt\",\n        \"cdk synth\"\n      ]\n    }\n  },\n  \"artifacts\": {\n    \"base-directory\": \"cdk.out\",\n    \"files\": \"**/*\"\n  }\n}",
"Type": "CODEPIPELINE"

正如您所看到的,它是一个 bash 结构,因为[[ ... ]]纯 POSIX 仅外壳不支持此结构。在 CodePipeline 构建步骤中合成它时,它会失败并显示:

/codebuild/output/tmp/script.sh: 4: [[: not found

因此,aws 使用的上述脚本可能不符合 bash,或者环境未设置为 bash。

我该如何解决这个问题?有没有办法可以以某种方式从 CDK 代码中修改构建规范?

(使用:cdk 版本 1.129.0 和 python3.8)

标签: aws-cdkaws-codepipelineaws-codebuild

解决方案


这是正在使用的外壳的问题。似乎ShellStep没有将底层配置为至少CodeBuild使用.bashadditional_inputs

使用更细粒度的子类CodeBuildStep并显式设置 shell 来bash解决这个问题:

pipeline = CodePipeline(self, "...",
            synth=CodeBuildStep("Synth",
                partial_build_spec=BuildSpec.from_object({
                    "version": "0.2",
                    "env": {
                        "shell": "bash"
                    }
                }),
                input=...,
                additional_inputs={ ... },
                commands= [ ... ],
                ...

由于additional_inputs不能通过ShellStepthen 使用,它不能公开它(并且只能通过 提供CodeBuildStep)或者aws-cdk 源代码中的工厂方法应该更改为使用符合 POSIX 的构造 - 所以[ .. 而不是[[ ..

如果这一切都是真的,我会认为它是 cdk 中的一个错误。无论如何,与此同时,我们可以像上面那样解决它。


推荐阅读