当我尝试使用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中,我可以通过以下方式使构建工作:

  • 通过从开头的
  • 中删除“/go:”,从${THEGOPATH}中获取${GOPATH}
  • 将所有代码复制到${THEGOPATH}/src/<app path>
  • 将其他存储库复制到${THEGOPATH}/src/<other app path>
  • 正常导入外部依赖项(在我们的示例中为go get ./...或显式)
  • 构建并强制输出名称(从CodeBuild启动时,它使用不同的目录名称)

  • 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存储库的凭据正确设置。

    为此,我们完成了所需的一切:
  • 通过更改对go模块的引用,我们可以轻松地将子包引用为
  • 我们能够锁定所有依赖项的版本
  • 通过在company-name.com上实现一个简单的服务器,我们可以从应用程序
  • 中引用其他私有(private)模块

    09-20 20:15