k8s && bazel 项目从 go1.20 升级 go1.21

go1.20 -> go1.21 的变化就不细说了,release note 在这 https://tip.golang.org/doc/go1.21
主要是 bazel 构建相关的升级,还是值得留下一些文字记录。(本文仓库的 bazel 构建在初期借鉴了 https://github.com/kubernetes/repo-infra

go 版本的升级很简单,go.mod 修改 1.201.21 即可。go1.21 需要使用 rules_go >= 0.41.0,而 rules_go 0.41.0 又需要 gazelle >= 0.30.0。
一整套工具链都需要升级。

rules_gogazellerelease note,就可以看到这个版本之后需要手动导入 googleapis 依赖了,有例子,依葫芦画瓢即可。如果使用的 proto 较多,可以善用 github search 或者 gazellegit history

其实仅仅到这里就没有文字记录的必要了,坑在后面。

有部分很老的带 proto 的依赖需要手动添加 googleapisdirectives,不想仓库直接写在 BUILD.bazel 就可以。这需要自行写在 go_repositorybuild_directives 里面。

然后就是更坑的。

当以上问题解决之后,update-bazel.sh 执行正常,但是 verify-bazel.shgazelle fix --mode=diff)跪了,会提示所有与 go 相关的 rules 都需要清除。换个说法就是在 gazelle 视角里面似乎已经没有任何 go 代码了。

为此我创建了一个最小复现仓库,使用不同版本的 gazelle 进行测试,最终找到了 bazelbuild/bazel-gazelle#1384

由于 verify-bazel.sh 面对的文件并非直接来自于当前上下文而是 filegroup all-srcs。这个 commit 使 gazelle 不再读取任何软链接内容,而 filegroup 就是软链接构建的,所以在 gazelle 视角里面就没有任何文件了。

具体的修复可以看 kubernetes/repo-infra#250

嗯其实还有一个坑,很隐蔽,上线生产两个周才被发现,来自于 go1.21 release note 里面轻飘飘的一句话

Package initialization order is now specified more precisely

有机会下篇再说。


k8s && bazel 项目从 go1.20 升级 go1.21
https://hunsh.net/20231130/k8s-bazel-项目从-go1-20-升级-go1-21/
发布于
2023年11月30日
许可协议