See Update below for a complete answer if you are on golang 1.11 or higher... We no longer use my initial work around.
I was able to get an answer working. I'll post it here in case it is helpful to others, but it relies on observed behavior in AWS CodeBuild to work, so I don't think it is ideal.
In my buildspec.yaml I am able to get the build to work by:
- Getting
${THEGOPATH}
from ${GOPATH}
by removing the "/go:" from the beginning
- Copying all the code to the
${THEGOPATH}/src/<app path>
- Copying other repositories to
${THEGOPATH}/src/<other app path>
- Importing external dependencies as normal (in our case,
go get ./...
or explicit)
- Building and forcing the output name (when launched from CodeBuild it used a different directory name)
The buildspec.yaml looks something like the following:
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
Update -- Better fix
Today we attempted to build with go modules (available since 1.11) see here for an explanation of go modules.
Using go modules we defined the current source module app1 as company-name.com
in the go.mod file like this:
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*
We even reference our external files this way (though you'll need to figure out how to authenticate with your git repository. We used the credential helper built into the buildspec for https authentication). So, our import blocks look something like this now:
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*
Finally, we added the following environment variable to the buildspec:
variables:
GO111MODULE: "on"
git-credential-helper: yes
These ensured that modules worked in the path (thanks amwill04 for reminding me of my omission) and allowed the credentials for our Git repository to get setup properly.
In doing this we accomplished everything we needed:
- By changing our references to the go module we could easily reference the subpackages as such
- We were able to lock the version of all our dependencies
- By implementing a simple server at company-name.com, we could reference other private modules from our application