Go 小项目发布前检查清单:从能跑到敢交付

本文整理 Go 小项目发布前的入门检查清单,包括测试、格式化、构建、配置、日志、超时、错误处理和文档。

能跑和敢交付之间还有一段路

很多 Go 小项目写到最后,go run . 能跑,接口也能返回结果,于是就想直接上线或交给别人使用。可是真正交付前,还应该做一轮基础检查:测试是否通过,代码是否格式化,构建是否可复现,配置是否清楚,日志是否足够,外部调用是否有超时,错误是否会泄露敏感信息,README 是否告诉别人怎么运行。

这不是大公司流程,而是对自己和使用者负责。Go 工具链很简单,所以很多检查可以用几条命令完成。

这篇文章整理一份适合初学者的小项目发布清单。它不追求覆盖所有企业级要求,但能帮助你从“我这里能跑”走向“别人也能可靠运行”。

代码格式和静态检查

格式化:

gofmt -w .

更常用:

go fmt ./...

测试:

go test ./...

并发相关项目加 race:

go test -race ./...

如果项目有 vet 检查:

go vet ./...

这些命令应该在发布前至少跑一遍。它们速度快,能挡住很多低级问题。

构建二进制

go build -o dist/app .

如果有版本变量:

go build -ldflags "-X main.version=v1.0.0" -o dist/app .

构建成功只是第一步,还要实际运行:

./dist/app version
./dist/app -help

命令行工具至少应该有帮助信息。服务程序至少应该能启动并响应健康检查:

curl http://localhost:8080/healthz

不要只验证源码运行,发布什么就验证什么。

配置和密钥

检查配置来源是否清楚:

port := getenv("PORT", "8080")
dataFile := getenv("DATA_FILE", "data.json")

密钥不要写进代码:

const apiKey = "real-secret"

应该通过环境变量或密钥系统传入:

apiKey := os.Getenv("API_KEY")
if apiKey == "" {
	return fmt.Errorf("API_KEY is required")
}

README 里要说明必填配置:

PORT: HTTP 服务端口,默认 8080
API_KEY: 第三方接口密钥,必填

别人运行失败时,最怕配置规则藏在代码里。

超时和关闭

HTTP 客户端要有超时:

client := &http.Client{
	Timeout: 5 * time.Second,
}

服务要能优雅关闭:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
server.Shutdown(ctx)

外部调用要传 context:

req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)

没有超时的服务在正常情况下也许没问题,但一旦外部依赖卡住,就会拖住整个系统。

日志和错误

日志至少要记录启动配置摘要、请求路径、错误和耗时。不要记录密码、token 和完整敏感请求体。

错误响应不要把内部细节直接暴露给用户:

log.Printf("query database: %v", err)
http.Error(w, "internal server error", http.StatusInternalServerError)

不要:

http.Error(w, err.Error(), http.StatusInternalServerError)

内部错误给开发者看,外部错误给用户看。两者边界要分清。

文档和示例

一个小项目至少应该有:

项目做什么
如何运行
需要哪些配置
如何测试
如何构建
常见接口或命令示例

示例:

go test ./...
go build -o app .
PORT=8080 ./app

如果是 HTTP API,给一两个 curl:

curl http://localhost:8080/healthz
curl -X POST http://localhost:8080/tasks \
  -H 'Content-Type: application/json' \
  -d '{"title":"学习 Go"}'

文档不需要长,但要让新人能跑起来。

发布后也要能回滚和定位

发布不是把二进制丢到服务器就结束。至少要知道当前运行的是哪个版本,以及出问题时如何回到上一个版本。对小项目来说,可以保留最近几个构建产物:

releases/
├── app-v1.0.0
├── app-v1.0.1
└── app-v1.0.2

服务启动时打印版本:

logger.Info("server starting",
	"version", version,
	"commit", commit,
	"addr", addr,
)

健康检查也可以返回版本信息:

func healthHandler(w http.ResponseWriter, r *http.Request) {
	writeJSON(w, http.StatusOK, map[string]string{
		"status":  "ok",
		"version": version,
	})
}

这样你能通过接口确认线上版本。用户反馈问题时,先确认版本,再看日志,比猜测本地代码和线上是否一致可靠得多。

回滚也要提前想好。如果使用 systemd、Docker 或简单脚本部署,都应该知道如何停止当前进程、切换二进制、重新启动。小项目可以简单,但不能完全没有路径。真正紧急的时候,临时研究回滚会很被动。

小结

Go 小项目发布前可以按这条线检查:格式化、测试、构建、运行、配置、密钥、超时、关闭、日志、错误响应、文档。每一项都不复杂,但合在一起能显著提高交付质量。

“能跑”只是开发阶段的结果,“敢交付”需要更多确定性。Go 的工具链已经帮你把很多检查变得很轻,真正要做的是养成发布前走一遍清单的习惯。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页