Golang应用程序自动构建版本控制

Seb*_*oli 175 go

每次编译Go应用程序时,是否可以自动增加次要版本号?

我想在我的程序中设置一个版本号,带有一个自动增量部分:

$ myapp -version
MyApp version 0.5.132
Run Code Online (Sandbox Code Playgroud)

我设置的版本号为0.5,132是每次编译二进制时自动递增的值.

Go有可能吗?

axw*_*axw 317

Go链接器(go工具链接)有一个选项来设置未初始化的字符串变量的值:

-X importpath.name=value
  Set the value of the string variable in importpath named name to
Run Code Online (Sandbox Code Playgroud)

作为构建过程的一部分,您可以使用此设置版本字符串变量.您可以go使用该工具传递此信息-ldflags.例如,给定以下源文件:

package main

import "fmt"

var xyz string

func main() {
    fmt.Println(xyz)
}
Run Code Online (Sandbox Code Playgroud)

然后:

$ go run -ldflags "-X main.xyz=abc" main.go
abc
Run Code Online (Sandbox Code Playgroud)

为了设置main.minversion构建的构建日期和时间:

go build -ldflags "-X main.minversion=`date -u +.%Y%m%d.%H%M%S`" service.go
Run Code Online (Sandbox Code Playgroud)

如果编译时没有main.minversion以这种方式初始化,它将包含空字符串.

  • 请注意,需要完整的包名称.`go build -ldflags"-X pkg.version = 123"```go build -ldflags"-X path/to/pkg.version = 123"`无法正常工作.希望能帮助到你. (24认同)
  • `go build -ldflags"-X main.minversion \`date -u +.%Y%m%d%.H%M%S \`"service.go` (5认同)
  • 使用新1.5语法的工作示例,用于添加构建时变量```go build -ldflags"-X'main.buildtime = $(date -u'+%Y-%m-%d%H:%M:%S' )""``` (5认同)
  • 如果我使用`go bouild`而不是`go run`,那么这个值会保存到二进制文件中吗? (4认同)
  • goxc为你做这个:)默认情况下它使用-ldflags编译"-Xmain.VERSION xxx -Xmain.BUILD_DATE CurrentDateInISO8601",但你可以根据需要配置这些变量名.请参阅https://github.com/laher/goxc ...(免责声明:我写过goxc) (4认同)

peg*_*gli 25

-ldflags在构建混合命令行应用程序和库项目时,我无法使用该参数,因此我最终使用Makefile目标生成包含应用程序版本和构建日期的Go源文件:

BUILD_DATE := `date +%Y-%m-%d\ %H:%M`
VERSIONFILE := cmd/myapp/version.go

gensrc:
    rm -f $(VERSIONFILE)
    @echo "package main" > $(VERSIONFILE)
    @echo "const (" >> $(VERSIONFILE)
    @echo "  VERSION = \"1.0\"" >> $(VERSIONFILE)
    @echo "  BUILD_DATE = \"$(BUILD_DATE)\"" >> $(VERSIONFILE)
    @echo ")" >> $(VERSIONFILE)
Run Code Online (Sandbox Code Playgroud)

在我的init()方法中,我这样做:

