Drone中go test ./报import not found,主因是工作目录、模块路径与GO111MODULE未对齐:需显式cd至项目根目录、设GO111MODULE=on、确保go.mod声明与import路径一致。

Drone CI里go test ./报import not found怎么办
根本不是代码问题,是Drone工作目录、模块路径、GO111MODULE三者没对齐。Drone默认把代码克隆到/drone/src(或你配置的workspace.path),但如果你没显式cd进含go.mod的目录,go test ./就会在错误位置执行。
- 在
.drone.yml的build step开头加cd $DRONE_WORKSPACE(或你项目实际根路径),别依赖Drone自动定位 - 显式设置
GO111MODULE=on:Drone容器不保证默认开启,尤其用老版golang镜像时 - 验证
go env GO111MODULE输出为on,不是auto或空字符串 - 确保
go.mod中module声明与所有import路径前缀一致,比如module github.com/yourorg/app,就不能import "app/internal"
Drone里如何安全复用Go模块缓存
Drone runner默认无持久化缓存,每次构建都重下依赖,慢且易受代理波动影响。关键不是“能不能缓存”,而是“缓存什么、怎么验证一致性”。
- 用
go mod download预热缓存:在build step前加go mod download,它只拉取go.mod声明的精确版本,不触发go.sum校验失败 - 配置
GOPROXY:推荐https://goproxy.cn,direct,国内快;避免全用direct,网络抖动直接中断 - 不要挂载
$GOMODCACHE到宿主机:Drone runner常跨节点调度,缓存不一致会导致go build静默失败 -
go.sum必须提交:它记录每个依赖的SHA256,Drone构建时会强制校验,缺了就报checksum mismatch
多模块项目在Drone中怎么管理replace
本地开发常用replace指向未发布的内部模块,但Drone里若不处理,go build会报no matching versions for query "latest"——因为replace只在当前模块生效,CI里没源码就找不到。
- Drone构建前,用
sed -i '/replace/d' go.mod临时删掉replace行(仅限发布分支) - 更稳妥的做法:把内部模块打Git tag,用语义化版本引用,
replace只保留在dev分支的go.mod里 - 如果必须用
replace,在Drone step里手动git clone被替换的模块到对应路径,再go mod edit -replace还原 - 注意
go mod tidy在Drone里慎用:它可能改写go.mod,导致PR检查与主干不一致
Drone构建二进制时怎么平衡体积和调试能力
默认go build产物含完整符号表,Docker镜像动辄20MB+,但全裁剪又会让pprof和堆栈追踪失效。
立即学习“go语言免费学习笔记(深入)”;
- 必加
-ldflags="-s -w":-s删符号表,-w删DWARF,两者合用后runtime.Caller仍返回文件名+行号,不影响日志trace - 禁用
CGO_ENABLED=0:避免链接libc,生成纯静态二进制,file myapp显示statically linked - 慎用
-trimpath:它让runtime.Caller返回main.go:12而非/drone/src/github.com/.../main.go:12,某些APM工具依赖绝对路径做链路关联 - 构建后加
strip --strip-unneeded myapp二次瘦身,可再减1–2MB,不影响调试信息
go env配置,所有GO*变量都得在step里显式export,且go.mod和go.sum的提交状态直接决定依赖是否可重现——没提交go.sum,CI就永远在赌网络和缓存运气。


















