Go:如何将 git 修订添加到构建的二进制文件中?

Posted

技术标签:

【中文标题】Go:如何将 git 修订添加到构建的二进制文件中?【英文标题】:Go: how to add git revision to binaries built? 【发布时间】:2013-03-20 15:48:06 【问题描述】:

我想将当前的 git 修订号添加到由 go build 构建的二进制文件中,以便我可以执行类似 ./mybinary --revision 的操作来查看它是从哪个修订版构建的(通常用于稍后部署后的故障排除)。

显然我不能将修订号放入源代码,因为这会用新的修订版本更改源代码。

我想知道是否有其他方法可以做到这一点? 或者你认为这只是一个坏主意?如果是这样,在构建的二进制文件与其源版本之间建立关系的推荐方法是什么? 对于分布式版本控制系统,版本号似乎不是一个好主意。

【问题讨论】:

实用阅读Is it a good practice to make a tag in git for every deployment build?Enable ident string for Git reposHow to auto-generate a version string in git 这是一个懒惰的答案,@LazyBadger。你真的很尊重你的名字。 【参考方案1】:

您通常会使用标签(在其他版本控制系统中也称为标签)来记录构成特定构建的文件。 http://git-scm.com/book/en/Git-Basics-Tagging。我通常制作包含版本和构建日期的标签。例如 v1.2_29Mar2013。如果我有几个可以从同一个代码库构建的产品,我将包含一些东西来识别哪个产品。

【讨论】:

【参考方案2】:

对于 所有和任何 版本的 Git 代码 最明显的方式 用于获取任何变更集的标识字符串(而我将在 @987654322 上显示此字符串的任务留给你@options) 是

使用(至少偶尔)标签 git describe(带有相关选项)在构建阶段

【讨论】:

【参考方案3】:

我会创建一个带有单个 var version stringversion.go 文件,然后在调用 go build 之前对其进行处理并在之后将其重置。换句话说,Go 不支持任何类型的代码生成,因此您需要依赖外部的东西来执行此操作。

【讨论】:

【参考方案4】:

如果您可以将 git 修订版放入 $VERSION 并在您的主包中有一个名为 version(类型字符串)的变量,您可以在构建过程中设置它:

#!/bin/sh
VERSION=`git rev-parse --short HEAD`
go build -ldflags "-X main.version=$VERSION"  myfile.go

【讨论】:

这太棒了。顺便说一句,git describe 做得很好(特别是如果你有标签) 我在构建时遇到错误 - -X 标志需要 importpath.name=value 形式的参数 @VivekR 感谢您的评论,我已经修复了我的答案。【参考方案5】:

从 Go 1.18(2021 年第四季度/2022 年第一季度)开始,正常流程不应再涉及任何 ldflags

见issue 37475和CL 356013

go 命令现在将版本控制信息嵌入到二进制文件中,包括当前签出的修订版本和指示是否存在已编辑或未跟踪文件的标志。

如果在 Git 或 Mercurial 存储库中的目录中调用 go 命令,并且 main 包及其包含的 main 模块位于同一存储库中,则会嵌入版本控制信息。 可以使用标志 -buildvcs=false 省略此信息。

此外,go 命令嵌入了以下信息:

包含构建和工具标签的构建(使用-tags 设置), 编译器, 汇编器和 链接器标志(如-gcflags), cgo 是否启用,如果启用,cgo 环境变量的值(如CGO_CFLAGS)。

可以使用标志-buildinfo=false 省略此信息。

VCS 和构建信息都可以与模块信息一起使用:

go version -m fileruntime/debug.ReadBuildInfo(用于当前运行的二进制文件)或 新的debug/buildinfo package。

CL 373875 补充

BuildInfo 结构具有新字段,其中包含有关如何构建二进制文件的附加信息。 新的 GoVersion 字段包含用于构建二进制文件的 Go 版本。 新的Settings 字段是BuildSettings 结构的一部分,其中包含描述构建的键/值对。

【讨论】:

以上是关于Go:如何将 git 修订添加到构建的二进制文件中?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 gdoc 的修订历史导出到 git?

如何将文件嵌入到 Go 二进制文件中

如何将 Go 添加到 gitg 的可见源列表?

如何从特定修订版更改 GIT 中提交的作者 [重复]

Git 如何处理二进制文件?

如何使用 git hash 作为构建版本或 CFBundleVersion