From d25cd15ea624cf023f11cfbc0be3648fc27b1b46 Mon Sep 17 00:00:00 2001 From: Amir Mofasser Date: Wed, 23 Sep 2020 14:32:35 +0200 Subject: [PATCH] Makefile improvements (#40) --- .gitignore | 2 + .travis.yml | 65 ++++---- Dockerfile | 4 +- Makefile | 237 ++++++++++++++++----------- charts/index.yaml | 0 charts/node-cert-exporter/Chart.yaml | 4 +- 6 files changed, 182 insertions(+), 130 deletions(-) create mode 100644 charts/index.yaml diff --git a/.gitignore b/.gitignore index 0e80de5..d48ab82 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out out/ +bin/ +test/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 4f4bd21..dd97869 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,60 +3,60 @@ dist: xenial language: go go: - - "1.12" - -cache: - directories: - - $GOPATH/pkg/mod - -env: -- GO111MODULE=on + - "1.13" + +before_install: + - curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash stages: - test - build - deploy -before_install: -- make dep - jobs: include: - stage: test name: "Verify" script: - make checkfmt - - make fmt + - make fmt - make vet + - make race - make gocyclo - - make golint + - make lint - make ineffassign - make misspell - make helm_lint + - name: "Unit Test" script: - make test - - name: "Integration Test" - script: - - make integration-test - - stage: build + - make benchmark + - make coverage + #- bash <(curl -s https://codecov.io/bash) + + - name: "Compile" + stage: build script: - - make linux - - make darwin - - make rpi - - make windows + - make + - stage: deploy name: "GitHub Releases" script: - - make build + - GOOS=linux GOARCH=amd64 BUILDPATH=./bin/node-cert-exporter-linux-amd64 make + - GOOS=linux GOARCH=arm BUILDPATH=./bin/node-cert-exporter-linux-arm make + - GOOS=linux GOARCH=arm64 BUILDPATH=./bin/node-cert-exporter-linux-arm64 make + - GOOS=windows GOARCH=amd64 BUILDPATH=./bin/node-cert-exporter-windows-amd64.exe make + - GOOS=darwin GOARCH=amd64 BUILDPATH=./bin/node-cert-exporter-darwin-amd64 make deploy: provider: releases api_key: ${GITHUB_API_KEY} - file: - - out/node-cert-exporter-linux-amd64 - - out/node-cert-exporter-darwin-amd64 - - out/node-cert-exporter-linux-arm - - out/node-cert-exporter-windows-amd64.exe + file: + - bin/node-cert-exporter-linux-amd64 + - bin/node-cert-exporter-linux-arm + - bin/node-cert-exporter-linux-arm64 + - bin/node-cert-exporter-windows-amd64.exe + - bin/node-cert-exporter-darwin-amd64 skip_cleanup: true draft: true on: @@ -64,12 +64,17 @@ jobs: - stage: deploy name: "GitHub Pages - Helm Chart" script: - - make helm_package - - make helm_index + - mkdir files-to-gh-pages + - helm package charts/node-cert-exporter -d files-to-gh-pages + - cp charts/node-cert-exporter/README.md files-to-gh-pages + - cd files-to-gh-pages + - helm repo index . + - ls -ltr + - cat index.yaml deploy: provider: pages github_token: ${GITHUB_API_KEY} - local_dir: charts + local_dir: files-to-gh-pages target_branch: gh-pages skip_cleanup: true keep_history: true diff --git a/Dockerfile b/Dockerfile index 5375663..d85c2a4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,9 +3,9 @@ RUN apk add --no-cache git make ca-certificates LABEL maintaner="@amimof (github.com/amimof)" COPY . /go/src/github.com/amimof/node-cert-exporter WORKDIR /go/src/github.com/amimof/node-cert-exporter -RUN make linux +RUN make FROM scratch -COPY --from=build-env /go/src/github.com/amimof/node-cert-exporter/out/node-cert-exporter-linux-amd64 /go/bin/node-cert-exporter +COPY --from=build-env /go/src/github.com/amimof/node-cert-exporter/bin/node-cert-exporter /go/bin/node-cert-exporter COPY --from=build-env /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ ENTRYPOINT ["/go/bin/node-cert-exporter"] \ No newline at end of file diff --git a/Makefile b/Makefile index 33bc2a2..34b94af 100644 --- a/Makefile +++ b/Makefile @@ -1,76 +1,131 @@ -# Borrowed from: -# https://github.com/silven/go-example/blob/master/Makefile -# https://vic.demuzere.be/articles/golang-makefile-crosscompile/ - -BINARY=node-cert-exporter -GOARCH=amd64 -VERSION=$(shell git describe --abbrev=0 --tags) +MODULE = $(shell env GO111MODULE=on $(GO) list -m) +DATE ?= $(shell date +%FT%T%z) +VERSION ?= $(shell git describe --tags --always --dirty --match=v* 2> /dev/null || \ + cat $(CURDIR)/.version 2> /dev/null || echo v0) COMMIT=$(shell git rev-parse HEAD) BRANCH=$(shell git rev-parse --abbrev-ref HEAD) GOVERSION=$(shell go version | awk -F\go '{print $$3}' | awk '{print $$1}') -GITHUB_USERNAME=amimof -BUILD_DIR=${GOPATH}/src/github.com/${GITHUB_USERNAME}/${BINARY} -PKG_LIST=$$(go list ./... | grep -v /vendor/) -# Setup the -ldflags option for go build here, interpolate the variable values -LDFLAGS = -ldflags "-X main.VERSION=${VERSION} -X main.COMMIT=${COMMIT} -X main.BRANCH=${BRANCH} -X main.GOVERSION=${GOVERSION}" +PKGS = $(or $(PKG),$(shell env GO111MODULE=on $(GO) list ./...)) +TESTPKGS = $(shell env GO111MODULE=on $(GO) list -f \ + '{{ if or .TestGoFiles .XTestGoFiles }}{{ .ImportPath }}{{ end }}' \ + $(PKGS)) +BUILDPATH ?= $(BIN)/$(shell basename $(MODULE)) +SRC_FILES=find . -name "*.go" -type f -not -path "./vendor/*" -not -path "./.git/*" -not -path "./.cache/*" -print0 | xargs -0 +BIN = $(CURDIR)/bin +TBIN = $(CURDIR)/test/bin +INTDIR = $(CURDIR)/test/int-test +GO = go +TIMEOUT = 15 +V = 0 +Q = $(if $(filter 1,$V),,@) +M = $(shell printf "\033[34;1m➜\033[0m") + +export GO111MODULE=on +export CGO_ENABLED=0 + +# Build + +.PHONY: all +all: | $(BIN) ; $(info $(M) building executable to $(BUILDPATH)) @ ## Build program binary + $Q $(GO) build \ + -tags release \ + -ldflags '-X main.VERSION=${VERSION} -X main.COMMIT=${COMMIT} -X main.BRANCH=${BRANCH} -X main.GOVERSION=${GOVERSION}' \ + -o $(BUILDPATH) cmd/node-cert-exporter/main.go + +.PHONY: docker_build +docker_build: ; $(info $(M) building docker image) @ ## Build docker image + docker build -t amimof/node-cert-exporter:${VERSION} . + docker tag amimof/node-cert-exporter:${VERSION} amimof/node-cert-exporter:latest -.PHONY: checkfmt +# Tools -# Build the project -all: build - -dep: - curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash; \ - go get -v -d ./cmd/node-cert-exporter/... ; \ - -fmt: - cd ${BUILD_DIR}; \ - gofmt -s -e -d -w .; \ - -vet: - cd ${BUILD_DIR}; \ - go vet ${PKG_LIST}; \ - -gocyclo: - go get -u github.com/fzipp/gocyclo; \ - cd ${BUILD_DIR}; \ - ${GOPATH}/bin/gocyclo -over 15 .; \ - -golint: - go get -u golang.org/x/lint/golint; \ - cd ${BUILD_DIR}; \ - ${GOPATH}/bin/golint ${PKG_LIST}; \ - -ineffassign: - go get github.com/gordonklaus/ineffassign; \ - cd ${BUILD_DIR}; \ - ${GOPATH}/bin/ineffassign .; \ - -misspell: - go get -u github.com/client9/misspell/cmd/misspell; \ - cd ${BUILD_DIR}; \ - find . -type f -not -path "./vendor/*" -not -path "./.git/*" -print0 | xargs -0 ${GOPATH}/bin/misspell; \ - -checkfmt: - cd ${BUILD_DIR} - if [ "`gofmt -l .`" != "" ]; then \ - echo "Code not formatted, please run 'make fmt'"; \ - exit 1; \ - fi +$(BIN): + @mkdir -p $(BIN) +$(TBIN): + @mkdir -p $@ +$(INTDIR): + @mkdir -p $@ +$(TBIN)/%: | $(TBIN) ; $(info $(M) building $(PACKAGE)) + $Q tmp=$$(mktemp -d); \ + env GO111MODULE=off GOPATH=$$tmp GOBIN=$(TBIN) $(GO) get $(PACKAGE) \ + || ret=$$?; \ + rm -rf $$tmp ; exit $$ret + +GOLINT = $(TBIN)/golint +$(BIN)/golint: PACKAGE=golang.org/x/lint/golint + +GOCYCLO = $(TBIN)/gocyclo +$(TBIN)/gocyclo: PACKAGE=github.com/fzipp/gocyclo + +INEFFASSIGN = $(TBIN)/ineffassign +$(TBIN)/ineffassign: PACKAGE=github.com/gordonklaus/ineffassign + +MISSPELL = $(TBIN)/misspell +$(TBIN)/misspell: PACKAGE=github.com/client9/misspell/cmd/misspell + +GOLINT = $(TBIN)/golint +$(TBIN)/golint: PACKAGE=golang.org/x/lint/golint + +GOCOV = $(TBIN)/gocov +$(TBIN)/gocov: PACKAGE=github.com/axw/gocov/... + +# Tests + +.PHONY: lint +lint: | $(GOLINT) ; $(info $(M) running golint) @ ## Runs the golint command + $Q $(GOLINT) -set_exit_status $(PKGS) + +.PHONY: gocyclo +gocyclo: | $(GOCYCLO) ; $(info $(M) running gocyclo) @ ## Calculates cyclomatic complexities of functions in Go source code + $Q $(GOCYCLO) -over 25 . + +.PHONY: ineffassign +ineffassign: | $(INEFFASSIGN) ; $(info $(M) running ineffassign) @ ## Detects ineffectual assignments in Go code + $Q $(INEFFASSIGN) . + +.PHONY: misspell +misspell: | $(MISSPELL) ; $(info $(M) running misspell) @ ## Finds commonly misspelled English words + $Q $(MISSPELL) . + +.PHONY: test +test: ; $(info $(M) running go test) @ ## Runs unit tests + $Q $(GO) test -v ${PKGS} -ci: fmt vet gocyclo golint ineffassign misspell +.PHONY: fmt +fmt: ; $(info $(M) running gofmt) @ ## Formats Go code + $Q $(GO) fmt $(PKGS) -test: dep - cd ${BUILD_DIR}; \ - go test ${PKG_LIST}; \ +.PHONY: vet +vet: ; $(info $(M) running go vet) @ ## Examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string + $Q $(GO) vet $(PKGS) -integration-test: docker_build - mkdir -p ${BUILD_DIR}/out/integration-test/ssl +.PHONY: race +race: ; $(info $(M) running go race) @ ## Runs tests with data race detection + $Q CGO_ENABLED=1 $(GO) test -race -short $(PKGS) + +.PHONY: benchmark +benchmark: ; $(info $(M) running go benchmark test) @ ## Benchmark tests to examine performance + $Q $(GO) test -run=__absolutelynothing__ -bench=. $(PKGS) + +.PHONY: coverage +coverage: ; $(info $(M) running go coverage) @ ## Runs tests and generates code coverage report at ./test/coverage.out + $Q mkdir -p $(CURDIR)/test/ + $Q $(GO) test -coverprofile="$(CURDIR)/test/coverage.out" $(PKGS) + +.PHONY: checkfmt +checkfmt: ; $(info $(M) running checkfmt) @ ## Checks if code is formatted with go fmt and errors out if not + @test "$(shell $(SRC_FILES) gofmt -l)" = "" \ + || { echo "Code not formatted, please run 'make fmt'"; exit 2; } + +.PHONY: checkfmt +integration-test: | $(INTDIR) docker_build ; $(info $(M) running integration tests) @ ## Run integration tests + mkdir -p ${INTDIR}/ssl openssl req -new -newkey rsa:1024 -days 365 -nodes -x509 \ -subj '/CN=localhost/C=SE/L=Gothenburg/O=system:nodes/OU=amimof/ST=Vastra Gotalands Lan' \ - -keyout ${BUILD_DIR}/out/integration-test/ssl/self-signed-key.pem \ - -out ${BUILD_DIR}/out/integration-test/ssl/self-signed.pem - docker run -d --name node-cert-exporter --hostname 0a9ad966a64e -v ${BUILD_DIR}/out/integration-test/ssl:/certs -p 9117:9117 -e NODE_NAME=docker-node amimof/node-cert-exporter:${VERSION} --logtostderr=true --v=4 --path=/certs + -keyout ${INTDIR}/ssl/self-signed-key.pem \ + -out ${INTDIR}/ssl/self-signed.pem + openssl x509 -in ${INTDIR}/ssl/self-signed.pem -outform der -out ${INTDIR}/ssl/self-signed-bin.cer + docker run -d --name node-cert-exporter --hostname 0a9ad966a64e -v ${INTDIR}/ssl:/certs -p 9117:9117 -e NODE_NAME=docker-node amimof/node-cert-exporter:${VERSION} --logtostderr=true --v=4 --path=/certs sleep 3 curl -s http://127.0.0.1:9117/metrics | grep ssl_certificate_expiry_seconds curl -s http://127.0.0.1:9117/metrics | grep 'issuer="CN=localhost,OU=amimof,O=system:nodes,L=Gothenburg,ST=Vastra Gotalands Lan,C=SE"' @@ -82,7 +137,7 @@ integration-test: docker_build curl -s http://127.0.0.1:9117/metrics | grep 'nodename="docker-node"' docker kill node-cert-exporter docker rm node-cert-exporter - docker run -d --name node-cert-exporter -v ${BUILD_DIR}/out/integration-test/ssl:/certs -p 9117:9117 amimof/node-cert-exporter:${VERSION} --logtostderr=true --v=4 --path=/certs --exclude-path=/certs + docker run -d --name node-cert-exporter -v ${INTDIR}/ssl:/certs -p 9117:9117 amimof/node-cert-exporter:${VERSION} --logtostderr=true --v=4 --path=/certs --exclude-path=/certs sleep 3 if [ "`curl -s http://127.0.0.1:9117/metrics | grep ssl_certificate_expiry_seconds`" != "" ]; then \ exit 1; \ @@ -90,38 +145,28 @@ integration-test: docker_build docker kill node-cert-exporter docker rm node-cert-exporter -linux: dep - CGO_ENABLED=0 GOOS=linux GOARCH=${GOARCH} go build ${LDFLAGS} -o ${BUILD_DIR}/out/${BINARY}-linux-${GOARCH} cmd/node-cert-exporter/main.go - -rpi: dep - CGO_ENABLED=0 GOOS=linux GOARCH=arm go build ${LDFLAGS} -o ${BUILD_DIR}/out/${BINARY}-linux-arm cmd/node-cert-exporter/main.go - -darwin: dep - CGO_ENABLED=0 GOOS=darwin GOARCH=${GOARCH} go build ${LDFLAGS} -o ${BUILD_DIR}/out/${BINARY}-darwin-${GOARCH} cmd/node-cert-exporter/main.go - -windows: dep - CGO_ENABLED=0 GOOS=windows GOARCH=${GOARCH} go build ${LDFLAGS} -o ${BUILD_DIR}/out/${BINARY}-windows-${GOARCH}.exe cmd/node-cert-exporter/main.go +# Helm -build: linux darwin rpi windows - -docker_build: - docker build -t amimof/node-cert-exporter:${VERSION} . - docker tag amimof/node-cert-exporter:${VERSION} amimof/node-cert-exporter:latest - -docker_push: - docker push amimof/node-cert-exporter:${VERSION} - docker push amimof/node-cert-exporter:latest - -helm_package: - helm package charts/node-cert-exporter -d charts/node-cert-exporter --version ${VERSION} --app-version ${VERSION} - -helm_index: - helm repo index charts/ - -helm_lint: +.PHONY: helm_lint +helm_lint: ; $(info $(M) running helm lint) @ ## Verifies that the chart is well-formed helm lint charts/node-cert-exporter/ -docker: docker_build docker_push - -clean: - rm -rf ${BUILD_DIR}/out/ \ No newline at end of file +# Misc + +.PHONY: help +help: + @grep -hE '^[ a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \ + awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m∙ %s:\033[0m %s\n", $$1, $$2}' + +.PHONY: version +version: ## Print version information + @echo App: $(VERSION) + @echo Go: $(GOVERSION) + @echo Commit: $(COMMIT) + @echo Branch: $(BRANCH) + +.PHONY: clean +clean: ; $(info $(M) cleaning) @ ## Cleanup everything + @rm -rfv $(BIN) + @rm -rfv $(TBIN) + @rm -rfv $(CURDIR)/test \ No newline at end of file diff --git a/charts/index.yaml b/charts/index.yaml new file mode 100644 index 0000000..e69de29 diff --git a/charts/node-cert-exporter/Chart.yaml b/charts/node-cert-exporter/Chart.yaml index ed0ef02..3a5b376 100644 --- a/charts/node-cert-exporter/Chart.yaml +++ b/charts/node-cert-exporter/Chart.yaml @@ -15,11 +15,11 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.0.0-beta.4 +version: 1.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. -appVersion: 1.0.0-beta.4 +appVersion: 1.0.1 sources: - https://github.com/amimof/node-cert-exporter \ No newline at end of file