From 5f98f96ea4a13c400150f09fdb82bbf6d90b8f5b Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Tue, 26 May 2020 16:31:21 +0200 Subject: [PATCH] make: add build and release commands --- .gitignore | 8 +- Makefile | 183 ++++++++++++++++++++++++++++++++++++++++++ make/release_flags.mk | 27 +++++++ release.sh | 111 +++++++++++++++++++++++++ 4 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 Makefile create mode 100644 make/release_flags.mk create mode 100755 release.sh diff --git a/.gitignore b/.gitignore index a9a880a1..8b80c565 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,10 @@ https.cert https.key # local environment vars to ignore -.env*.local \ No newline at end of file +.env*.local + +shushtar-debug +/shushtar-* + +# go code generated by statik +/statik/statik.go diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..6e67bbe9 --- /dev/null +++ b/Makefile @@ -0,0 +1,183 @@ +PKG := github.com/lightninglabs/shushtar +ESCPKG := github.com\/lightninglabs\/shushtar +LND_PKG := github.com/lightningnetwork/lnd + +LINT_PKG := github.com/golangci/golangci-lint/cmd/golangci-lint +GOVERALLS_PKG := github.com/mattn/goveralls +GOACC_PKG := github.com/ory/go-acc +STATIK_PKG := github.com/rakyll/statik + +GO_BIN := ${GOPATH}/bin +GOVERALLS_BIN := $(GO_BIN)/goveralls +LINT_BIN := $(GO_BIN)/golangci-lint +GOACC_BIN := $(GO_BIN)/go-acc +STATIK_BIN := $(GO_BIN)/statik + +COMMIT := $(shell git describe --abbrev=40 --dirty --tags) + +LINT_COMMIT := v1.18.0 +GOACC_COMMIT := ddc355013f90fea78d83d3a6c71f1d37ac07ecd5 + +DEPGET := cd /tmp && GO111MODULE=on go get -v +GOBUILD := GO111MODULE=on go build -v +GOINSTALL := GO111MODULE=on go install -v +GOTEST := GO111MODULE=on go test -v +GOMOD := GO111MODULE=on go mod + +GOFILES_NOVENDOR = $(shell find . -type f -name '*.go' -not -path "./vendor/*") +GOLIST := go list -deps $(PKG)/... | grep '$(PKG)'| grep -v '/vendor/' +GOLISTCOVER := $(shell go list -deps -f '{{.ImportPath}}' ./... | grep '$(PKG)' | sed -e 's/^$(ESCPKG)/./') + +RM := rm -f +CP := cp +MAKE := make +XARGS := xargs -L 1 + +LINT = $(LINT_BIN) run -v + +include make/release_flags.mk + +# We only return the part inside the double quote here to avoid escape issues +# when calling the external release script. The second parameter can be used to +# add additional ldflags if needed (currently only used for the release). +make_ldflags = $(2) -X $(LND_PKG)/build.Commit=$(COMMIT) \ + -X $(LND_PKG)/build.CommitHash=$(COMMIT_HASH) \ + -X $(LND_PKG)/build.GoVersion=$(GOVERSION) \ + -X $(LND_PKG)/build.RawTags=$(shell echo $(1) | sed -e 's/ /,/g') + +LDFLAGS := $(call make_ldflags, $(LND_RELEASE_TAGS)) + +# For the release, we want to remove the symbol table and debug information (-s) +# and omit the DWARF symbol table (-w). Also we clear the build ID. +RELEASE_LDFLAGS := $(call make_ldflags, $(LND_RELEASE_TAGS), -s -w -buildid=) + +GREEN := "\\033[0;32m" +NC := "\\033[0m" +define print + echo $(GREEN)$1$(NC) +endef + +default: scratch + +all: scratch check install + +# ============ +# DEPENDENCIES +# ============ + +$(GOVERALLS_BIN): + @$(call print, "Fetching goveralls.") + go get -u $(GOVERALLS_PKG) + +$(LINT_BIN): + @$(call print, "Fetching linter") + $(DEPGET) $(LINT_PKG)@$(LINT_COMMIT) + +$(GOACC_BIN): + @$(call print, "Fetching go-acc") + $(DEPGET) $(GOACC_PKG)@$(GOACC_COMMIT) + +$(STATIK_BIN): + @$(call print, "Fetching statik") + $(DEPGET) $(STATIK_PKG) + +yarn-install: + @$(call print, "Installing app dependencies with yarn") + cd app; yarn + +# ============ +# INSTALLATION +# ============ +statik-build: $(STATIK_BIN) app-build + @$(call print, "Building statik package.") + statik -src=app/build + +build: statik-build go-build +install: statik-build go-install + +go-build: + @$(call print, "Building shushtar.") + $(GOBUILD) -tags="$(LND_RELEASE_TAGS)" -ldflags "$(LDFLAGS)" -o shushtar-debug $(PKG)/cmd/shushtar + +go-install: + @$(call print, "Installing shushtar.") + $(GOINSTALL) -tags="$(LND_RELEASE_TAGS)" -ldflags "$(LDFLAGS)" $(PKG)/cmd/shushtar + +app-build: yarn-install + @$(call print, "Building production app.") + cd app; yarn build + +release: statik-build + @$(call print, "Creating release of shushtar.") + ./release.sh build-release "$(VERSION_TAG)" "$(BUILD_SYSTEM)" "$(LND_RELEASE_TAGS)" "$(RELEASE_LDFLAGS)" + +scratch: build + +# ======= +# TESTING +# ======= + +check: unit + +unit: + @$(call print, "Running unit tests.") + $(UNIT) + +unit-cover: $(GOACC_BIN) + @$(call print, "Running unit coverage tests.") + $(GOACC_BIN) $(COVER_PKG) + +unit-race: + @$(call print, "Running unit race tests.") + env CGO_ENABLED=1 GORACE="history_size=7 halt_on_errors=1" $(UNIT_RACE) + +goveralls: $(GOVERALLS_BIN) + @$(call print, "Sending coverage report.") + $(GOVERALLS_BIN) -coverprofile=coverage.txt -service=travis-ci + +travis-race: lint unit-race + +travis-cover: lint unit-cover goveralls + +travis-itest: lint + + +# ============= +# FLAKE HUNTING +# ============= +flake-unit: + @$(call print, "Flake hunting unit tests.") + while [ $$? -eq 0 ]; do GOTRACEBACK=all $(UNIT) -count=1; done + +# ========= +# UTILITIES +# ========= +fmt: + @$(call print, "Formatting source.") + gofmt -l -w -s $(GOFILES_NOVENDOR) + +lint: $(LINT_BIN) + @$(call print, "Linting source.") + $(LINT) + +mod: + @$(call print, "Tidying modules.") + $(GOMOD) tidy + +mod-check: + @$(call print, "Checking modules.") + $(GOMOD) tidy + if test -n "$$(git status | grep -e "go.mod\|go.sum")"; then echo "Running go mod tidy changes go.mod/go.sum"; git status; git diff; exit 1; fi + +list: + @$(call print, "Listing commands.") + @$(MAKE) -qp | \ + awk -F':' '/^[a-zA-Z0-9][^$$#\/\t=]*:([^=]|$$)/ {split($$1,A,/ /);for(i in A)print A[i]}' | \ + grep -v Makefile | \ + sort + +clean: + @$(call print, "Cleaning source.$(NC)") + $(RM) ./shushtar-debug + $(RM) coverage.txt + $(RM) -r statik diff --git a/make/release_flags.mk b/make/release_flags.mk new file mode 100644 index 00000000..2616d7c5 --- /dev/null +++ b/make/release_flags.mk @@ -0,0 +1,27 @@ +VERSION_TAG = $(shell date +%Y%m%d)-01 +VERSION_CHECK = @$(call print, "Building master with date version tag") + +BUILD_SYSTEM = darwin-386 \ +darwin-amd64 \ +linux-386 \ +linux-amd64 \ +linux-armv6 \ +linux-armv7 \ +linux-arm64 \ +windows-386 \ +windows-amd64 \ +windows-arm + +LND_RELEASE_TAGS = grub autopilotrpc signrpc walletrpc chainrpc invoicesrpc watchtowerrpc + +# By default we will build all systems. But with the 'sys' tag, a specific +# system can be specified. This is useful to release for a subset of +# systems/architectures. +ifneq ($(sys),) +BUILD_SYSTEM = $(sys) +endif + +# Use all build tags by default but allow them to be overwritten. +ifneq ($(tags),) +LND_RELEASE_TAGS = $(tags) +endif diff --git a/release.sh b/release.sh new file mode 100755 index 00000000..4f9f529e --- /dev/null +++ b/release.sh @@ -0,0 +1,111 @@ +#!/bin/bash + +# Simple bash script to build basic lnd tools for all the platforms +# we support with the golang cross-compiler. +# +# Copyright (c) 2016 Company 0, LLC. +# Use of this source code is governed by the ISC +# license. + +set -e + +PKG="github.com/lightninglabs/shushtar" +PACKAGE=shushtar + +# green prints one line of green text (if the terminal supports it). +function green() { + echo -e "\e[0;32m${1}\e[0m" +} + +# red prints one line of red text (if the terminal supports it). +function red() { + echo -e "\e[0;31m${1}\e[0m" +} + +# build_release builds the actual release binaries. +# arguments: +function build_release() { + local tag=$1 + local sys=$2 + local buildtags=$3 + local ldflags=$4 + + green " - Packaging vendor" + go mod vendor + tar -czf vendor.tar.gz vendor + + maindir=$PACKAGE-$tag + mkdir -p $maindir + + cp vendor.tar.gz $maindir/ + rm vendor.tar.gz + rm -r vendor + + package_source="${maindir}/${PACKAGE}-source-${tag}.tar" + git archive -o "${package_source}" HEAD + gzip -f "${package_source}" >"${package_source}.gz" + + cd "${maindir}" + + for i in $sys; do + os=$(echo $i | cut -f1 -d-) + arch=$(echo $i | cut -f2 -d-) + arm= + + if [[ $arch == "armv6" ]]; then + arch=arm + arm=6 + elif [[ $arch == "armv7" ]]; then + arch=arm + arm=7 + fi + + dir="${PACKAGE}-${i}-${tag}" + mkdir "${dir}" + pushd "${dir}" + + green " - Building: ${os} ${arch} ${arm} with build tags '${buildtags}'" + env CGO_ENABLED=0 GOOS=$os GOARCH=$arch GOARM=$arm go build -v -trimpath -ldflags="${ldflags}" -tags="${buildtags}" ${PKG}/cmd/shushtar + popd + + if [[ $os == "windows" ]]; then + zip -r "${dir}.zip" "${dir}" + else + tar -cvzf "${dir}.tar.gz" "${dir}" + fi + + rm -r "${dir}" + done + + shasum -a 256 * >manifest-$tag.txt +} + +# usage prints the usage of the whole script. +function usage() { + red "Usage: " + red "release.sh build-release " +} + +# Whatever sub command is passed in, we need at least 2 arguments. +if [ "$#" -lt 2 ]; then + usage + exit 1 +fi + +# Extract the sub command and remove it from the list of parameters by shifting +# them to the left. +SUBCOMMAND=$1 +shift + +# Call the function corresponding to the specified sub command or print the +# usage if the sub command was not found. +case $SUBCOMMAND in +build-release) + green "Building release" + build_release "$@" + ;; +*) + usage + exit 1 + ;; +esac