mirror of https://github.com/status-im/op-geth.git
build: improve debian packaging
This commit tweaks the debian packaging tool: * All build environment metadata can now be overriden on the command line. This allows testing the CI build behaviour locally. * -unstable packages now actually contain the binaries (oops) * packages use Go 1.7 to build * archiving is skipped for PR builds
This commit is contained in:
parent
d8715fba1a
commit
4f7627972e
|
@ -27,7 +27,7 @@ matrix:
|
||||||
- debhelper
|
- debhelper
|
||||||
- dput
|
- dput
|
||||||
script:
|
script:
|
||||||
- go run build/ci.go travis-debsrc
|
- go run build/ci.go debsrc -signer "Felix Lange (Geth CI Testing Key) <fjl@twurst.com>" -upload ppa:lp-fjl/geth-ci-testing
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- go get golang.org/x/tools/cmd/cover
|
- go get golang.org/x/tools/cmd/cover
|
||||||
|
|
28
Makefile
28
Makefile
|
@ -42,12 +42,12 @@ geth-linux: geth-linux-386 geth-linux-amd64 geth-linux-arm geth-linux-mips64 get
|
||||||
@ls -ld $(GOBIN)/geth-linux-*
|
@ls -ld $(GOBIN)/geth-linux-*
|
||||||
|
|
||||||
geth-linux-386:
|
geth-linux-386:
|
||||||
build/env.sh go run build/ci.go xgo --go=$(GO) --dest=$(GOBIN) --targets=linux/386 -v ./cmd/geth
|
build/env.sh go run build/ci.go xgo -- --go=$(GO) --dest=$(GOBIN) --targets=linux/386 -v ./cmd/geth
|
||||||
@echo "Linux 386 cross compilation done:"
|
@echo "Linux 386 cross compilation done:"
|
||||||
@ls -ld $(GOBIN)/geth-linux-* | grep 386
|
@ls -ld $(GOBIN)/geth-linux-* | grep 386
|
||||||
|
|
||||||
geth-linux-amd64:
|
geth-linux-amd64:
|
||||||
build/env.sh go run build/ci.go xgo --go=$(GO) --dest=$(GOBIN) --targets=linux/amd64 -v ./cmd/geth
|
build/env.sh go run build/ci.go xgo -- --go=$(GO) --dest=$(GOBIN) --targets=linux/amd64 -v ./cmd/geth
|
||||||
@echo "Linux amd64 cross compilation done:"
|
@echo "Linux amd64 cross compilation done:"
|
||||||
@ls -ld $(GOBIN)/geth-linux-* | grep amd64
|
@ls -ld $(GOBIN)/geth-linux-* | grep amd64
|
||||||
|
|
||||||
|
@ -56,32 +56,32 @@ geth-linux-arm: geth-linux-arm-5 geth-linux-arm-6 geth-linux-arm-7 geth-linux-ar
|
||||||
@ls -ld $(GOBIN)/geth-linux-* | grep arm
|
@ls -ld $(GOBIN)/geth-linux-* | grep arm
|
||||||
|
|
||||||
geth-linux-arm-5:
|
geth-linux-arm-5:
|
||||||
build/env.sh go run build/ci.go xgo --go=$(GO) --dest=$(GOBIN) --targets=linux/arm-5 -v ./cmd/geth
|
build/env.sh go run build/ci.go xgo -- --go=$(GO) --dest=$(GOBIN) --targets=linux/arm-5 -v ./cmd/geth
|
||||||
@echo "Linux ARMv5 cross compilation done:"
|
@echo "Linux ARMv5 cross compilation done:"
|
||||||
@ls -ld $(GOBIN)/geth-linux-* | grep arm-5
|
@ls -ld $(GOBIN)/geth-linux-* | grep arm-5
|
||||||
|
|
||||||
geth-linux-arm-6:
|
geth-linux-arm-6:
|
||||||
build/env.sh go run build/ci.go xgo --go=$(GO) --dest=$(GOBIN) --targets=linux/arm-6 -v ./cmd/geth
|
build/env.sh go run build/ci.go xgo -- --go=$(GO) --dest=$(GOBIN) --targets=linux/arm-6 -v ./cmd/geth
|
||||||
@echo "Linux ARMv6 cross compilation done:"
|
@echo "Linux ARMv6 cross compilation done:"
|
||||||
@ls -ld $(GOBIN)/geth-linux-* | grep arm-6
|
@ls -ld $(GOBIN)/geth-linux-* | grep arm-6
|
||||||
|
|
||||||
geth-linux-arm-7:
|
geth-linux-arm-7:
|
||||||
build/env.sh go run build/ci.go xgo --go=$(GO) --dest=$(GOBIN) --targets=linux/arm-7 -v ./cmd/geth
|
build/env.sh go run build/ci.go xgo -- --go=$(GO) --dest=$(GOBIN) --targets=linux/arm-7 -v ./cmd/geth
|
||||||
@echo "Linux ARMv7 cross compilation done:"
|
@echo "Linux ARMv7 cross compilation done:"
|
||||||
@ls -ld $(GOBIN)/geth-linux-* | grep arm-7
|
@ls -ld $(GOBIN)/geth-linux-* | grep arm-7
|
||||||
|
|
||||||
geth-linux-arm64:
|
geth-linux-arm64:
|
||||||
build/env.sh go run build/ci.go xgo --go=$(GO) --dest=$(GOBIN) --targets=linux/arm64 -v ./cmd/geth
|
build/env.sh go run build/ci.go xgo -- --go=$(GO) --dest=$(GOBIN) --targets=linux/arm64 -v ./cmd/geth
|
||||||
@echo "Linux ARM64 cross compilation done:"
|
@echo "Linux ARM64 cross compilation done:"
|
||||||
@ls -ld $(GOBIN)/geth-linux-* | grep arm64
|
@ls -ld $(GOBIN)/geth-linux-* | grep arm64
|
||||||
|
|
||||||
geth-linux-mips64:
|
geth-linux-mips64:
|
||||||
build/env.sh go run build/ci.go xgo --go=$(GO) --dest=$(GOBIN) --targets=linux/mips64 -v ./cmd/geth
|
build/env.sh go run build/ci.go xgo -- --go=$(GO) --dest=$(GOBIN) --targets=linux/mips64 -v ./cmd/geth
|
||||||
@echo "Linux MIPS64 cross compilation done:"
|
@echo "Linux MIPS64 cross compilation done:"
|
||||||
@ls -ld $(GOBIN)/geth-linux-* | grep mips64
|
@ls -ld $(GOBIN)/geth-linux-* | grep mips64
|
||||||
|
|
||||||
geth-linux-mips64le:
|
geth-linux-mips64le:
|
||||||
build/env.sh go run build/ci.go xgo --go=$(GO) --dest=$(GOBIN) --targets=linux/mips64le -v ./cmd/geth
|
build/env.sh go run build/ci.go xgo -- --go=$(GO) --dest=$(GOBIN) --targets=linux/mips64le -v ./cmd/geth
|
||||||
@echo "Linux MIPS64le cross compilation done:"
|
@echo "Linux MIPS64le cross compilation done:"
|
||||||
@ls -ld $(GOBIN)/geth-linux-* | grep mips64le
|
@ls -ld $(GOBIN)/geth-linux-* | grep mips64le
|
||||||
|
|
||||||
|
@ -90,12 +90,12 @@ geth-darwin: geth-darwin-386 geth-darwin-amd64
|
||||||
@ls -ld $(GOBIN)/geth-darwin-*
|
@ls -ld $(GOBIN)/geth-darwin-*
|
||||||
|
|
||||||
geth-darwin-386:
|
geth-darwin-386:
|
||||||
build/env.sh go run build/ci.go xgo --go=$(GO) --dest=$(GOBIN) --targets=darwin/386 -v ./cmd/geth
|
build/env.sh go run build/ci.go xgo -- --go=$(GO) --dest=$(GOBIN) --targets=darwin/386 -v ./cmd/geth
|
||||||
@echo "Darwin 386 cross compilation done:"
|
@echo "Darwin 386 cross compilation done:"
|
||||||
@ls -ld $(GOBIN)/geth-darwin-* | grep 386
|
@ls -ld $(GOBIN)/geth-darwin-* | grep 386
|
||||||
|
|
||||||
geth-darwin-amd64:
|
geth-darwin-amd64:
|
||||||
build/env.sh go run build/ci.go xgo --go=$(GO) --dest=$(GOBIN) --targets=darwin/amd64 -v ./cmd/geth
|
build/env.sh go run build/ci.go xgo -- --go=$(GO) --dest=$(GOBIN) --targets=darwin/amd64 -v ./cmd/geth
|
||||||
@echo "Darwin amd64 cross compilation done:"
|
@echo "Darwin amd64 cross compilation done:"
|
||||||
@ls -ld $(GOBIN)/geth-darwin-* | grep amd64
|
@ls -ld $(GOBIN)/geth-darwin-* | grep amd64
|
||||||
|
|
||||||
|
@ -104,21 +104,21 @@ geth-windows: geth-windows-386 geth-windows-amd64
|
||||||
@ls -ld $(GOBIN)/geth-windows-*
|
@ls -ld $(GOBIN)/geth-windows-*
|
||||||
|
|
||||||
geth-windows-386:
|
geth-windows-386:
|
||||||
build/env.sh go run build/ci.go xgo --go=$(GO) --dest=$(GOBIN) --targets=windows/386 -v ./cmd/geth
|
build/env.sh go run build/ci.go xgo -- --go=$(GO) --dest=$(GOBIN) --targets=windows/386 -v ./cmd/geth
|
||||||
@echo "Windows 386 cross compilation done:"
|
@echo "Windows 386 cross compilation done:"
|
||||||
@ls -ld $(GOBIN)/geth-windows-* | grep 386
|
@ls -ld $(GOBIN)/geth-windows-* | grep 386
|
||||||
|
|
||||||
geth-windows-amd64:
|
geth-windows-amd64:
|
||||||
build/env.sh go run build/ci.go xgo --go=$(GO) --dest=$(GOBIN) --targets=windows/amd64 -v ./cmd/geth
|
build/env.sh go run build/ci.go xgo -- --go=$(GO) --dest=$(GOBIN) --targets=windows/amd64 -v ./cmd/geth
|
||||||
@echo "Windows amd64 cross compilation done:"
|
@echo "Windows amd64 cross compilation done:"
|
||||||
@ls -ld $(GOBIN)/geth-windows-* | grep amd64
|
@ls -ld $(GOBIN)/geth-windows-* | grep amd64
|
||||||
|
|
||||||
geth-android:
|
geth-android:
|
||||||
build/env.sh go run build/ci.go xgo --go=$(GO) --dest=$(GOBIN) --targets=android-21/aar -v ./cmd/geth
|
build/env.sh go run build/ci.go xgo -- --go=$(GO) --dest=$(GOBIN) --targets=android-21/aar -v ./cmd/geth
|
||||||
@echo "Android cross compilation done:"
|
@echo "Android cross compilation done:"
|
||||||
@ls -ld $(GOBIN)/geth-android-*
|
@ls -ld $(GOBIN)/geth-android-*
|
||||||
|
|
||||||
geth-ios:
|
geth-ios:
|
||||||
build/env.sh go run build/ci.go xgo --go=$(GO) --dest=$(GOBIN) --targets=ios-7.0/framework -v ./cmd/geth
|
build/env.sh go run build/ci.go xgo -- --go=$(GO) --dest=$(GOBIN) --targets=ios-7.0/framework -v ./cmd/geth
|
||||||
@echo "iOS framework cross compilation done:"
|
@echo "iOS framework cross compilation done:"
|
||||||
@ls -ld $(GOBIN)/geth-ios-*
|
@ls -ld $(GOBIN)/geth-ios-*
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
Debian Packaging
|
# Debian Packaging
|
||||||
----------------
|
|
||||||
|
|
||||||
Tagged releases and develop branch commits are available as installable Debian packages
|
Tagged releases and develop branch commits are available as installable Debian packages
|
||||||
for Ubuntu. Packages are built for the all Ubuntu versions which are supported by
|
for Ubuntu. Packages are built for the all Ubuntu versions which are supported by
|
||||||
|
@ -8,6 +7,7 @@ Canonical:
|
||||||
- Trusty Tahr (14.04 LTS)
|
- Trusty Tahr (14.04 LTS)
|
||||||
- Wily Werewolf (15.10)
|
- Wily Werewolf (15.10)
|
||||||
- Xenial Xerus (16.04 LTS)
|
- Xenial Xerus (16.04 LTS)
|
||||||
|
- Yakkety Yak (16.10)
|
||||||
|
|
||||||
Packages of develop branch commits have suffix -unstable and cannot be installed alongside
|
Packages of develop branch commits have suffix -unstable and cannot be installed alongside
|
||||||
the stable version. Switching between release streams requires user intervention.
|
the stable version. Switching between release streams requires user intervention.
|
||||||
|
@ -21,6 +21,29 @@ variable which Travis CI makes available to certain builds.
|
||||||
We want to build go-ethereum with the most recent version of Go, irrespective of the Go
|
We want to build go-ethereum with the most recent version of Go, irrespective of the Go
|
||||||
version that is available in the main Ubuntu repository. In order to make this possible,
|
version that is available in the main Ubuntu repository. In order to make this possible,
|
||||||
our PPA depends on the ~gophers/ubuntu/archive PPA. Our source package build-depends on
|
our PPA depends on the ~gophers/ubuntu/archive PPA. Our source package build-depends on
|
||||||
golang-1.6, which is co-installable alongside the regular golang package. PPA dependencies
|
golang-1.7, which is co-installable alongside the regular golang package. PPA dependencies
|
||||||
can be edited at https://launchpad.net/%7Elp-fjl/+archive/ubuntu/geth-ci-testing/+edit-dependencies
|
can be edited at https://launchpad.net/%7Elp-fjl/+archive/ubuntu/geth-ci-testing/+edit-dependencies
|
||||||
|
|
||||||
|
## Building Packages Locally (for testing)
|
||||||
|
|
||||||
|
You need to run Ubuntu to do test packaging.
|
||||||
|
|
||||||
|
Add the gophers PPA and install Go 1.7 and Debian packaging tools:
|
||||||
|
|
||||||
|
$ sudo apt-add-repository ppa:gophers/ubuntu/archive
|
||||||
|
$ sudo apt-get update
|
||||||
|
$ sudo apt-get install build-essential golang-1.7 devscripts debhelper
|
||||||
|
|
||||||
|
Create the source packages:
|
||||||
|
|
||||||
|
$ go run build/ci.go debsrc -workdir dist
|
||||||
|
|
||||||
|
Then go into the source package directory for your running distribution and build the package:
|
||||||
|
|
||||||
|
$ cd dist/ethereum-unstable-1.5.0+xenial
|
||||||
|
$ dpkg-buildpackage
|
||||||
|
|
||||||
|
Built packages are placed in the dist/ directory.
|
||||||
|
|
||||||
|
$ cd ..
|
||||||
|
$ dpkg-deb -c geth-unstable_1.5.0+xenial_amd64.deb
|
||||||
|
|
189
build/ci.go
189
build/ci.go
|
@ -120,8 +120,6 @@ func main() {
|
||||||
doArchive(os.Args[2:])
|
doArchive(os.Args[2:])
|
||||||
case "debsrc":
|
case "debsrc":
|
||||||
doDebianSource(os.Args[2:])
|
doDebianSource(os.Args[2:])
|
||||||
case "travis-debsrc":
|
|
||||||
doTravisDebianSource(os.Args[2:])
|
|
||||||
case "xgo":
|
case "xgo":
|
||||||
doXgo(os.Args[2:])
|
doXgo(os.Args[2:])
|
||||||
default:
|
default:
|
||||||
|
@ -132,8 +130,8 @@ func main() {
|
||||||
// Compiling
|
// Compiling
|
||||||
|
|
||||||
func doInstall(cmdline []string) {
|
func doInstall(cmdline []string) {
|
||||||
commitHash := flag.String("gitcommit", "", "Git commit hash embedded into binary.")
|
|
||||||
flag.CommandLine.Parse(cmdline)
|
flag.CommandLine.Parse(cmdline)
|
||||||
|
env := build.Env()
|
||||||
|
|
||||||
// Check Go version. People regularly open issues about compilation
|
// Check Go version. People regularly open issues about compilation
|
||||||
// failure with outdated Go. This should save them the trouble.
|
// failure with outdated Go. This should save them the trouble.
|
||||||
|
@ -150,13 +148,17 @@ func doInstall(cmdline []string) {
|
||||||
packages = flag.Args()
|
packages = flag.Args()
|
||||||
}
|
}
|
||||||
|
|
||||||
goinstall := goTool("install", makeBuildFlags(*commitHash)...)
|
goinstall := goTool("install", buildFlags(env)...)
|
||||||
goinstall.Args = append(goinstall.Args, "-v")
|
goinstall.Args = append(goinstall.Args, "-v")
|
||||||
goinstall.Args = append(goinstall.Args, packages...)
|
goinstall.Args = append(goinstall.Args, packages...)
|
||||||
build.MustRun(goinstall)
|
build.MustRun(goinstall)
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeBuildFlags(commitHash string) (flags []string) {
|
func buildFlags(env build.Environment) (flags []string) {
|
||||||
|
if os.Getenv("GO_OPENCL") != "" {
|
||||||
|
flags = append(flags, "-tags", "opencl")
|
||||||
|
}
|
||||||
|
|
||||||
// Since Go 1.5, the separator char for link time assignments
|
// Since Go 1.5, the separator char for link time assignments
|
||||||
// is '=' and using ' ' prints a warning. However, Go < 1.5 does
|
// is '=' and using ' ' prints a warning. However, Go < 1.5 does
|
||||||
// not support using '='.
|
// not support using '='.
|
||||||
|
@ -164,26 +166,9 @@ func makeBuildFlags(commitHash string) (flags []string) {
|
||||||
if runtime.Version() > "go1.5" || strings.Contains(runtime.Version(), "devel") {
|
if runtime.Version() > "go1.5" || strings.Contains(runtime.Version(), "devel") {
|
||||||
sep = "="
|
sep = "="
|
||||||
}
|
}
|
||||||
|
// Set gitCommit constant via link-time assignment.
|
||||||
if os.Getenv("GO_OPENCL") != "" {
|
if env.Commit != "" {
|
||||||
flags = append(flags, "-tags", "opencl")
|
flags = append(flags, "-ldflags", "-X main.gitCommit"+sep+env.Commit)
|
||||||
}
|
|
||||||
|
|
||||||
// Set gitCommit constant via link-time assignment. If this is a git checkout, we can
|
|
||||||
// just get the current commit hash through git. Otherwise we fall back to the hash
|
|
||||||
// that was passed as -gitcommit.
|
|
||||||
//
|
|
||||||
// -gitcommit is required for Debian package builds. The source package doesn't
|
|
||||||
// contain .git but we still want to embed the commit hash into the packaged binary.
|
|
||||||
// The hash is rendered into the debian/rules build script when the source package is
|
|
||||||
// created.
|
|
||||||
if _, err := os.Stat(filepath.Join(".git", "HEAD")); !os.IsNotExist(err) {
|
|
||||||
if c := build.GitCommit(); c != "" {
|
|
||||||
commitHash = c
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if commitHash != "" {
|
|
||||||
flags = append(flags, "-ldflags", "-X main.gitCommit"+sep+commitHash)
|
|
||||||
}
|
}
|
||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
@ -253,7 +238,11 @@ func doArchive(cmdline []string) {
|
||||||
default:
|
default:
|
||||||
log.Fatal("unknown archive type: ", atype)
|
log.Fatal("unknown archive type: ", atype)
|
||||||
}
|
}
|
||||||
base := makeArchiveBasename()
|
|
||||||
|
env := build.Env()
|
||||||
|
maybeSkipArchive(env)
|
||||||
|
|
||||||
|
base := archiveBasename(env)
|
||||||
if err := build.WriteArchive("geth-"+base, ext, gethArchiveFiles); err != nil {
|
if err := build.WriteArchive("geth-"+base, ext, gethArchiveFiles); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -262,36 +251,41 @@ func doArchive(cmdline []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeArchiveBasename() string {
|
func archiveBasename(env build.Environment) string {
|
||||||
// date := time.Now().UTC().Format("200601021504")
|
// date := time.Now().UTC().Format("200601021504")
|
||||||
platform := runtime.GOOS + "-" + runtime.GOARCH
|
platform := runtime.GOOS + "-" + runtime.GOARCH
|
||||||
archive := platform + "-" + build.VERSION()
|
archive := platform + "-" + build.VERSION()
|
||||||
if commit := build.GitCommit(); commit != "" {
|
if env.Commit != "" {
|
||||||
archive += "-" + commit[:8]
|
archive += "-" + env.Commit[:8]
|
||||||
}
|
}
|
||||||
return archive
|
return archive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skips archiving for some build configurations.
|
||||||
|
func maybeSkipArchive(env build.Environment) {
|
||||||
|
if env.IsPullRequest {
|
||||||
|
log.Printf("skipping because this is a PR build")
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
if env.Branch != "develop" && !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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Debian Packaging
|
// Debian Packaging
|
||||||
|
|
||||||
// CLI entry point for Travis CI.
|
func doDebianSource(cmdline []string) {
|
||||||
func doTravisDebianSource(cmdline []string) {
|
var (
|
||||||
|
signer = flag.String("signer", "", `Signing key name, also used as package author`)
|
||||||
|
upload = flag.String("upload", "", `Where to upload the source package (usually "ppa:ethereum/ethereum")`)
|
||||||
|
workdir = flag.String("workdir", "", `Output directory for packages (uses temp dir if unset)`)
|
||||||
|
now = time.Now()
|
||||||
|
)
|
||||||
flag.CommandLine.Parse(cmdline)
|
flag.CommandLine.Parse(cmdline)
|
||||||
|
*workdir = makeWorkdir(*workdir)
|
||||||
// Package only whitelisted branches.
|
env := build.Env()
|
||||||
switch {
|
maybeSkipArchive(env)
|
||||||
case os.Getenv("TRAVIS_REPO_SLUG") != "ethereum/go-ethereum":
|
|
||||||
log.Printf("skipping because this is a fork build")
|
|
||||||
return
|
|
||||||
case os.Getenv("TRAVIS_PULL_REQUEST") != "false":
|
|
||||||
log.Printf("skipping because this is a PR build")
|
|
||||||
return
|
|
||||||
case os.Getenv("TRAVIS_BRANCH") != "develop" && !strings.HasPrefix(os.Getenv("TRAVIS_TAG"), "v1."):
|
|
||||||
log.Printf("skipping because branch %q tag %q is not on the whitelist",
|
|
||||||
os.Getenv("TRAVIS_BRANCH"),
|
|
||||||
os.Getenv("TRAVIS_TAG"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Import the signing key.
|
// Import the signing key.
|
||||||
if b64key := os.Getenv("PPA_SIGNING_KEY"); b64key != "" {
|
if b64key := os.Getenv("PPA_SIGNING_KEY"); b64key != "" {
|
||||||
|
@ -304,46 +298,16 @@ func doTravisDebianSource(cmdline []string) {
|
||||||
build.MustRun(gpg)
|
build.MustRun(gpg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign unstable status to non-tag builds.
|
// Create the packages.
|
||||||
unstable := "true"
|
|
||||||
if os.Getenv("TRAVIS_BRANCH") != "develop" && os.Getenv("TRAVIS_TAG") != "" {
|
|
||||||
unstable = "false"
|
|
||||||
}
|
|
||||||
|
|
||||||
doDebianSource([]string{
|
|
||||||
"-signer", "Felix Lange (Geth CI Testing Key) <fjl@twurst.com>",
|
|
||||||
"-buildnum", os.Getenv("TRAVIS_BUILD_NUMBER"),
|
|
||||||
"-upload", "ppa:lp-fjl/geth-ci-testing",
|
|
||||||
"-unstable", unstable,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// CLI entry point for doing packaging locally.
|
|
||||||
func doDebianSource(cmdline []string) {
|
|
||||||
var (
|
|
||||||
signer = flag.String("signer", "", `Signing key name, also used as package author`)
|
|
||||||
upload = flag.String("upload", "", `Where to upload the source package (usually "ppa:ethereum/ethereum")`)
|
|
||||||
buildnum = flag.String("buildnum", "", `Build number (included in version)`)
|
|
||||||
unstable = flag.Bool("unstable", false, `Use package name suffix "-unstable"`)
|
|
||||||
now = time.Now()
|
|
||||||
)
|
|
||||||
flag.CommandLine.Parse(cmdline)
|
|
||||||
|
|
||||||
// Create the debian worktree in /tmp.
|
|
||||||
tmpdir, err := ioutil.TempDir("", "eth-deb-build-")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, distro := range debDistros {
|
for _, distro := range debDistros {
|
||||||
meta := newDebMetadata(distro, *signer, *buildnum, *unstable, now)
|
meta := newDebMetadata(distro, *signer, env, now)
|
||||||
pkgdir := stageDebianSource(tmpdir, meta)
|
pkgdir := stageDebianSource(*workdir, meta)
|
||||||
debuild := exec.Command("debuild", "-S", "-sa", "-us", "-uc")
|
debuild := exec.Command("debuild", "-S", "-sa", "-us", "-uc")
|
||||||
debuild.Dir = pkgdir
|
debuild.Dir = pkgdir
|
||||||
build.MustRun(debuild)
|
build.MustRun(debuild)
|
||||||
|
|
||||||
changes := fmt.Sprintf("%s_%s_source.changes", meta.Name(), meta.VersionString())
|
changes := fmt.Sprintf("%s_%s_source.changes", meta.Name(), meta.VersionString())
|
||||||
changes = filepath.Join(tmpdir, changes)
|
changes = filepath.Join(*workdir, changes)
|
||||||
if *signer != "" {
|
if *signer != "" {
|
||||||
build.MustRunCommand("debsign", changes)
|
build.MustRunCommand("debsign", changes)
|
||||||
}
|
}
|
||||||
|
@ -353,35 +317,53 @@ func doDebianSource(cmdline []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type debExecutable struct {
|
func makeWorkdir(wdflag string) string {
|
||||||
Name, Description string
|
var err error
|
||||||
|
if wdflag != "" {
|
||||||
|
err = os.MkdirAll(wdflag, 0744)
|
||||||
|
} else {
|
||||||
|
wdflag, err = ioutil.TempDir("", "eth-deb-build-")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return wdflag
|
||||||
|
}
|
||||||
|
|
||||||
|
func isUnstableBuild(env build.Environment) bool {
|
||||||
|
if env.Branch != "develop" && env.Tag != "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
type debMetadata struct {
|
type debMetadata struct {
|
||||||
|
Env build.Environment
|
||||||
|
|
||||||
// go-ethereum version being built. Note that this
|
// go-ethereum version being built. Note that this
|
||||||
// is not the debian package version. The package version
|
// is not the debian package version. The package version
|
||||||
// is constructed by VersionString.
|
// is constructed by VersionString.
|
||||||
Version string
|
Version string
|
||||||
|
|
||||||
Author string // "name <email>", also selects signing key
|
Author string // "name <email>", also selects signing key
|
||||||
Buildnum string // build number
|
Distro, Time string
|
||||||
Distro, Commit, Time string
|
Executables []debExecutable
|
||||||
Executables []debExecutable
|
|
||||||
Unstable bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDebMetadata(distro, author, buildnum string, unstable bool, t time.Time) debMetadata {
|
type debExecutable struct {
|
||||||
|
Name, Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDebMetadata(distro, author string, env build.Environment, t time.Time) debMetadata {
|
||||||
if author == "" {
|
if author == "" {
|
||||||
// No signing key, use default author.
|
// No signing key, use default author.
|
||||||
author = "Ethereum Builds <fjl@ethereum.org>"
|
author = "Ethereum Builds <fjl@ethereum.org>"
|
||||||
}
|
}
|
||||||
return debMetadata{
|
return debMetadata{
|
||||||
Unstable: unstable,
|
Env: env,
|
||||||
Author: author,
|
Author: author,
|
||||||
Distro: distro,
|
Distro: distro,
|
||||||
Commit: build.GitCommit(),
|
|
||||||
Version: build.VERSION(),
|
Version: build.VERSION(),
|
||||||
Buildnum: buildnum,
|
|
||||||
Time: t.Format(time.RFC1123Z),
|
Time: t.Format(time.RFC1123Z),
|
||||||
Executables: debExecutables,
|
Executables: debExecutables,
|
||||||
}
|
}
|
||||||
|
@ -390,7 +372,7 @@ func newDebMetadata(distro, author, buildnum string, unstable bool, t time.Time)
|
||||||
// Name returns the name of the metapackage that depends
|
// Name returns the name of the metapackage that depends
|
||||||
// on all executable packages.
|
// on all executable packages.
|
||||||
func (meta debMetadata) Name() string {
|
func (meta debMetadata) Name() string {
|
||||||
if meta.Unstable {
|
if isUnstableBuild(meta.Env) {
|
||||||
return "ethereum-unstable"
|
return "ethereum-unstable"
|
||||||
}
|
}
|
||||||
return "ethereum"
|
return "ethereum"
|
||||||
|
@ -399,8 +381,8 @@ func (meta debMetadata) Name() string {
|
||||||
// VersionString returns the debian version of the packages.
|
// VersionString returns the debian version of the packages.
|
||||||
func (meta debMetadata) VersionString() string {
|
func (meta debMetadata) VersionString() string {
|
||||||
vsn := meta.Version
|
vsn := meta.Version
|
||||||
if meta.Buildnum != "" {
|
if meta.Env.Buildnum != "" {
|
||||||
vsn += "+build" + meta.Buildnum
|
vsn += "+build" + meta.Env.Buildnum
|
||||||
}
|
}
|
||||||
if meta.Distro != "" {
|
if meta.Distro != "" {
|
||||||
vsn += "+" + meta.Distro
|
vsn += "+" + meta.Distro
|
||||||
|
@ -419,7 +401,7 @@ func (meta debMetadata) ExeList() string {
|
||||||
|
|
||||||
// ExeName returns the package name of an executable package.
|
// ExeName returns the package name of an executable package.
|
||||||
func (meta debMetadata) ExeName(exe debExecutable) string {
|
func (meta debMetadata) ExeName(exe debExecutable) string {
|
||||||
if meta.Unstable {
|
if isUnstableBuild(meta.Env) {
|
||||||
return exe.Name + "-unstable"
|
return exe.Name + "-unstable"
|
||||||
}
|
}
|
||||||
return exe.Name
|
return exe.Name
|
||||||
|
@ -428,7 +410,7 @@ func (meta debMetadata) ExeName(exe debExecutable) string {
|
||||||
// ExeConflicts returns the content of the Conflicts field
|
// ExeConflicts returns the content of the Conflicts field
|
||||||
// for executable packages.
|
// for executable packages.
|
||||||
func (meta debMetadata) ExeConflicts(exe debExecutable) string {
|
func (meta debMetadata) ExeConflicts(exe debExecutable) string {
|
||||||
if meta.Unstable {
|
if isUnstableBuild(meta.Env) {
|
||||||
// Set up the conflicts list so that the *-unstable packages
|
// Set up the conflicts list so that the *-unstable packages
|
||||||
// cannot be installed alongside the regular version.
|
// cannot be installed alongside the regular version.
|
||||||
//
|
//
|
||||||
|
@ -461,8 +443,8 @@ func stageDebianSource(tmpdir string, meta debMetadata) (pkgdir string) {
|
||||||
build.RenderString("8\n", filepath.Join(debian, "compat"), 0644, meta)
|
build.RenderString("8\n", filepath.Join(debian, "compat"), 0644, meta)
|
||||||
build.RenderString("3.0 (native)\n", filepath.Join(debian, "source/format"), 0644, meta)
|
build.RenderString("3.0 (native)\n", filepath.Join(debian, "source/format"), 0644, meta)
|
||||||
for _, exe := range meta.Executables {
|
for _, exe := range meta.Executables {
|
||||||
install := filepath.Join(debian, exe.Name+".install")
|
install := filepath.Join(debian, meta.ExeName(exe)+".install")
|
||||||
docs := filepath.Join(debian, exe.Name+".docs")
|
docs := filepath.Join(debian, meta.ExeName(exe)+".docs")
|
||||||
build.Render("build/deb.install", install, 0644, exe)
|
build.Render("build/deb.install", install, 0644, exe)
|
||||||
build.Render("build/deb.docs", docs, 0644, exe)
|
build.Render("build/deb.docs", docs, 0644, exe)
|
||||||
}
|
}
|
||||||
|
@ -473,18 +455,19 @@ func stageDebianSource(tmpdir string, meta debMetadata) (pkgdir string) {
|
||||||
// Cross compilation
|
// Cross compilation
|
||||||
|
|
||||||
func doXgo(cmdline []string) {
|
func doXgo(cmdline []string) {
|
||||||
|
flag.CommandLine.Parse(cmdline)
|
||||||
|
env := build.Env()
|
||||||
|
|
||||||
// Make sure xgo is available for cross compilation
|
// Make sure xgo is available for cross compilation
|
||||||
gogetxgo := goTool("get", "github.com/karalabe/xgo")
|
gogetxgo := goTool("get", "github.com/karalabe/xgo")
|
||||||
build.MustRun(gogetxgo)
|
build.MustRun(gogetxgo)
|
||||||
|
|
||||||
// Execute the actual cross compilation
|
// Execute the actual cross compilation
|
||||||
pkg := cmdline[len(cmdline)-1]
|
xgo := xgoTool(append(buildFlags(env), flag.Args()...))
|
||||||
args := append(cmdline[:len(cmdline)-1], makeBuildFlags("")...)
|
build.MustRun(xgo)
|
||||||
|
|
||||||
build.MustRun(xgoTool(append(args, pkg)...))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func xgoTool(args ...string) *exec.Cmd {
|
func xgoTool(args []string) *exec.Cmd {
|
||||||
cmd := exec.Command(filepath.Join(GOBIN, "xgo"), args...)
|
cmd := exec.Command(filepath.Join(GOBIN, "xgo"), args...)
|
||||||
cmd.Env = []string{
|
cmd.Env = []string{
|
||||||
"GOPATH=" + build.GOPATH(),
|
"GOPATH=" + build.GOPATH(),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{{.Name}} ({{.VersionString}}) {{.Distro}}; urgency=low
|
{{.Name}} ({{.VersionString}}) {{.Distro}}; urgency=low
|
||||||
|
|
||||||
* git build of {{.Commit}}
|
* git build of {{.Env.Commit}}
|
||||||
|
|
||||||
-- {{.Author}} {{.Time}}
|
-- {{.Author}} {{.Time}}
|
||||||
|
|
|
@ -2,7 +2,7 @@ Source: {{.Name}}
|
||||||
Section: science
|
Section: science
|
||||||
Priority: extra
|
Priority: extra
|
||||||
Maintainer: {{.Author}}
|
Maintainer: {{.Author}}
|
||||||
Build-Depends: debhelper (>= 8.0.0), golang-1.6
|
Build-Depends: debhelper (>= 8.0.0), golang-1.7
|
||||||
Standards-Version: 3.9.5
|
Standards-Version: 3.9.5
|
||||||
Homepage: https://ethereum.org
|
Homepage: https://ethereum.org
|
||||||
Vcs-Git: git://github.com/ethereum/go-ethereum.git
|
Vcs-Git: git://github.com/ethereum/go-ethereum.git
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#export DH_VERBOSE=1
|
#export DH_VERBOSE=1
|
||||||
|
|
||||||
override_dh_auto_build:
|
override_dh_auto_build:
|
||||||
build/env.sh /usr/lib/go-1.6/bin/go run build/ci.go install -gitcommit {{.Commit}}
|
build/env.sh /usr/lib/go-1.7/bin/go run build/ci.go install -git-commit={{.Env.Commit}} -git-branch={{.Env.Branch}} -git-tag={{.Env.Tag}} -buildnum={{.Env.Buildnum}} -pull-request={{.Env.IsPullRequest}}
|
||||||
|
|
||||||
override_dh_auto_test:
|
override_dh_auto_test:
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
// Copyright 2016 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package build
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// These flags override values in build env.
|
||||||
|
GitCommitFlag = flag.String("git-commit", "", `Overrides git commit hash embedded into executables`)
|
||||||
|
GitBranchFlag = flag.String("git-branch", "", `Overrides git branch being built`)
|
||||||
|
GitTagFlag = flag.String("git-tag", "", `Overrides git tag being built`)
|
||||||
|
BuildnumFlag = flag.String("buildnum", "", `Overrides CI build number`)
|
||||||
|
PullRequestFlag = flag.Bool("pull-request", false, `Overrides pull request status of the build`)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Env returns metadata about the current CI environment, falling back to LocalEnv
|
||||||
|
// if not running on CI.
|
||||||
|
func Env() Environment {
|
||||||
|
switch {
|
||||||
|
case os.Getenv("CI") == "true" && os.Getenv("TRAVIS") == "true":
|
||||||
|
return Environment{
|
||||||
|
Name: "travis",
|
||||||
|
Repo: os.Getenv("TRAVIS_REPO_SLUG"),
|
||||||
|
Commit: os.Getenv("TRAVIS_COMMIT"),
|
||||||
|
Branch: os.Getenv("TRAVIS_BRANCH"),
|
||||||
|
Tag: os.Getenv("TRAVIS_TAG"),
|
||||||
|
Buildnum: os.Getenv("TRAVIS_BUILD_NUMBER"),
|
||||||
|
IsPullRequest: os.Getenv("TRAVIS_PULL_REQUEST") != "false",
|
||||||
|
}
|
||||||
|
case os.Getenv("CI") == "True" && os.Getenv("APPVEYOR") == "True":
|
||||||
|
return Environment{
|
||||||
|
Name: "appveyor",
|
||||||
|
Repo: os.Getenv("APPVEYOR_REPO_NAME"),
|
||||||
|
Commit: os.Getenv("APPVEYOR_REPO_COMMIT"),
|
||||||
|
Branch: os.Getenv("APPVEYOR_REPO_BRANCH"),
|
||||||
|
Tag: os.Getenv("APPVEYOR_REPO_TAG"),
|
||||||
|
Buildnum: os.Getenv("APPVEYOR_BUILD_NUMBER"),
|
||||||
|
IsPullRequest: os.Getenv("APPVEYOR_PULL_REQUEST_NUMBER") != "",
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return LocalEnv()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LocalEnv returns build environment metadata gathered from git.
|
||||||
|
func LocalEnv() Environment {
|
||||||
|
env := applyEnvFlags(Environment{Name: "local", Repo: "ethereum/go-ethereum"})
|
||||||
|
if _, err := os.Stat(".git"); err != nil {
|
||||||
|
return env
|
||||||
|
}
|
||||||
|
if env.Commit == "" {
|
||||||
|
env.Commit = RunGit("rev-parse", "HEAD")
|
||||||
|
}
|
||||||
|
if env.Branch == "" {
|
||||||
|
env.Branch = RunGit("symbolic-ref", "-q", "--short", "HEAD")
|
||||||
|
}
|
||||||
|
// Note that we don't get the current git tag. It would slow down
|
||||||
|
// builds and isn't used by anything.
|
||||||
|
return env
|
||||||
|
}
|
||||||
|
|
||||||
|
func applyEnvFlags(env Environment) Environment {
|
||||||
|
if !flag.Parsed() {
|
||||||
|
panic("you need to call flag.Parse before Env or LocalEnv")
|
||||||
|
}
|
||||||
|
if *GitCommitFlag != "" {
|
||||||
|
env.Commit = *GitCommitFlag
|
||||||
|
}
|
||||||
|
if *GitBranchFlag != "" {
|
||||||
|
env.Branch = *GitBranchFlag
|
||||||
|
}
|
||||||
|
if *GitTagFlag != "" {
|
||||||
|
env.Tag = *GitTagFlag
|
||||||
|
}
|
||||||
|
if *BuildnumFlag != "" {
|
||||||
|
env.Buildnum = *BuildnumFlag
|
||||||
|
}
|
||||||
|
if *PullRequestFlag {
|
||||||
|
env.IsPullRequest = true
|
||||||
|
}
|
||||||
|
return env
|
||||||
|
}
|
|
@ -29,9 +29,7 @@ import (
|
||||||
"text/template"
|
"text/template"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var DryRunFlag = flag.Bool("n", false, "dry run, don't execute commands")
|
||||||
DryRunFlag = flag.Bool("n", false, "dry run, don't execute commands")
|
|
||||||
)
|
|
||||||
|
|
||||||
// MustRun executes the given command and exits the host process for
|
// MustRun executes the given command and exits the host process for
|
||||||
// any error.
|
// any error.
|
||||||
|
@ -69,6 +67,7 @@ func GOPATH() string {
|
||||||
return strings.Join(newpath, string(filepath.ListSeparator))
|
return strings.Join(newpath, string(filepath.ListSeparator))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VERSION returns the content of the VERSION file.
|
||||||
func VERSION() string {
|
func VERSION() string {
|
||||||
version, err := ioutil.ReadFile("VERSION")
|
version, err := ioutil.ReadFile("VERSION")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -77,10 +76,8 @@ func VERSION() string {
|
||||||
return string(bytes.TrimSpace(version))
|
return string(bytes.TrimSpace(version))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GitCommit() string {
|
// RunGit runs a git subcommand and returns its output.
|
||||||
return RunGit("rev-parse", "HEAD")
|
// The command must complete successfully.
|
||||||
}
|
|
||||||
|
|
||||||
func RunGit(args ...string) string {
|
func RunGit(args ...string) string {
|
||||||
cmd := exec.Command("git", args...)
|
cmd := exec.Command("git", args...)
|
||||||
var stdout, stderr bytes.Buffer
|
var stdout, stderr bytes.Buffer
|
||||||
|
@ -94,12 +91,13 @@ func RunGit(args ...string) string {
|
||||||
return strings.TrimSpace(stdout.String())
|
return strings.TrimSpace(stdout.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render renders the given template file.
|
// Render renders the given template file into outputFile.
|
||||||
func Render(templateFile, outputFile string, outputPerm os.FileMode, x interface{}) {
|
func Render(templateFile, outputFile string, outputPerm os.FileMode, x interface{}) {
|
||||||
tpl := template.Must(template.ParseFiles(templateFile))
|
tpl := template.Must(template.ParseFiles(templateFile))
|
||||||
render(tpl, outputFile, outputPerm, x)
|
render(tpl, outputFile, outputPerm, x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RenderString renders the given template string into outputFile.
|
||||||
func RenderString(templateContent, outputFile string, outputPerm os.FileMode, x interface{}) {
|
func RenderString(templateContent, outputFile string, outputPerm os.FileMode, x interface{}) {
|
||||||
tpl := template.Must(template.New("").Parse(templateContent))
|
tpl := template.Must(template.New("").Parse(templateContent))
|
||||||
render(tpl, outputFile, outputPerm, x)
|
render(tpl, outputFile, outputPerm, x)
|
||||||
|
|
Loading…
Reference in New Issue