flag.Usage = func() {
    fmt.Fprintf(os.Stderr, "%s version %s\n", os.Args[0], VERSION)
    fmt.Fprintf(os.Stderr, "built %s\n", BUILD_DATE)
    fmt.Fprintln(os.Stderr, "usage:")
    flag.PrintDefaults()
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您想要一个原子增加的内部版本号而不是构建日期,则可能需要创建一个包含最后一个内部版本号的本地文件.您的Makefile会将文件内容读入变量,递增,将其插入version.go文件而不是日期,然后将新的内部编号写回文件.

  • 好的解决方案 不过,我想我已经找到了-ldflags问题的原因.如果未触及由-X更新的包含变量的文件,则编译不会触发,并且您在二进制文件中具有旧版本.我的解决方案是触摸一个只包含变量的小文件,通过-ldflags"-X ..."重置. (2认同)

Mac*_*arz 22

另外我想发布一个小例子如何使用git和makefile:

--- Makefile ----

# This how we want to name the binary output
BINARY=gomake

# These are the values we want to pass for VERSION and BUILD
# git tag 1.0.1
# git commit -am "One more change after the tags"
VERSION=`git describe --tags`
BUILD=`date +%FT%T%z`

# Setup the -ldflags option for go build here, interpolate the variable values
LDFLAGS_f1=-ldflags "-w -s -X main.Version=${VERSION} -X main.Build=${BUILD} -X main.Entry=f1"
LDFLAGS_f2=-ldflags "-w -s -X main.Version=${VERSION} -X main.Build=${BUILD} -X main.Entry=f2"

# Builds the project
build:
    go build ${LDFLAGS_f1} -o ${BINARY}_f1
    go build ${LDFLAGS_f2} -o ${BINARY}_f2

# Installs our project: copies binaries
install:
    go install ${LDFLAGS_f1}

# Cleans our project: deletes binaries
clean:
    if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi

.PHONY: clean install
Run Code Online (Sandbox Code Playgroud)

make文件将创建两个可执行文件.一个是执行函数一,另一个是函数二作为主条目:

package main

import (
        "fmt"
)

var (

        Version string
        Build   string
        Entry   string

        funcs = map[string]func() {
                "f1":functionOne,"f2":functionTwo,
        }

)

func functionOne() {
    fmt.Println("This is function one")
}

func functionTwo() {
    fmt.Println("This is function two")
}

func main() {

        fmt.Println("Version: ", Version)
        fmt.Println("Build Time: ", Build)

    funcs[Entry]()

}
Run Code Online (Sandbox Code Playgroud)

然后运行:

make
Run Code Online (Sandbox Code Playgroud)

你会得到:

mab@h2470988:~/projects/go/gomake/3/gomake$ ls -al
total 2020
drwxrwxr-x 3 mab mab    4096 Sep  7 22:41 .
drwxrwxr-x 3 mab mab    4096 Aug 16 10:00 ..
drwxrwxr-x 8 mab mab    4096 Aug 17 16:40 .git
-rwxrwxr-x 1 mab mab 1023488 Sep  7 22:41 gomake_f1
-rwxrwxr-x 1 mab mab 1023488 Sep  7 22:41 gomake_f2
-rw-rw-r-- 1 mab mab     399 Aug 16 10:21 main.go
-rw-rw-r-- 1 mab mab     810 Sep  7 22:41 Makefile
mab@h2470988:~/projects/go/gomake/3/gomake$ ./gomake_f1
Version:  1.0.1-1-gfb51187
Build Time:  2016-09-07T22:41:38+0200
This is function one
mab@h2470988:~/projects/go/gomake/3/gomake$ ./gomake_f2
Version:  1.0.1-1-gfb51187
Build Time:  2016-09-07T22:41:39+0200
This is function two
Run Code Online (Sandbox Code Playgroud)

  • 或更简单:只需在两个不同的目录中建立两个主目录即可。该解决方案似乎经过了认真的设计。 (4认同)

And*_*ann 16

用于ldflagsmain包中设置变量:

与文件main.go

package main

import "fmt"

var (
    version string
    build   string
)

func main() {
    fmt.Println("version=", version)
    fmt.Println("build=", build)
}
Run Code Online (Sandbox Code Playgroud)

然后运行:

go run \
  -ldflags "-X main.version=1.0.0 -X main.build=12082019" \ 
  main.go
Run Code Online (Sandbox Code Playgroud)

建立:

go build -o mybinary \
  -ldflags "-X main.version=1.0.0 -X 'main.build=$(date)'" \ 
  main.go
Run Code Online (Sandbox Code Playgroud)

用于ldflags在非main包中设置变量:

与文件config.go

package config

import "fmt"

var (
    Version string
)

func LogVersion() {
    fmt.Println("version=", Version)
}
Run Code Online (Sandbox Code Playgroud)

您还将需要文件main.go

package main

import (
    "fmt"
    "github.com/user/repo/config"
}

func main() {
    config.LogVersion()
}
Run Code Online (Sandbox Code Playgroud)

首先构建您的二进制文件:

go build -o mybinary main.go 
Run Code Online (Sandbox Code Playgroud)

查找要设置的变量名的完整路径:

go tool nm <path_to_binary> | grep Version
Run Code Online (Sandbox Code Playgroud)

再次运行并构建二进制文件,但要使用ldflags

go run \
  -ldflags "-X github.com/user/repo/config.Version=1.0.0" \
  main.go --version       


go build -o mybinary \
  -ldflags "-X github.com/user/repo/config.Version=1.0.0" \
  main.go     
Run Code Online (Sandbox Code Playgroud)

https://github.com/golang/go/wiki/GcToolchainTricks#include-build-information-in-the-executable的启发


另外,如果您正在使用,请goreleaser阅读以下https://goreleaser.com/#using-the-main-version

默认明智的GoReleaser设置三个ldflags:

main.version:当前的Git标签
main.commit:当前的git commit SHA
main.date:日期符合RFC3339


如果您想在实际中看到它:https : //github.com/hoto/fuzzy-repo-finder/blob/master/pkg/config/config.go

  • goreleaser 文档的链接已更改:https://goreleaser.com/environment/#using-the-mainversion (2认同)

小智 12

使用多个-ldflags:

$ go build -ldflags "-X name1=value1 -X name2=value2" -o path/to/output
Run Code Online (Sandbox Code Playgroud)


Ost*_*ati 11

在Windows操作系统上给出以下程序

package main

import "fmt"

var (
    version string
    date    string
)

func main() {
    fmt.Printf("version=%s, date=%s", version, date)
}
Run Code Online (Sandbox Code Playgroud)

你可以建立使用

go build -ldflags "-X main.version=0.0.1 -X main.date=%date:~10,4%-%date:~4,2%-%date:~7,2%T%time:~0,2%:%time:~3,2%:%time:~6,2%"
Run Code Online (Sandbox Code Playgroud)

日期格式假定你的环境echo %date%Fri 07/22/2016echo %time%16:21:52.88

然后输出将是: version=0.0.1, date=2016-07-22T16:21:52