英文:
Go: how to add git revision to binaries built?
问题
我想将当前的git修订号添加到由go build
构建的二进制文件中,这样我就可以像./mybinary --revision
这样做,以查看它是从哪个修订版本构建的(通常用于部署后的故障排除)。
显然,我不能将修订号放入源代码中,因为这样会用新的修订号更改源代码。
我想知道是否有其他方法可以做到这一点?
或者你认为这只是一个坏主意吗?如果是这样,建议建立构建的二进制文件与其源代码版本之间的关系的方法是什么?
版本号似乎不是一个好主意,因为它与分布式版本控制系统不兼容。
英文:
I want to add the current git revision number to the the binary built by go build
so that I can do something like ./mybinary --revision
to see which revision it is built from (usually for troubleshooting later on after deployment).
Obviously I cannot put the revision number into the source since that will change the source with a new revision.
I'm wondering if there is any other way to do this?
Or do you think this is just a bad idea? If so, what's the recommended way to establish the relation between built binaries and its source version?
Version numbers do not seem to be a good idea with a distributed version control system.
答案1
得分: 10
如果你能将git修订版本放入$VERSION中,并在你的主包中有一个名为version
的变量(类型为字符串),你可以在构建过程中设置它:
#!/bin/sh
VERSION=`git rev-parse --short HEAD`
go build -ldflags "-X main.version=$VERSION" myfile.go
英文:
If you can get the git revision into $VERSION and have a variable named version
(type string) in your main package, you can set it during the build with:
#!/bin/sh
VERSION=`git rev-parse --short HEAD`
go build -ldflags "-X main.version=$VERSION" myfile.go
答案2
得分: 6
正常流程不再涉及任何ldflags
,从Go 1.18(2021年第4季度/2022年第1季度)开始。
> go
命令现在在二进制文件中嵌入版本控制信息,包括当前检出的修订版本和一个指示是否存在已编辑或未跟踪文件的标志。
>
> 如果在Git或Mercurial存储库中的目录中调用go
命令,并且main
包及其包含的main
模块位于同一个存储库中,则会嵌入版本控制信息。
可以使用标志-buildvcs=false
来省略此信息。
>
> 此外,go
命令还嵌入了有关以下信息的信息:
>
> - 构建信息,包括使用-tags
设置的构建和工具标签,
> - 编译器,
> - 汇编器,
> - 链接器标志(如-gcflags
),
> - 是否启用了cgo
,如果启用了,则是cgo
环境变量的值(如CGO_CFLAGS
)。
>
> 可以使用标志-buildinfo=false
来省略此信息。
>
> 可以使用以下方式同时读取VCS和构建信息以及模块信息:
>
> - go version -m file
或
> - runtime/debug.ReadBuildInfo
(用于当前运行的二进制文件)或
> - 新的debug/buildinfo
包。
CL 373875添加了
> - BuildInfo
结构体具有关于二进制文件构建方式的附加信息的新字段。
> - 新的GoVersion
字段保存用于构建二进制文件的Go版本。
> - 新的Settings
字段是一个包含描述构建的键值对的BuildSettings
结构体切片。
英文:
The normal process should no longer involve any ldflags
, starting with Go 1.18 (Q4 2021/Q1 2022).
See issue 37475 and CL 356013
> The go
command now embeds version control information in binaries including the currently checked-out revision and a flag indicating whether edited or untracked files are present.
>
> Version control information is embedded if the go
command is invoked in a directory within a Git or Mercurial repository, and the main
package and its containing main
module are in the same repository.
This information may be omitted using the flag -buildvcs=false
.
>
> Additionally, the go
command embeds information about:
>
> - the build including build and tool tags (set with -tags
),
> - compiler,
> - assembler, and
> - linker flags (like -gcflags
),
> - whether cgo
was enabled, and if it was, the values of the cgo
environment variables (like CGO_CFLAGS
).
>
> This information may be omitted using the flag -buildinfo=false
.
>
> Both VCS and build information may be read together with module information using:
>
> - go version -m file
or
> - runtime/debug.ReadBuildInfo
(for the currently running binary) or
> - the new debug/buildinfo
package.
CL 373875 adds
> - The BuildInfo
struct has new fields with additional information about how the binary was built.
> - The new GoVersion
field holds the version of Go used to build the binary.
> - The new Settings
field is a slice of BuildSettings
structs holding key/value pairs describing the build.
答案3
得分: 2
我会创建一个名为version.go
的文件,其中只包含一个var version string
变量。然后,在调用go build
之前处理该变量,并在之后将其重置。换句话说,Go语言不支持任何类型的代码生成,所以你需要依赖外部工具来完成这个任务。
英文:
I'd create a version.go
file with a single var version string
and then process that before a call to go build
and reset it after. In other words, go doesn't support any type of code generation so you'll need to rely on something external to do this.
答案4
得分: 1
对于在Git中版本化的所有代码,获取任何变更集的标识字符串的最明显的方法(我将把在“--revision”选项上显示此字符串的任务留给您)是:
-
至少偶尔使用标签
-
在构建阶段使用git describe(使用相关选项)
英文:
For all and any versioned in Git code most obvious way for getting identification-string for any changeset (while I leave to you task of displaying this string on --revision
options) is
-
using (at least sporadically) tags
-
git describe (with relevant options) on build stage
答案5
得分: 0
通常,您会使用标签(在其他版本控制系统中也称为标签)来标记构建的文件。我通常会创建包含版本和构建日期的标签。例如v1.2_29Mar2013。如果我有几个产品可以从相同的代码库构建,我会包含一些用于识别产品的内容。
英文:
You would generally use tags (also known as labels in other version control systems) to note the files that make up a particular build. http://git-scm.com/book/en/Git-Basics-Tagging. I typically make tags that include the version and build date. For example v1.2_29Mar2013. If I have several products that can be built from the same code base I'll include something to identify which product.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论