当我尝试使用CodeBuild golang image 1.10构建golang项目时,它失败,无法找到子包。一些背景:
该应用程序组织如下:
/go/src/company/app
/go/src/company/app/sub1
/go/src/company/app/sub2
etc...
这在我的开发机器上构建良好。但是,当由codebuild提取时,它会被提取到另一个目录(
/codebuild/output/srcNNN/src/<some path>
)中,其中<some path>
根据触发生成的原因而有所不同。我最初是通过将代码从其复制到golang目录(
/codebuild/output/srcNNN
)的地方来工作的,但是由于GOPATH
目录的CodeBuild环境变量在前面插入/go:(/go:/codebuild/output/srcNNN
),因此我使用了../../... 复制。但是,这很丑陋,但一旦我以另一种方式触发了构建,它就会失败。我的问题是,是否有一种很好的方法来使它起作用?我的下一个想法是将字符串操作应用于观察到的路径,并在该路径中复制以(希望)提高可靠性。但这仅在
GOPATH
符合我的假设的情况下才有效。任何想法,将不胜感激。
澄清:
在代码中导入包时,将按以下方式导入外部包:
import (
"context"
...
}
子包未显式导入,但在如上所示部署代码时找到(
/go/src/company/app
)。但是,AWS CodeBuild不会以这种方式引入代码。 最佳答案
如果您使用的是Golang 1.11或更高版本,请参见下面的更新以获取完整的答案...我们不再使用我的最初工作。
我能够得到一个有效的答案。如果对其他人有帮助,我将在此处发布,但是它依赖于AWS CodeBuild中观察到的行为才能起作用,所以我认为这不是理想的选择。
在我的buildspec.yaml中,我可以通过以下方式使构建工作:
${THEGOPATH}
中获取${GOPATH}
。${THEGOPATH}/src/<app path>
${THEGOPATH}/src/<other app path>
go get ./...
或显式)buildspec.yaml类似于以下内容:
phases:
install:
commands:
- echo GOPATH - $GOPATH
- export THEGOPATH=`echo $GOPATH | cut -c 5-`
- echo THEGOPATH = $THEGOPATH
- mkdir -p ${THEGOPATH}/src/company/app1
- mkdir -p ${THEGOPATH}/src/company/other_repository_dependency
- echo Copy source files to go root
- cp -a ${CODEBUILD_SRC_DIR}/. ${THEGOPATH}/src/company/app1/${PACKAGE}
- cp -a ${CODEBUILD_SRC_DIR_other_dep}/. ${THEGOPATH}/src/app/other_repository_dependecy/.
- ls ${THEGOPATH}/src/
build:
commands:
- echo Build started on `date`
- echo Getting packages
- go get ./...
- echo DOING THE BUILD
- go build -ldflags "<some flags>" -o "appname"
- go test ./...
post_build:
commands:
- echo Build completed on `date`
- ls -al
- pwd
artifacts:
files:
- appname
更新-更好地修复
今天,我们尝试使用go模块(自1.11开始可用)进行构建,请参见here以获取go模块的说明。
使用go模块,我们在go.mod文件中将当前源模块app1定义为
company-name.com
,如下所示:module company-name.com/app1
go 1.12
require (
... *for example*
github.com/golang/mock v1.3.1
github.com/google/btree v1.0.0 // indirect
github.com/google/go-cmp v0.3.0
... *etc*
我们甚至以这种方式引用我们的外部文件(尽管您需要弄清楚如何使用git存储库进行身份验证。我们使用buildspec中内置的凭据帮助程序进行https身份验证)。因此,我们的导入块现在看起来像这样:
import (
"company-name.com/app1/subpackage1"
abbrev "company-name.com/app1/subpackage2"
"company-name.com/externalpkg" // In another private git repo of ours
... //etc
)
... //golang source follows here*
最后,我们在buildspec中添加了以下环境变量:
variables:
GO111MODULE: "on"
git-credential-helper: yes
这些确保模块在路径中正常工作(感谢amwill04提醒我我的遗漏),并允许我们的Git存储库的凭据正确设置。
为此,我们完成了所需的一切: