diff --git a/.github/workflows/builder.yml b/.github/workflows/builder.yml index ff79fbc..4e56dfc 100644 --- a/.github/workflows/builder.yml +++ b/.github/workflows/builder.yml @@ -122,7 +122,7 @@ jobs: uses: actions/upload-artifact@v2 with: name: ${{ steps.builder.outputs.filename }} - path: ./bin/${{ env.PRODUCT }}* + path: ./build/binary/${{ env.PRODUCT }}* if-no-files-found: error snapcraft: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d29f430..f3325f8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,33 +10,101 @@ env: permissions: write-all jobs: - setup: - name: Initial build env - runs-on: ubuntu-latest - steps: - - name: Set up Go 1.x - uses: actions/setup-go@v2 - with: - go-version: ^1.17 - build: - name: Checkout, build, archive, upload + name: Build + strategy: + matrix: + os: [ linux, freebsd, openbsd, dragonfly, windows, darwin ] + arch: [ amd64, 386 ] + include: + - os: linux + arch: arm + arm: 5 + - os: linux + arch: arm + arm: 6 + - os: linux + arch: arm + arm: 7 + - os: linux + arch: arm64 + - os: linux + arch: mips + mips: softfloat + - os: linux + arch: mips + mips: hardfloat + - os: linux + arch: mipsle + mipsle: softfloat + - os: linux + arch: mipsle + mipsle: hardfloat + - os: linux + arch: mips64 + - os: linux + arch: mips64le + - os: linux + arch: ppc64 + - os: linux + arch: ppc64le + - os: linux + arch: s390x + - os: windows + arch: arm + - os: windows + arch: arm64 + - os: android + arch: arm64 + - os: darwin + arch: arm64 + - os: freebsd + arch: arm64 + exclude: + - os: darwin + arch: 386 + - os: dragonfly + arch: 386 + fail-fast: false runs-on: ubuntu-latest - needs: setup + env: + GOOS: ${{ matrix.os }} + GOARCH: ${{ matrix.arch }} + GOARM: ${{ matrix.arm }} + GOMIPS: ${{ matrix.mips }} + GOMIPS64: ${{ matrix.mips64 }} + GOMIPSLE: ${{ matrix.mipsle }} steps: - name: Check out code into the Go module directory uses: actions/checkout@v2 + with: + fetch-depth: 0 - - name: List checked-out code - run: ls -al + - name: Set up Go 1.x + uses: actions/setup-go@v2 + with: + go-version: ^1.17 - name: Build fat binary - run: make all-arch + id: builder + run: | + ARGS="${GOOS}-${GOARCH}" + if [[ -n "${GOARM}" ]]; then + ARGS="${ARGS}v${GOARM}" + elif [[ -n "${GOMIPS}" ]]; then + ARGS="${ARGS}-${GOMIPS}" + elif [[ -n "${GOMIPS64}" ]]; then + ARGS="${ARGS}-${GOMIPS64}" + elif [[ -n "${GOMIPSLE}" ]]; then + ARGS="${ARGS}-${GOMIPSLE}" + fi + make ${ARGS} + echo "::set-output name=args::${ARGS}" - name: Archive binary - run: make releases + run: make TARGET=${{ steps.builder.outputs.args }} releases - - name: Upload archived binary + - name: Upload artifact uses: actions/upload-artifact@v2 with: name: ${{ env.PRODUCT }} diff --git a/.gitignore b/.gitignore index 9ce9461..ff09f94 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,6 @@ # vendor/ /bin -/build/package +/build/binary/* +/build/package/* +!/build/package/.gitkeep diff --git a/Makefile b/Makefile index 7934f7f..0d4e5f2 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,28 @@ export GO111MODULE = on +export CGO_ENABLED = 0 export GOPROXY = https://proxy.golang.org NAME = ipfs-pinner -BINDIR ?= ./bin +REPO = github.com/wabarc/ipfs-pinner +BINDIR ?= ./build/binary PACKDIR ?= ./build/package -GOBUILD := CGO_ENABLED=0 go build --ldflags="-s -w" -v -GOFILES := $(wildcard ./cmd/ipfs-pinner/*.go) -VERSION := $(shell git describe --tags `git rev-list --tags --max-count=1`) -VERSION := $(VERSION:v%=%) +LDFLAGS := $(shell echo "-X '${REPO}/version.Version=`git describe --tags --abbrev=0`'") +LDFLAGS := $(shell echo "${LDFLAGS} -X '${REPO}/version.Commit=`git rev-parse --short HEAD`'") +LDFLAGS := $(shell echo "${LDFLAGS} -X '${REPO}/version.BuildDate=`date +%FT%T%z`'") +GOBUILD ?= go build -trimpath --ldflags "-s -w ${LDFLAGS} -buildid=" -v +VERSION ?= $(shell git describe --tags `git rev-list --tags --max-count=1` | sed -e 's/v//g') +GOFILES ?= $(wildcard ./cmd/ipfs-pinner/*.go) PROJECT := github.com/wabarc/ipfs-pinner -PACKAGES := $(shell go list ./...) +PACKAGES ?= $(shell go list ./...) +DOCKER ?= $(shell which docker || which podman) +DOCKER_IMAGE := wabarc/ipfs-pinner +DEB_IMG_ARCH := amd64 + +.DEFAULT_GOAL := help + +.PHONY: help +help: ## show help message + @awk 'BEGIN {FS = ":.*##"; printf "Usage:\n make \n\nTargets: \033[36m\033[0m\n"} /^[$$()% 0-9a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) PLATFORM_LIST = \ darwin-amd64 \ @@ -19,7 +32,7 @@ PLATFORM_LIST = \ linux-armv5 \ linux-armv6 \ linux-armv7 \ - linux-armv8 \ + linux-arm64 \ linux-mips-softfloat \ linux-mips-hardfloat \ linux-mipsle-softfloat \ @@ -31,115 +44,98 @@ PLATFORM_LIST = \ linux-s390x \ freebsd-386 \ freebsd-amd64 \ + freebsd-arm64 \ openbsd-386 \ - openbsd-amd64 + openbsd-amd64 \ + dragonfly-amd64 \ + android-arm64 WINDOWS_ARCH_LIST = \ windows-386 \ - windows-amd64 - -.PHONY: all -all: linux-amd64 darwin-amd64 windows-amd64 - -darwin-386: - GOARCH=386 GOOS=darwin $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -darwin-amd64: - GOARCH=amd64 GOOS=darwin $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -darwin-arm64: - GOARCH=arm64 GOOS=darwin $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -linux-386: - GOARCH=386 GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -linux-amd64: - GOARCH=amd64 GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -linux-armv5: - GOARCH=arm GOOS=linux GOARM=5 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -linux-armv6: - GOARCH=arm GOOS=linux GOARM=6 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -linux-armv7: - GOARCH=arm GOOS=linux GOARM=7 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -linux-arm64: linux-armv8 -linux-armv8: - GOARCH=arm64 GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -linux-mips-softfloat: - GOARCH=mips GOMIPS=softfloat GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -linux-mips-hardfloat: - GOARCH=mips GOMIPS=hardfloat GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -linux-mipsle-softfloat: - GOARCH=mipsle GOMIPS=softfloat GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -linux-mipsle-hardfloat: - GOARCH=mipsle GOMIPS=hardfloat GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -linux-mips64: - GOARCH=mips64 GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -linux-mips64le: - GOARCH=mips64le GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -linux-ppc64: - GOARCH=ppc64 GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -linux-ppc64le: - GOARCH=ppc64le GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -linux-s390x: - GOARCH=s390x GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -freebsd-386: - GOARCH=386 GOOS=freebsd $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -freebsd-amd64: - GOARCH=amd64 GOOS=freebsd $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -freebsd-arm64: - GOARCH=arm64 GOOS=freebsd $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -openbsd-386: - GOARCH=386 GOOS=openbsd $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -openbsd-amd64: - GOARCH=amd64 GOOS=openbsd $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) - -windows-386: - GOARCH=386 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe $(GOFILES) - -windows-amd64: - GOARCH=amd64 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe $(GOFILES) - -fmt: - @echo "-> Running go fmt" - @go fmt $(PACKAGES) - + windows-amd64 \ + windows-arm \ + windows-arm64 + +.PHONY: \ + all-arch \ + tar_releases \ + zip_releases \ + releases \ + clean \ + test \ + fmt + +.SECONDEXPANSION: +%: ## Build binary, format: linux-amd64, darwin-arm64, full list: https://golang.org/doc/install/source#environment + $(eval OS := $(shell echo $@ | cut -d'-' -f1)) + $(eval ARM := $(shell echo $@ | cut -d'-' -f2 | grep arm | sed -e 's/arm64//' | tr -dc '[0-9]')) + $(eval ARCH := $(shell echo $@ | cut -d'-' -f2 | sed -e 's/armv.*/arm/' | grep -v $(OS))) + $(eval MIPS := $(shell echo $@ | cut -d'-' -f3)) + $(if $(strip $(OS)),,$(error missing OS)) + $(if $(strip $(ARCH)),,$(error missing ARCH)) + GOOS="$(OS)" GOARCH="$(ARCH)" GOMIPS="$(MIPS)" GOARM="$(ARM)" $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES) + +.PHONY: build +build: ## Build binary for current OS + $(GOBUILD) -o $(BINDIR)/$(NAME) $(GOFILES) + +.PHONY: linux-armv8 +linux-armv8: linux-arm64 + +ifeq ($(TARGET),) tar_releases := $(addsuffix .gz, $(PLATFORM_LIST)) zip_releases := $(addsuffix .zip, $(WINDOWS_ARCH_LIST)) +else +ifeq ($(findstring windows,$(TARGET)),windows) +zip_releases := $(addsuffix .zip, $(TARGET)) +else +tar_releases := $(addsuffix .gz, $(TARGET)) +endif +endif $(tar_releases): %.gz : % - @mkdir -p $(PACKDIR) chmod +x $(BINDIR)/$(NAME)-$(basename $@) - tar -czf $(PACKDIR)/$(NAME)-$(basename $@)-$(VERSION).tar.gz --transform "s/$(notdir $(BINDIR))//g" $(BINDIR)/$(NAME)-$(basename $@) + tar -czf $(PACKDIR)/$(NAME)-$(basename $@)-$(VERSION).tar.gz --transform "s/.*\///g" $(BINDIR)/$(NAME)-$(basename $@) LICENSE README.md $(zip_releases): %.zip : % - @mkdir -p $(PACKDIR) - zip -m -j $(PACKDIR)/$(NAME)-$(basename $@)-$(VERSION).zip $(BINDIR)/$(NAME)-$(basename $@).exe + @mv $(BINDIR)/$(NAME)-$(basename $@) $(BINDIR)/$(NAME)-$(basename $@).exe + zip -m -j $(PACKDIR)/$(NAME)-$(basename $@)-$(VERSION).zip $(BINDIR)/$(NAME)-$(basename $@).exe LICENSE README.md -all-arch: $(PLATFORM_LIST) $(WINDOWS_ARCH_LIST) +all-arch: $(PLATFORM_LIST) $(WINDOWS_ARCH_LIST) ## Build binary for all architecture -releases: $(tar_releases) $(zip_releases) +releases: $(tar_releases) $(zip_releases) ## Packaging all binaries -clean: +clean: ## Clean workspace rm -f $(BINDIR)/* rm -f $(PACKDIR)/* + rm -rf data-dir* + rm -rf coverage* + rm -rf *.out + rm -rf ipfs-pinner.db + +fmt: ## Format codebase + @echo "-> Running go fmt" + @go fmt $(PACKAGES) + +vet: ## Vet codebase + @echo "-> Running go vet" + @go vet $(PACKAGES) + +test: ## Run testing + @echo "-> Running go test" + @go clean -testcache + @CGO_ENABLED=1 go test -v -race -cover -coverprofile=coverage.out -covermode=atomic -parallel=1 ./... + +test-integration: ## Run integration testing + @echo 'mode: atomic' > coverage.out + @go list ./... | xargs -n1 -I{} sh -c 'CGO_ENABLED=1 go test -race -tags=integration -covermode=atomic -coverprofile=coverage.tmp -coverpkg $(go list ./... | tr "\n" ",") {} && tail -n +2 coverage.tmp >> coverage.out || exit 255' + @rm coverage.tmp + +test-cover: ## Collect code coverage + @echo "-> Running go tool cover" + @go tool cover -func=coverage.out + @go tool cover -html=coverage.out -o coverage.html -tag: - git tag v$(VERSION) +scan: ## Scan vulnerabilities + @echo "-> Scanning vulnerabilities..." + @go list -json -m all | $(DOCKER) run --rm -i sonatypecommunity/nancy sleuth --skip-update-check diff --git a/build/package/.gitkeep b/build/package/.gitkeep new file mode 100644 index 0000000..e69de29