为Go程序添加git与编译信息
GItHub Actions & Go Build
实现效果
可以通过/version获取到当前服务的git版本号以及相关信息,也可以看到编译时间与编译环境等信息。
实现原理
在进行Go程序的编译时,可以通过传入额外的参数来修改编译过程,比较常见的有:
o <output>
: 指定输出文件的名称。例如,go build -o myprogram
将生成名为myprogram
的可执行文件。ldflags "<flags>"
: 用于传递链接器(ld)的标志。您可以使用此选项将特定标志传递给链接器,例如设置版本信息或自定义链接行为。例如,go build -ldflags "-X main.version=1.0.0"
将在构建过程中设置名为version
的变量的值为1.0.0
。gcflags "<flags>"
: 用于传递Go编译器(gc)的标志。您可以使用此选项传递特定标志给编译器,例如优化级别或其他调试信息。例如,go build -gcflags "-N -l"
将禁用优化并生成带有调试信息的可执行文件。
本次的实现则是利用ldflags "<flags>"
指令进行信息的注入。
核心构建指令
接下来进行Go代码与GitHub Actions、Docker file的编写。
Go美化注入代码
新建一个.Go文件,以变量的形式用以储存在程序中需要的git与版本信息,并创建一个函数用以美化显示信息。
创建需要注入信息的变量,设置默认值为unknown,等待编译注入再进行重新赋值。
在Go项目中显示git与编译信息
可在main.go中设置命令行参数进行信息显示。
如下代码,在运行编译后的二进制文件时,通过-v
进行信息显示。
或者可以通过绑定接口的形式,在访问服务/version
时进行信息的显示。
Dockerfile编写
首先定义Go构建器
设置需要注入的构建参数的默认值
关键的注入则是通过在docker进行构建时也可以进行参数的绑定这个特性来完成的。
GitHub Action将ARG的参数传入docker build后,接下来则将信息传入到gf build或者go build中,首先构建传入的信息。
以'home-network-watcher/utility/bin_utils.GitTag=${GIT_TAG}'
为例
go通过追溯包名进行参数数据的传递,在上述定义存储变量的Go文件中,模块为"home-network-watcher/utility/bin_utils”
,则在构建时也是传入包名加内部的变量名进行数据传递,在这里我们将上面获取到的GIT_TAG传递给GitTag变量。
最后则是通过go build传递进去
以下为完整Dockerfile
Github Actions编写
十分简单,只需要利用Actions里面可以方便获取的git信息即可,通过—build-arg
传递入docker build中
将获取到的信息首先储存在$GITHUB_ENV
中,在构建docker build指令时进行传递
这样子便完成了git与版本信息的注入,十分的自动便捷。
结语
主要的难点还是如何将信息在整个构建的过程中传递下去,只要可以传递好所需的信息在构建的时候即可以方便地通过go build的-ldflags将信息传递入二进制文件中。