创建docker容器以运行“go test”,并下载和缓存所有模块依赖项
我想在需要使用Docker的CI环境中测试我的Go代码。我如何创建一个Docker映像,该映像具有已下载和编译的创建docker容器以运行“go test”,并下载和缓存所有模块依赖项,docker,go,Docker,Go,我想在需要使用Docker的CI环境中测试我的Go代码。我如何创建一个Docker映像,该映像具有已下载和编译的go.mod中列出的所有依赖项,以便Docker run$IMG go test使用缓存的工件 此图像的所需属性: 图像仅使用go.mod编译依赖项。我不想使用完整的源代码,因为对源代码的任何更改都会使保存缓存依赖项的Docker层无效 docker运行$IMG go测试。/…不会重新下载或重新编译go.mod中列出的依赖项 避免实验性的Docker特性 # syntax = doc
go.mod
中列出的所有依赖项,以便Docker run$IMG go test
使用缓存的工件
此图像的所需属性:
- 图像仅使用
编译依赖项。我不想使用完整的源代码,因为对源代码的任何更改都会使保存缓存依赖项的Docker层无效go.mod
不会重新下载或重新编译docker运行$IMG go测试。/…
中列出的依赖项go.mod
- 避免实验性的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
现有方法
解析go.mod并使用go-get
从
这种方法很接近,但当我运行go test
时,它似乎没有使用GOCACHE
。这似乎也会阻塞某些模块路径,如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\u BUILDKIT
最初在中描述。这只适用于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
我经常把
COPY go.mod
放在Dockerfile的开头,因为它不会经常更改
来自golang的:1.14.3作为构建者
WORKDIR/app
复制go.mod。
复制go.sum。
运行go mod下载
复制
运行go build-tags netgo-ldflags'-extldflags'-static'-o应用程序。
从centos开始:7
WORKDIR/root
复制--from=builder/app/app。
因此,如果您的go mod没有更改,则行
运行go mod download
仅第一次运行。如果您运行go get,则在您的dockerfile中。/。。。它将根据go.mod和go.sum将所有依赖项下载到docker映像中。如果您正在处理内部自签名存储库,还可以将--unsecure标志添加到go-get命令中。非常类似于go mod下载。除此之外,您还可以拥有一个实际启动Go测试的shell脚本。/。。。并将其报告给您的CI环境(如果允许),我知道Gitlab允许这样做
FROM golang:1.15-alpine AS builder
RUN apk add --update git gcc musl-dev
RUN apk update && apk add bash
COPY . /app
RUN go version
WORKDIR /app
ENV CGO_ENABLED=0
RUN git config --global http.sslVerify false
RUN go get ./...
WORKDIR /app
RUN chmod +x ./unitTest.sh
RUN ./unitTest.sh
WORKDIR /app/cmd/svr
RUN go build -o app
RUN chmod 700 app
FROM alpine:latest
WORKDIR /root/
ARG build_stamp
ARG git_commit
ARG build_number
ENV BUILD_STAMP=$build_stamp
ENV GIT_COMMIT=$git_commit
ENV BUILD_NUMBER=$build_number
COPY --from=builder /app/cmd/svr .
EXPOSE 8000
CMD ["./app"]
剧本呢
#!/usr/bin/env bash
TESTS=$(go test -v -covermode=count -coverprofile=count.txt ./...)
echo "$TESTS"
if echo "$TESTS" | grep -q "FAIL" ; then
echo ""
echo "One or more Unit Tests for app have Failed. Build will now fail. Pipeline will also fail..."
echo ""
exit 1
else
echo ""
echo "All Unit Tests for application have passed!"
echo "Running Code Coverage..."
echo ""
COVERAGE=$(go tool cover -func=./count.txt)
echo "$COVERAGE"
exit 0
fi
你找到好的解决办法了吗?