From be4d74f8d22e573d37a4bf4514aa4320cb62a75d Mon Sep 17 00:00:00 2001 From: "C. Brown" Date: Wed, 8 May 2019 08:44:28 -0500 Subject: [PATCH] cmd, internal/build, docker: advertise commit date in unstable build versions (#19522) * add-date-to unstable * fields-insteadof-split * internal/build: support building with missing git * docker: add git history back to support commit date in version * internal/build: use PR commits hashes for PR builds --- .dockerignore | 4 --- Dockerfile | 2 +- Dockerfile.alltools | 2 +- build/ci.go | 1 + cmd/ethkey/main.go | 3 +- cmd/evm/main.go | 3 +- cmd/geth/config.go | 2 +- cmd/geth/consolecmd_test.go | 4 +-- cmd/geth/main.go | 3 +- cmd/geth/misccmd.go | 3 ++ cmd/swarm/global-store/main.go | 4 +++ cmd/swarm/main.go | 2 +- cmd/swarm/swarm-snapshot/main.go | 3 +- cmd/utils/flags.go | 7 ++--- internal/build/env.go | 52 ++++++++++++++++++++++++-------- internal/build/util.go | 13 ++++---- params/version.go | 5 ++- 17 files changed, 75 insertions(+), 38 deletions(-) diff --git a/.dockerignore b/.dockerignore index d280741c60..0c013d18b1 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,7 +1,3 @@ -**/.git -.git -!.git/HEAD -!.git/refs/heads **/*_test.go build/_workspace diff --git a/Dockerfile b/Dockerfile index 4b205d6492..c766576a8f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # Build Geth in a stock Go builder container FROM golang:1.12-alpine as builder -RUN apk add --no-cache make gcc musl-dev linux-headers +RUN apk add --no-cache make gcc musl-dev linux-headers git ADD . /go-ethereum RUN cd /go-ethereum && make geth diff --git a/Dockerfile.alltools b/Dockerfile.alltools index 4a4a26f8bc..a4adba9d5b 100644 --- a/Dockerfile.alltools +++ b/Dockerfile.alltools @@ -1,7 +1,7 @@ # Build Geth in a stock Go builder container FROM golang:1.12-alpine as builder -RUN apk add --no-cache make gcc musl-dev linux-headers +RUN apk add --no-cache make gcc musl-dev linux-headers git ADD . /go-ethereum RUN cd /go-ethereum && make all diff --git a/build/ci.go b/build/ci.go index f5553fd300..dbf158005d 100644 --- a/build/ci.go +++ b/build/ci.go @@ -284,6 +284,7 @@ func buildFlags(env build.Environment) (flags []string) { var ld []string if env.Commit != "" { ld = append(ld, "-X", "main.gitCommit="+env.Commit) + ld = append(ld, "-X", "main.gitDate="+env.Date) } if runtime.GOOS == "darwin" { ld = append(ld, "-s") diff --git a/cmd/ethkey/main.go b/cmd/ethkey/main.go index c434da0c05..a8399ad7c5 100644 --- a/cmd/ethkey/main.go +++ b/cmd/ethkey/main.go @@ -30,11 +30,12 @@ const ( // Git SHA1 commit hash of the release (set via linker flags) var gitCommit = "" +var gitDate = "" var app *cli.App func init() { - app = utils.NewApp(gitCommit, "an Ethereum key manager") + app = utils.NewApp(gitCommit, gitDate, "an Ethereum key manager") app.Commands = []cli.Command{ commandGenerate, commandInspect, diff --git a/cmd/evm/main.go b/cmd/evm/main.go index ebac2047aa..a5159c6b7e 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -27,9 +27,10 @@ import ( ) var gitCommit = "" // Git SHA1 commit hash of the release (set via linker flags) +var gitDate = "" var ( - app = utils.NewApp(gitCommit, "the evm command line interface") + app = utils.NewApp(gitCommit, gitDate, "the evm command line interface") DebugFlag = cli.BoolFlag{ Name: "debug", diff --git a/cmd/geth/config.go b/cmd/geth/config.go index f316380cee..8f0bae8225 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -101,7 +101,7 @@ func loadConfig(file string, cfg *gethConfig) error { func defaultNodeConfig() node.Config { cfg := node.DefaultConfig cfg.Name = clientIdentifier - cfg.Version = params.VersionWithCommit(gitCommit) + cfg.Version = params.VersionWithCommit(gitCommit, gitDate) cfg.HTTPModules = append(cfg.HTTPModules, "eth", "shh") cfg.WSModules = append(cfg.WSModules, "eth", "shh") cfg.IPCPath = "geth.ipc" diff --git a/cmd/geth/consolecmd_test.go b/cmd/geth/consolecmd_test.go index 34ba877020..4360451195 100644 --- a/cmd/geth/consolecmd_test.go +++ b/cmd/geth/consolecmd_test.go @@ -50,7 +50,7 @@ func TestConsoleWelcome(t *testing.T) { geth.SetTemplateFunc("goos", func() string { return runtime.GOOS }) geth.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) geth.SetTemplateFunc("gover", runtime.Version) - geth.SetTemplateFunc("gethver", func() string { return params.VersionWithMeta }) + geth.SetTemplateFunc("gethver", func() string { return params.VersionWithCommit("", "") }) geth.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) }) geth.SetTemplateFunc("apis", func() string { return ipcAPIs }) @@ -133,7 +133,7 @@ func testAttachWelcome(t *testing.T, geth *testgeth, endpoint, apis string) { attach.SetTemplateFunc("goos", func() string { return runtime.GOOS }) attach.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) attach.SetTemplateFunc("gover", runtime.Version) - attach.SetTemplateFunc("gethver", func() string { return params.VersionWithMeta }) + attach.SetTemplateFunc("gethver", func() string { return params.VersionWithCommit("", "") }) attach.SetTemplateFunc("etherbase", func() string { return geth.Etherbase }) attach.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) }) attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") }) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 0e89481fe3..838029333e 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -50,8 +50,9 @@ const ( var ( // Git SHA1 commit hash of the release (set via linker flags) gitCommit = "" + gitDate = "" // The app that holds all commands and flags. - app = utils.NewApp(gitCommit, "the go-ethereum command line interface") + app = utils.NewApp(gitCommit, gitDate, "the go-ethereum command line interface") // flags that configure the node nodeFlags = []cli.Flag{ utils.IdentityFlag, diff --git a/cmd/geth/misccmd.go b/cmd/geth/misccmd.go index f62e254786..39ca47872b 100644 --- a/cmd/geth/misccmd.go +++ b/cmd/geth/misccmd.go @@ -112,6 +112,9 @@ func version(ctx *cli.Context) error { if gitCommit != "" { fmt.Println("Git Commit:", gitCommit) } + if gitDate != "" { + fmt.Println("Git Commit Date:", gitDate) + } fmt.Println("Architecture:", runtime.GOARCH) fmt.Println("Protocol Versions:", eth.ProtocolVersions) fmt.Println("Network Id:", eth.DefaultConfig.NetworkId) diff --git a/cmd/swarm/global-store/main.go b/cmd/swarm/global-store/main.go index 52fafc8f6a..58505f9886 100644 --- a/cmd/swarm/global-store/main.go +++ b/cmd/swarm/global-store/main.go @@ -26,6 +26,7 @@ import ( var ( version = "0.1" gitCommit string // Git SHA1 commit hash of the release (set via linker flags) + gitDate string ) func main() { @@ -45,6 +46,9 @@ func newApp() (app *cli.App) { if len(gitCommit) >= 8 { app.Version += "-" + gitCommit[:8] } + if gitDate != "" { + app.Version += "-" + gitDate + } app.Usage = "Swarm Global Store" // app flags (for all commands) diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go index a4041eb3d1..f4c1dd688c 100644 --- a/cmd/swarm/main.go +++ b/cmd/swarm/main.go @@ -102,7 +102,7 @@ func init() { utils.ListenPortFlag.Value = 30399 } -var app = utils.NewApp("", "Ethereum Swarm") +var app = utils.NewApp("", "", "Ethereum Swarm") // This init function creates the cli.App. func init() { diff --git a/cmd/swarm/swarm-snapshot/main.go b/cmd/swarm/swarm-snapshot/main.go index 136295e511..4a1e8b4f59 100644 --- a/cmd/swarm/swarm-snapshot/main.go +++ b/cmd/swarm/swarm-snapshot/main.go @@ -25,6 +25,7 @@ import ( ) var gitCommit string // Git SHA1 commit hash of the release (set via linker flags) +var gitDate string // default value for "create" command --nodes flag const defaultNodes = 8 @@ -40,7 +41,7 @@ func main() { // newApp construct a new instance of Swarm Snapshot Utility. // Method Run is called on it in the main function and in tests. func newApp() (app *cli.App) { - app = utils.NewApp(gitCommit, "Swarm Snapshot Utility") + app = utils.NewApp(gitCommit, gitDate, "Swarm Snapshot Utility") app.Name = "swarm-snapshot" app.Usage = "" diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index ab4060dd21..2dc45cbba2 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -92,16 +92,13 @@ GLOBAL OPTIONS: } // NewApp creates an app with sane defaults. -func NewApp(gitCommit, usage string) *cli.App { +func NewApp(gitCommit, gitDate, usage string) *cli.App { app := cli.NewApp() app.Name = filepath.Base(os.Args[0]) app.Author = "" //app.Authors = nil app.Email = "" - app.Version = params.VersionWithMeta - if len(gitCommit) >= 8 { - app.Version += "-" + gitCommit[:8] - } + app.Version = params.VersionWithCommit(gitCommit, gitDate) app.Usage = usage return app } diff --git a/internal/build/env.go b/internal/build/env.go index b553e0ed80..b7aa0f1228 100644 --- a/internal/build/env.go +++ b/internal/build/env.go @@ -20,7 +20,9 @@ import ( "flag" "fmt" "os" + "strconv" "strings" + "time" ) var ( @@ -35,17 +37,17 @@ var ( // Environment contains metadata provided by the build environment. type Environment struct { - Name string // name of the environment - Repo string // name of GitHub repo - Commit, Branch, Tag string // Git info - Buildnum string - IsPullRequest bool - IsCronJob bool + Name string // name of the environment + Repo string // name of GitHub repo + Commit, Date, Branch, Tag string // Git info + Buildnum string + IsPullRequest bool + IsCronJob bool } func (env Environment) String() string { - return fmt.Sprintf("%s env (commit:%s branch:%s tag:%s buildnum:%s pr:%t)", - env.Name, env.Commit, env.Branch, env.Tag, env.Buildnum, env.IsPullRequest) + return fmt.Sprintf("%s env (commit:%s date:%s branch:%s tag:%s buildnum:%s pr:%t)", + env.Name, env.Commit, env.Date, env.Branch, env.Tag, env.Buildnum, env.IsPullRequest) } // Env returns metadata about the current CI environment, falling back to LocalEnv @@ -53,10 +55,15 @@ func (env Environment) String() string { func Env() Environment { switch { case os.Getenv("CI") == "true" && os.Getenv("TRAVIS") == "true": + commit := os.Getenv("TRAVIS_PULL_REQUEST_SHA") + if commit == "" { + os.Getenv("TRAVIS_COMMIT") + } return Environment{ Name: "travis", Repo: os.Getenv("TRAVIS_REPO_SLUG"), - Commit: os.Getenv("TRAVIS_COMMIT"), + Commit: commit, + Date: getDate(commit), Branch: os.Getenv("TRAVIS_BRANCH"), Tag: os.Getenv("TRAVIS_TAG"), Buildnum: os.Getenv("TRAVIS_BUILD_NUMBER"), @@ -64,10 +71,15 @@ func Env() Environment { IsCronJob: os.Getenv("TRAVIS_EVENT_TYPE") == "cron", } case os.Getenv("CI") == "True" && os.Getenv("APPVEYOR") == "True": + commit := os.Getenv("APPVEYOR_PULL_REQUEST_HEAD_COMMIT") + if commit == "" { + os.Getenv("APPVEYOR_REPO_COMMIT") + } return Environment{ Name: "appveyor", Repo: os.Getenv("APPVEYOR_REPO_NAME"), - Commit: os.Getenv("APPVEYOR_REPO_COMMIT"), + Commit: commit, + Date: getDate(commit), Branch: os.Getenv("APPVEYOR_REPO_BRANCH"), Tag: os.Getenv("APPVEYOR_REPO_TAG_NAME"), Buildnum: os.Getenv("APPVEYOR_BUILD_NUMBER"), @@ -84,14 +96,15 @@ func LocalEnv() Environment { env := applyEnvFlags(Environment{Name: "local", Repo: "ethereum/go-ethereum"}) head := readGitFile("HEAD") - if splits := strings.Split(head, " "); len(splits) == 2 { - head = splits[1] + if fields := strings.Fields(head); len(fields) == 2 { + head = fields[1] } else { return env } if env.Commit == "" { env.Commit = readGitFile(head) } + env.Date = getDate(env.Commit) if env.Branch == "" { if head != "HEAD" { env.Branch = strings.TrimPrefix(head, "refs/heads/") @@ -107,6 +120,21 @@ func firstLine(s string) string { return strings.Split(s, "\n")[0] } +func getDate(commit string) string { + if commit == "" { + return "" + } + out := RunGit("show", "-s", "--format=%ct", commit) + if out == "" { + return "" + } + date, err := strconv.ParseInt(strings.TrimSpace(out), 10, 64) + if err != nil { + panic(fmt.Sprintf("failed to parse git commit date: %v", err)) + } + return time.Unix(date, 0).Format("20060102") +} + func applyEnvFlags(env Environment) Environment { if !flag.Parsed() { panic("you need to call flag.Parse before Env or LocalEnv") diff --git a/internal/build/util.go b/internal/build/util.go index 319c0f2d3e..971d948c44 100644 --- a/internal/build/util.go +++ b/internal/build/util.go @@ -68,13 +68,14 @@ func RunGit(args ...string) string { cmd := exec.Command("git", args...) var stdout, stderr bytes.Buffer cmd.Stdout, cmd.Stderr = &stdout, &stderr - if err := cmd.Run(); err == exec.ErrNotFound { - if !warnedAboutGit { - log.Println("Warning: can't find 'git' in PATH") - warnedAboutGit = true + if err := cmd.Run(); err != nil { + if e, ok := err.(*exec.Error); ok && e.Err == exec.ErrNotFound { + if !warnedAboutGit { + log.Println("Warning: can't find 'git' in PATH") + warnedAboutGit = true + } + return "" } - return "" - } else if err != nil { log.Fatal(strings.Join(cmd.Args, " "), ": ", err, "\n", stderr.String()) } return strings.TrimSpace(stdout.String()) diff --git a/params/version.go b/params/version.go index d3954e0bc3..c91a26ed82 100644 --- a/params/version.go +++ b/params/version.go @@ -55,10 +55,13 @@ func ArchiveVersion(gitCommit string) string { return vsn } -func VersionWithCommit(gitCommit string) string { +func VersionWithCommit(gitCommit, gitDate string) string { vsn := VersionWithMeta if len(gitCommit) >= 8 { vsn += "-" + gitCommit[:8] } + if (VersionMeta != "stable") && (gitDate != "") { + vsn += "-" + gitDate + } return vsn }