Создайте контейнер docker для запуска `go test` со всеми загруженными и кэшированными зависимостями модуля - PullRequest
4 голосов
/ 13 февраля 2020

Я хочу протестировать свой код Go в среде CI, для которой необходимо использовать Docker. Как создать изображение Docker, в котором все зависимости, перечисленные в go.mod, уже загружены и скомпилированы, чтобы docker run $IMG go test использовала кэшированные артефакты?

Желаемые свойства этого изображения:

  • В изображении используется только go.mod для компиляции зависимостей. Я не хочу использовать полный исходный код, потому что тогда любое изменение исходного кода сделает недействительным слой Docker, который содержит кэшированные зависимости.

  • docker run $IMG go test ./... не загружается повторно или Перекомпилируйте зависимости, перечисленные в go.mod.

  • Избегайте экспериментальных Docker функций.

Существующие подходы

Синтаксический анализ go .mod и использование go get

From https://github.com/golang/go/issues/27719#issuecomment -578246826

Этот подход близок, но, похоже, не используйте GOCACHE, когда я запускаю go test. Это также, похоже, душит определенные пути модулей, например gopkg.in/DataDog/dd-trace-go.v1:

FROM golang:1.13
WORKDIR /src
COPY go.mod ./
RUN set -eu \
  && go mod graph \
  | cut -d '@' -f 1 \
  | cut -d ' ' -f 2 \
  | sort -u \
  | sed -e 's#dd-trace-go.v1#&/ddtrace#' \
  | xargs go get -v
docker run --mount /src:/src $IMG go test ./...

Использование DOCKER_BUILDKIT с кешем монтирования

Изначально описано в https://github.com/golang/go/issues/27719#issuecomment -514747274 . Это работает только для go build. Я не могу использовать его для go test, потому что монтирование кэша отключено после команды RUN, поэтому оно не существует в созданном образе Docker.

Это также зависит от экспериментальных функций docker.

# syntax = docker/dockerfile:experimental
FROM golang:1.13 as go-builder
ARG VERSION
WORKDIR /src
COPY . /src/
# With a mount cache, Docker will cache the target directories for future
# invocations of this RUN layer. Meaning, once this command is run once, all
# successive calls will use the already downloaded and already compiled assets.
RUN --mount=type=cache,target=/go/pkg/mod \
    --mount=type=cache,target=/root/.cache/go-build \
    go build ./server
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...