PKG?=github.com/smallstep/certificates/cmd/step-ca BINNAME?=step-ca # Set V to 1 for verbose output from the Makefile Q=$(if $V,,@) PREFIX?= SRC=$(shell find . -type f -name '*.go' -not -path "./vendor/*") GOOS_OVERRIDE ?= OUTPUT_ROOT=output/ # Set shell to bash for `echo -e` SHELL := /bin/bash all: build test lint .PHONY: all ######################################### # Bootstrapping ######################################### bootstra%: $Q which dep || go get github.com/golang/dep/cmd/dep $Q dep ensure vendor: Gopkg.lock $Q dep ensure BOOTSTRAP=\ github.com/golang/lint/golint \ github.com/client9/misspell/cmd/misspell \ github.com/gordonklaus/ineffassign \ github.com/tsenart/deadcode \ github.com/alecthomas/gometalinter define VENDOR_BIN_TMPL vendor/bin/$(notdir $(1)): vendor $Q go build -o $$@ ./vendor/$(1) VENDOR_BINS += vendor/bin/$(notdir $(1)) endef $(foreach pkg,$(BOOTSTRAP),$(eval $(call VENDOR_BIN_TMPL,$(pkg)))) .PHONY: bootstra% vendor ################################################# # Determine the type of `push` and `version` ################################################# # Version flags to embed in the binaries VERSION ?= $(shell [ -d .git ] && git describe --tags --always --dirty="-dev") # If we are not in an active git dir then try reading the version from .VERSION. # .VERSION contains a slug populated by `git archive`. VERSION := $(or $(VERSION),$(shell ./.version.sh .VERSION)) VERSION := $(shell echo $(VERSION) | sed 's/^v//') # If TRAVIS_TAG is set then we know this ref has been tagged. ifdef TRAVIS_TAG PUSHTYPE=release else PUSHTYPE=master endif ######################################### # Build ######################################### DATE := $(shell date -u '+%Y-%m-%d %H:%M UTC') LDFLAGS := -ldflags='-w -X "main.Version=$(VERSION)" -X "main.BuildTime=$(DATE)"' GOFLAGS := CGO_ENABLED=0 build: $(PREFIX)bin/$(BINNAME) @echo "Build Complete!" $(PREFIX)bin/$(BINNAME): vendor $(call rwildcard,*.go) $Q mkdir -p $(@D) $Q $(GOOS_OVERRIDE) $(GOFLAGS) go build -v -o $(PREFIX)bin/$(BINNAME) $(LDFLAGS) $(PKG) # Target for building without calling dep ensure simple: $Q mkdir -p bin/ $Q $(GOOS_OVERRIDE) $(GOFLAGS) go build -v -o bin/$(BINNAME) $(LDFLAGS) $(PKG) @echo "Build Complete!" .PHONY: build simple ######################################### # Go generate ######################################### generate: $Q go generate ./... .PHONY: generate ######################################### # Test ######################################### test: $Q $(GOFLAGS) go test -short -coverprofile=coverage.out ./... vtest: $(Q)for d in $$(go list ./... | grep -v vendor); do \ echo -e "TESTS FOR: for \033[0;35m$$d\033[0m"; \ $(GOFLAGS) go test -v -bench=. -run=. -short -coverprofile=vcoverage.out $$d; \ out=$$?; \ if [[ $$out -ne 0 ]]; then ret=$$out; fi;\ rm -f profile.coverage.out; \ done; exit $$ret; .PHONY: test vtest integrate: integration integration: bin/$(BINNAME) $Q $(GOFLAGS) go test -tags=integration ./integration/... .PHONY: integrate integration ######################################### # Linting ######################################### LINTERS=\ gofmt \ golint \ vet \ misspell \ ineffassign \ deadcode $(patsubst %,%-bin,$(filter-out gofmt vet,$(LINTERS))): %-bin: vendor/bin/% gofmt-bin vet-bin: $(LINTERS): %: vendor/bin/gometalinter %-bin vendor $Q PATH=`pwd`/vendor/bin:$$PATH gometalinter --tests --disable-all --vendor \ --deadline=5m -s data -s pkg --enable $@ ./... fmt: $Q gofmt -l -w $(SRC) lint: $(LINTERS) .PHONY: $(LINTERS) lint fmt ######################################### # Install ######################################### INSTALL_PREFIX?=/usr/ install: $(PREFIX)bin/$(BINNAME) $Q install -D $(PREFIX)bin/$(BINNAME) $(DESTDIR)$(INSTALL_PREFIX)bin/$(BINNAME) uninstall: $Q rm -f $(DESTDIR)$(INSTALL_PREFIX)/bin/$(BINNAME) .PHONY: install uninstall ######################################### # Clean ######################################### clean: @echo "You will need to run 'make bootstrap' or 'dep ensure' directly to re-download any dependencies." $Q rm -rf vendor ifneq ($(BINNAME),"") $Q rm -f bin/$(BINNAME) endif .PHONY: clean ######################################### # Building Docker Image # # Builds a dockerfile for step by building a linux version of the step-cli and # then copying the specific binary when building the container. # # This ensures the container is as small as possible without having to deal # with getting access to private repositories inside the container during build # time. ######################################### # XXX We put the output for the build in 'output' so we don't mess with how we # do rule overriding from the base Makefile (if you name it 'build' it messes up # the wildcarding). DOCKER_OUTPUT=$(OUTPUT_ROOT)docker/ DOCKER_MAKE=V=$V GOOS_OVERRIDE='GOOS=linux GOARCH=amd64' PREFIX=$(1) make $(1)bin/$(2) DOCKER_BUILD=$Q docker build -t smallstep/$(1):latest -f docker/$(2) --build-arg BINPATH=$(DOCKER_OUTPUT)bin/$(1) . docker: docker-make docker/Dockerfile.step-ca $(call DOCKER_BUILD,step-ca,Dockerfile.step-ca) docker-make: mkdir -p $(DOCKER_OUTPUT) $(call DOCKER_MAKE,$(DOCKER_OUTPUT),step-ca) .PHONY: docker docker-make ################################################# # Releasing Docker Images # # Using the docker build infrastructure, this section is responsible for # logging into docker hub and pushing the built docker containers up with the # appropriate tags. ################################################# DOCKER_TAG=docker tag smallstep/$(1):latest smallstep/$(1):$(2) DOCKER_PUSH=docker push smallstep/$(1):$(2) docker-tag: $(call DOCKER_TAG,step-ca,$(VERSION)) docker-push-tag: docker-tag $(call DOCKER_PUSH,step-ca,$(VERSION)) # Rely on DOCKER_USERNAME and DOCKER_PASSWORD being set inside the CI or # equivalent environment docker-login: $Q docker login -u="$(DOCKER_USERNAME)" -p="$(DOCKER_PASSWORD)" .PHONY: docker-login docker-tag docker-push-tag ################################################# # Targets for pushing the docker images ################################################# # For all builds on the master branch, we actually build the container docker-master: docker # For all builds on the master branch with an rc tag docker-release: docker-master docker-login docker-push-tag .PHONY: docker-master docker-release ######################################### # Debian ######################################### changelog: $Q echo "step-certificates ($(VERSION)) unstable; urgency=medium" > debian/changelog $Q echo >> debian/changelog $Q echo " * See https://github.com/smallstep/certificates/releases" >> debian/changelog $Q echo >> debian/changelog $Q echo " -- Smallstep Labs, Inc. $(shell date -uR)" >> debian/changelog debian: changelog $Q mkdir -p $(RELEASE); \ OUTPUT=../step-certificates_*.deb; \ rm $$OUTPUT; \ dpkg-buildpackage -b -rfakeroot -us -uc && cp $$OUTPUT $(RELEASE)/ distclean: clean .PHONY: changelog debian distclean ################################################# # Build statically compiled step binary for various operating systems ################################################# BINARY_OUTPUT=$(OUTPUT_ROOT)binary/ BUNDLE_MAKE=v=$v GOOS_OVERRIDE='GOOS=$(1) GOARCH=$(2)' PREFIX=$(3) make $(3)bin/$(BINNAME) RELEASE=./.travis-releases binary-linux: $(call BUNDLE_MAKE,linux,amd64,$(BINARY_OUTPUT)linux/) binary-darwin: $(call BUNDLE_MAKE,darwin,amd64,$(BINARY_OUTPUT)darwin/) define BUNDLE $(q)BUNDLE_DIR=$(BINARY_OUTPUT)$(1)/bundle; \ stepName=step-certificates_$(2); \ mkdir -p $$BUNDLE_DIR $(RELEASE); \ TMP=$$(mktemp -d $$BUNDLE_DIR/tmp.XXXX); \ trap "rm -rf $$TMP" EXIT INT QUIT TERM; \ newdir=$$TMP/$$stepName; \ mkdir -p $$newdir/bin; \ cp $(BINARY_OUTPUT)$(1)/bin/$(BINNAME) $$newdir/bin/; \ cp README.md $$newdir/; \ NEW_BUNDLE=$(RELEASE)/step-certificates_$(2)_$(1)_$(3).tar.gz; \ rm -f $$NEW_BUNDLE; \ tar -zcvf $$NEW_BUNDLE -C $$TMP $$stepName; endef bundle-linux: binary-linux $(call BUNDLE,linux,$(VERSION),amd64) bundle-darwin: binary-darwin $(call BUNDLE,darwin,$(VERSION),amd64) .PHONY: binary-linux binary-darwin bundle-linux bundle-darwin ################################################# # Targets for creating OS specific artifacts and archives ################################################# artifacts-linux-tag: bundle-linux debian artifacts-darwin-tag: bundle-darwin artifacts-archive-tag: $Q mkdir -p $(RELEASE) $Q git archive v$(VERSION) | gzip > $(RELEASE)/step-certificates.tar.gz artifacts-tag: artifacts-linux-tag artifacts-darwin-tag .PHONY: artifacts-linux-tag artifacts-darwin-tag artifacts-archive-tag artifacts-tag ################################################# # Targets for creating step artifacts ################################################# # For all builds that are not tagged artifacts-master: # For all builds with a release-candidate (-rc) tag artifacts-release-candidate: artifacts-tag # For all builds with a release tag artifacts-release: artifacts-tag # This command is called by travis directly *after* a successful build artifacts: artifacts-$(PUSHTYPE) docker-$(PUSHTYPE) .PHONY: artifacts-master artifacts-release artifacts