为了账号安全,请及时绑定邮箱和手机立即绑定

创建 docker 容器以运行“go test”,并下载并缓存所有模块依赖项

创建 docker 容器以运行“go test”,并下载并缓存所有模块依赖项

Go
白猪掌柜的 2022-05-18 10:10:02
我想在需要使用 Docker 的 CI 环境中测试我的 Go 代码。如何创建一个 Docker 映像,其中包含go.mod已下载和编译的所有依赖项,以便docker run $IMG go test使用缓存的工件?此图像的所需属性:该图像仅用于go.mod编译依赖项。我不想使用完整的源代码,因为对源代码的任何更改都会使包含缓存依赖项的 Docker 层失效。docker run $IMG go test ./...不会重新下载或重新编译go.mod.避免实验性的 Docker 功能。现有方法解析 go.mod 并使用 go get来自https://github.com/golang/go/issues/27719#issuecomment-578246826这种方法很接近,但GOCACHE在我运行go test. 这似乎也会阻塞某些模块路径,例如gopkg.in/DataDog/dd-trace-go.v1:FROM golang:1.13WORKDIR /srcCOPY 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 -vdocker 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:experimentalFROM golang:1.13 as go-builderARG VERSIONWORKDIR /srcCOPY . /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
查看完整描述

2 回答

?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

我经常把COPY go.modDockerfile 放在开头,因为它不会经常更改。


FROM golang:1.14.3 as builder


WORKDIR /app


COPY go.mod .

COPY go.sum .


RUN go mod download


COPY . .

RUN go build -tags netgo -ldflags '-extldflags "-static"' -o app .


FROM centos:7  

WORKDIR /root


COPY --from=builder /app/app .

所以,如果你去 mod 不改变,该行RUN go mod download只运行第一次。


查看完整回答
反对 回复 2022-05-18
?
MMTTMM

TA贡献1869条经验 获得超4个赞

如果你运行 go get ./... 在你的 dockerfile 中,它会根据 go.mod 和 go.sum 将所有依赖项下载到你的 docker 镜像中。如果您正在处理内部自签名存储库,您还可以将 --insecure 标志添加到 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


查看完整回答
反对 回复 2022-05-18
  • 2 回答
  • 0 关注
  • 85 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号