Uygulama otomatik derleme sürüm oluşturma


193

Bir Go uygulaması her derlendiğinde küçük bir sürüm numarasını otomatik olarak artırmak mümkün müdür?

Programımın içinde, otomatik büyütme bölümü olan bir sürüm numarası ayarlamak istiyorum:

$ myapp -version
MyApp version 0.5.132

Ayarladığım sürüm numarasını 0,5 ve ikili dosya her derlendiğinde otomatik olarak artan bir değer olan 132'dir.

Go'da bu mümkün müdür?

Yanıtlar:


337

Git bağlayıcısının ( git aracı bağlantısı ), başlatılmamış bir dize değişkeninin değerini ayarlama seçeneği vardır:

-X importpath.name=value
  Set the value of the string variable in importpath named name to

değer. Go 1.5'ten önce bu seçeneğin iki ayrı argüman aldığını unutmayın. Şimdi ilk = işaretinde bir argüman bölünüyor.

Derleme işleminizin bir parçası olarak, bunu kullanarak bir sürüm dizesi değişkeni ayarlayabilirsiniz. Bunu gokullanarak araçtan geçebilirsiniz -ldflags. Örneğin, aşağıdaki kaynak dosya verildiğinde:

package main

import "fmt"

var xyz string

func main() {
    fmt.Println(xyz)
}

Sonra:

$ go run -ldflags "-X main.xyz=abc" main.go
abc

İnşa sırasında main.minversionyapım tarihi ve saatine ayarlamak için:

go build -ldflags "-X main.minversion=`date -u +.%Y%m%d.%H%M%S`" service.go

main.minversionBu şekilde başlatmadan derlerseniz, boş dize içerir.


4
go bouildBunun yerine kullanırsam bu değer ikili dosyaya kaydedilir go runmi?
Sebastián Grignoli

6
go build -ldflags "-X main.minversion `date -u +.%Y%m%d%.H%M%S`" service.go
Sebastián Grignoli

4
goxc bunu sizin için yapar :) varsayılan olarak -ldflags "-Xmain.VERSION xxx -Xmain.BUILD_DATE CurrentDateInISO8601" ile derler, ancak isterseniz bu değişken adlarını yapılandırabilirsiniz. Bkz. Github.com/laher/goxc ... (yasal uyarı: goxc yazdım)
laher

7
buildtime değişkeni eklemek için yeni 1.5 sözdizimi ile çalışma örneğigo build -ldflags "-X 'main.buildtime=$(date -u '+%Y-%m-%d %H:%M:%S')'"
xorpaul

26
tam paket adının gerekli olduğuna dikkat edin. beklendiği gibi go build -ldflags "-X pkg.version=123"çalışırken go build -ldflags "-X path/to/pkg.version=123"çalışmaz. Umarım yardımcı olur.
csyangchen

27

Ayrıca nasıl git ve bir makefile kullanmak için küçük bir örnek göndermek istiyorum:

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

Marka dosyası iki yürütülebilir dosya oluşturur. Biri birinci işlevi yürütüyor, diğeri ikinci girişi ana giriş olarak alacak:

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]()

}

Sonra sadece çalıştırın:

make

Alacaksın:

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

5
Ya da daha basit: iki farklı dizinde iki ana olun. Bu çözüm ciddi bir şekilde yeniden yapılandırılmış gibi görünüyor.
dolmen

26

-ldflagsKarma komut satırı uygulamamı ve kütüphane projemi oluştururken parametreyi kullanırken sorun yaşadım , bu yüzden uygulamamın sürümünü ve derleme tarihini içeren bir Go kaynak dosyası oluşturmak için Makefile hedefini kullandım:

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)

Benim init()yöntemde, bunu yapmak:

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()
}

Ancak, yapım tarihi yerine atomik olarak artan bir yapı numarası istiyorsanız, muhtemelen son yapı numarasını içeren yerel bir dosya oluşturmanız gerekir. Makefile'niz dosya içeriğini bir değişkene okur, artırır version.go, tarih yerine dosyaya ekler ve yeni yapı numarasını dosyaya geri yazar.


2
Güzel çözüm. Yine de, sanırım -ldflags sorunlarının nedenini buldum. -X tarafından güncellenen değişkeni içeren dosyaya dokunulmazsa, derleme tetiklenmez ve ikili dosyada eski sürümünüz vardır. Benim çözüm -ldflags "-X ..." üzerinden sıfırlanan sadece değişken içeren küçük bir dosyaya dokunmak oldu
Wojciech Kaczmarek

20

İçindeki ldflagsdeğişkenleri ayarlamak için kullanınmainPaketteki :

Dosya ile main.go:

package main

import "fmt"

var (
    version string
    build   string
)

func main() {
    fmt.Println("version=", version)
    fmt.Println("build=", build)
}

O zaman koş:

go run \
  -ldflags "-X main.version=1.0.0 -X main.build=12082019" \ 
  main.go

İnşa etmek:

go build -o mybinary \
  -ldflags "-X main.version=1.0.0 -X 'main.build=$(date)'" \ 
  main.go

Kullanım ldflagsa'da ayarlanan değişkenenon-main paketteki :

Dosya ile config.go:

package config

import "fmt"

var (
    Version string
)

func LogVersion() {
    fmt.Println("version=", Version)
}

Ayrıca dosyaya da ihtiyacınız olacak main.go:

package main

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

func main() {
    config.LogVersion()
}

Öncelikle ikili dosyanızı oluşturun:

go build -o mybinary main.go 

Ayarlamak istediğiniz değişken adının tam yolunu bulun:

go tool nm <path_to_binary> | grep Version

İkili çalıştırıp tekrar oluşturun 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     

Esinlenen https://github.com/golang/go/wiki/GcToolchainTricks#included-build-information-in-the-exutable


Ayrıca kullanıyorsanız, goreleaserbu https://goreleaser.com/#using-the-main-version adresini okuyun :

Varsayılan bilge GoReleaser üç ldflags ayarlar:

main.version: Geçerli Git etiketi
main.commit: Geçerli git commit SHA
main.date: RFC3339'a göre tarih


Bunu çalışırken görmek istiyorsanız: https://github.com/hoto/fuzzy-repo-finder/blob/master/pkg/config/config.go


12

multi kullanmak için -ldflags:

$ go build -ldflags "-X name1=value1 -X name2=value2" -o path/to/output

12

Windows işletim sisteminde aşağıdaki program verildi

package main

import "fmt"

var (
    version string
    date    string
)

func main() {
    fmt.Printf("version=%s, date=%s", version, date)
}

Kullanarak inşa edebilirsiniz

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%"

Tarih biçimi ortamınızı varsayar echo %date% olduğunu Fri 07/22/2016ve echo %time%bir16:21:52.88

Sonra çıktı: version=0.0.1, date=2016-07-22T16:21:52

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.