Сбой AWS CodeBuild для исходного кода golang с подпакетами - PullRequest
0 голосов
/ 19 ноября 2018

Когда я пытаюсь собрать свой проект golang с использованием CodeBuild golang image 1.10, он не может найти подпакеты. Немного предыстории:

Приложение организовано следующим образом:

/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), но поскольку переменная среды CodeBuild для каталога GOPATH вставляет / go: (/go:/codebuild/output/srcNNN) в спереди я использовал наблюдаемое число .. / .. / ... для копирования. Однако это уродливо и не удалось, как только я запустил сборку другим способом.

Мой вопрос: есть ли хороший способ заставить это работать? Моя следующая идея - применить манипуляции со строками к наблюдаемому пути и скопировать его для (надеюсь) большей надежности. Но это будет работать только до тех пор, пока GOPATH соответствует моим предположениям.

Любые идеи будут оценены.


Разъяснение: При импорте пакетов в коде внешние пакеты импортируются следующим образом:

import (
    "context"
    ...
}

Подпакеты не импортируются явно, но обнаруживаются при развертывании кода, как показано выше (/go/src/company/app). Однако AWS CodeBuild не вводит код таким способом.

Ответы [ 2 ]

0 голосов
/ 07 июня 2019

Это подход, который я выбрал.

version: 0.2

env:
  variables:
    PACKAGE: "github.com/rhyselsmore/foo"

phases:
  install:
    commands:
      # AWS Codebuild Go images use /go for the $GOPATH so let's copy our
      # application source code into that directory structure.
      - mkdir -p "/go/src/$(dirname ${PACKAGE})"
      - ln -s "${CODEBUILD_SRC_DIR}" "/go/src/${PACKAGE}"
      - # Make sure we're in the package directort within our GOPATH
      - cd "/go/src/${PACKAGE}"

Теперь, предполагая, что переменная PACKAGE является корнем вашего репозитория, который вы создаете, мы можем выполнить команды go.Давайте разберем его построчно.

- mkdir -p "/go/src/$(dirname ${PACKAGE})"

Это создаст новый каталог в GOPATH для вашего пакета.

- mkdir -p "/go/src/$(dirname ${PACKAGE})"

Это создаст символическую ссылку из корня вашегоПроект CodeBuild для вашего пакета Go.

- cd "/go/src/${PACKAGE}"

Это заполняет остальные операции Codebuild для выполнения в CWD вашего пакета Go.

0 голосов
/ 20 ноября 2018

См. Обновление ниже для полного ответа, если вы находитесь на Голанге 1.11 или выше ... Мы больше не используем мою первоначальную работу.

Мне удалось получить ответ. Я опубликую его здесь на тот случай, если он будет полезен для других, но он работает на основе наблюдаемого поведения в AWS CodeBuild, поэтому я не думаю, что он идеален.

В моем buildspec.yaml я могу заставить работать сборку:

  1. Получение ${THEGOPATH} из ${GOPATH} путем удаления "/ go:" с начала
  2. Копирование всего кода на ${THEGOPATH}/src/<app path>
  3. Копирование других репозиториев в ${THEGOPATH}/src/<other app path>
  4. Импорт внешних зависимостей как обычно (в нашем случае go get ./... или явный)
  5. Сборка и форсирование выходного имени (при запуске из 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), см. здесь для объяснения модулей go.

Используя модули go, мы определили текущий исходный модуль app1 как company-name.com в файле go.mod следующим образом:

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-репозитория.

При этом мы достигли всего, что нам было нужно:

  1. Изменяя наши ссылки на модуль go, мы можем легко ссылаться на подпакеты как таковые
  2. Нам удалось заблокировать версию всех наших зависимостей
  3. Реализуя простой сервер на company-name.com, мы могли бы ссылаться на другие частные модули из нашего приложения
...