如何将git版本添加到构建的二进制文件中?

huangapple go评论109阅读模式
英文:

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季度)开始。

参见issue 37475CL 356013

> 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.

huangapple
  • 本文由 发表于 2013年3月30日 05:36:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/15711780.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定