diff options
Diffstat (limited to 'build/ci.go')
-rw-r--r-- | build/ci.go | 151 |
1 files changed, 102 insertions, 49 deletions
diff --git a/build/ci.go b/build/ci.go index 914ce9eae..5e63c2411 100644 --- a/build/ci.go +++ b/build/ci.go @@ -24,7 +24,7 @@ Usage: go run ci.go <command> <command flags/arguments> Available commands are: install [ -arch architecture ] [ packages... ] -- builds packages and executables - test [ -coverage ] [ -vet ] [ -misspell ] [ packages... ] -- runs the tests + test [ -coverage ] [ -misspell ] [ packages... ] -- runs the tests archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -upload dest ] -- archives build artefacts importkeys -- imports signing keys from env debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package @@ -32,6 +32,7 @@ Available commands are: aar [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an Android archive xcode [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an iOS XCode framework xgo [ -alltools ] [ options ] -- cross builds according to options + purge [ -store blobstore ] [ -days threshold ] -- purges old archives from the blobstore For all commands, -n prevents execution of external programs (dry run mode). @@ -73,42 +74,47 @@ var ( executablePath("bootnode"), executablePath("evm"), executablePath("geth"), - executablePath("swarm"), + executablePath("puppeth"), executablePath("rlpdump"), + executablePath("swarm"), } // A debian package is created for all executables listed here. debExecutables = []debExecutable{ { - Name: "geth", - Description: "Ethereum CLI client.", + Name: "abigen", + Description: "Source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages.", }, { Name: "bootnode", Description: "Ethereum bootnode.", }, { - Name: "rlpdump", - Description: "Developer utility tool that prints RLP structures.", - }, - { Name: "evm", Description: "Developer utility version of the EVM (Ethereum Virtual Machine) that is capable of running bytecode snippets within a configurable environment and execution mode.", }, { - Name: "swarm", - Description: "Ethereum Swarm daemon and tools", + Name: "geth", + Description: "Ethereum CLI client.", }, { - Name: "abigen", - Description: "Source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages.", + Name: "puppeth", + Description: "Ethereum private network manager.", + }, + { + Name: "rlpdump", + Description: "Developer utility tool that prints RLP structures.", + }, + { + Name: "swarm", + Description: "Ethereum Swarm daemon and tools", }, } // Distros for which packages are created. // Note: vivid is unsupported because there is no golang-1.6 package for it. // Note: wily is unsupported because it was officially deprecated on lanchpad. - debDistros = []string{"trusty", "xenial", "yakkety"} + debDistros = []string{"trusty", "xenial", "yakkety", "zesty"} ) var GOBIN, _ = filepath.Abs(filepath.Join("build", "bin")) @@ -146,6 +152,8 @@ func main() { doXCodeFramework(os.Args[2:]) case "xgo": doXgo(os.Args[2:]) + case "purge": + doPurge(os.Args[2:]) default: log.Fatal("unknown command ", os.Args[1]) } @@ -162,9 +170,9 @@ func doInstall(cmdline []string) { // Check Go version. People regularly open issues about compilation // failure with outdated Go. This should save them the trouble. - if runtime.Version() < "go1.4" && !strings.HasPrefix(runtime.Version(), "devel") { + if runtime.Version() < "go1.7" && !strings.HasPrefix(runtime.Version(), "devel") { log.Println("You have Go version", runtime.Version()) - log.Println("go-ethereum requires at least Go version 1.4 and cannot") + log.Println("go-ethereum requires at least Go version 1.7 and cannot") log.Println("be compiled with an earlier version. Please upgrade your Go installation.") os.Exit(1) } @@ -173,6 +181,8 @@ func doInstall(cmdline []string) { if flag.NArg() > 0 { packages = flag.Args() } + packages = build.ExpandPackagesNoVendor(packages) + if *arch == "" || *arch == runtime.GOARCH { goinstall := goTool("install", buildFlags(env)...) goinstall.Args = append(goinstall.Args, "-v") @@ -215,20 +225,16 @@ func doInstall(cmdline []string) { } func buildFlags(env build.Environment) (flags []string) { - if os.Getenv("GO_OPENCL") != "" { - flags = append(flags, "-tags", "opencl") + var ld []string + if env.Commit != "" { + ld = append(ld, "-X", "main.gitCommit="+env.Commit) } - - // Since Go 1.5, the separator char for link time assignments - // is '=' and using ' ' prints a warning. However, Go < 1.5 does - // not support using '='. - sep := " " - if runtime.Version() > "go1.5" || strings.Contains(runtime.Version(), "devel") { - sep = "=" + if runtime.GOOS == "darwin" { + ld = append(ld, "-s") } - // Set gitCommit constant via link-time assignment. - if env.Commit != "" { - flags = append(flags, "-ldflags", "-X main.gitCommit"+sep+env.Commit) + + if len(ld) > 0 { + flags = append(flags, "-ldflags", strings.Join(ld, " ")) } return flags } @@ -249,10 +255,7 @@ func goToolArch(arch string, subcmd string, args ...string) *exec.Cmd { cmd.Args = append(cmd.Args, []string{"-ldflags", "-extldflags -Wl,--allow-multiple-definition"}...) } } - cmd.Env = []string{ - "GO15VENDOREXPERIMENT=1", - "GOPATH=" + build.GOPATH(), - } + cmd.Env = []string{"GOPATH=" + build.GOPATH()} if arch == "" || arch == runtime.GOARCH { cmd.Env = append(cmd.Env, "GOBIN="+GOBIN) } else { @@ -274,38 +277,25 @@ func goToolArch(arch string, subcmd string, args ...string) *exec.Cmd { func doTest(cmdline []string) { var ( - vet = flag.Bool("vet", false, "Whether to run go vet") misspell = flag.Bool("misspell", false, "Whether to run the spell checker") coverage = flag.Bool("coverage", false, "Whether to record code coverage") ) flag.CommandLine.Parse(cmdline) + env := build.Env() packages := []string{"./..."} if len(flag.CommandLine.Args()) > 0 { packages = flag.CommandLine.Args() } - if len(packages) == 1 && packages[0] == "./..." { - // Resolve ./... manually since go vet will fail on vendored stuff - out, err := goTool("list", "./...").CombinedOutput() - if err != nil { - log.Fatalf("package listing failed: %v\n%s", err, string(out)) - } - packages = []string{} - for _, line := range strings.Split(string(out), "\n") { - if !strings.Contains(line, "vendor") { - packages = append(packages, strings.TrimSpace(line)) - } - } - } + packages = build.ExpandPackagesNoVendor(packages) + // Run analysis tools before the tests. - if *vet { - build.MustRun(goTool("vet", packages...)) - } + build.MustRun(goTool("vet", packages...)) if *misspell { spellcheck(packages) } // Run the actual tests. - gotest := goTool("test") + gotest := goTool("test", buildFlags(env)...) // Test a single package at a time. CI builders are slow // and some tests run into timeouts under load. gotest.Args = append(gotest.Args, "-p", "1") @@ -445,6 +435,10 @@ func maybeSkipArchive(env build.Environment) { log.Printf("skipping because this is a PR build") os.Exit(0) } + if env.IsCronJob { + log.Printf("skipping because this is a cron job") + os.Exit(0) + } if env.Branch != "master" && !strings.HasPrefix(env.Tag, "v1.") { log.Printf("skipping because branch %q, tag %q is not on the whitelist", env.Branch, env.Tag) os.Exit(0) @@ -970,3 +964,62 @@ func xgoTool(args []string) *exec.Cmd { } return cmd } + +// Binary distribution cleanups + +func doPurge(cmdline []string) { + var ( + store = flag.String("store", "", `Destination from where to purge archives (usually "gethstore/builds")`) + limit = flag.Int("days", 30, `Age threshold above which to delete unstalbe archives`) + ) + flag.CommandLine.Parse(cmdline) + + if env := build.Env(); !env.IsCronJob { + log.Printf("skipping because not a cron job") + os.Exit(0) + } + // Create the azure authentication and list the current archives + auth := build.AzureBlobstoreConfig{ + Account: strings.Split(*store, "/")[0], + Token: os.Getenv("AZURE_BLOBSTORE_TOKEN"), + Container: strings.SplitN(*store, "/", 2)[1], + } + blobs, err := build.AzureBlobstoreList(auth) + if err != nil { + log.Fatal(err) + } + // Iterate over the blobs, collect and sort all unstable builds + for i := 0; i < len(blobs); i++ { + if !strings.Contains(blobs[i].Name, "unstable") { + blobs = append(blobs[:i], blobs[i+1:]...) + i-- + } + } + for i := 0; i < len(blobs); i++ { + for j := i + 1; j < len(blobs); j++ { + iTime, err := time.Parse(time.RFC1123, blobs[i].Properties.LastModified) + if err != nil { + log.Fatal(err) + } + jTime, err := time.Parse(time.RFC1123, blobs[j].Properties.LastModified) + if err != nil { + log.Fatal(err) + } + if iTime.After(jTime) { + blobs[i], blobs[j] = blobs[j], blobs[i] + } + } + } + // Filter out all archives more recent that the given threshold + for i, blob := range blobs { + timestamp, _ := time.Parse(time.RFC1123, blob.Properties.LastModified) + if time.Since(timestamp) < time.Duration(*limit)*24*time.Hour { + blobs = blobs[:i] + break + } + } + // Delete all marked as such and return + if err := build.AzureBlobstoreDelete(auth, blobs); err != nil { + log.Fatal(err) + } +} |