|
| 1 | +# ==================================================================================== |
| 2 | +# Variables |
| 3 | + |
| 4 | +## General Variables |
| 5 | +# Branch Variables |
| 6 | +PROTECTED_BRANCH := master |
| 7 | +CURRENT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD) |
| 8 | +# Use repository name as application name |
| 9 | +APP_NAME := $(shell basename -s .git `git config --get remote.origin.url`) |
| 10 | +# Get current commit |
| 11 | +APP_COMMIT := $(shell git log --pretty=format:'%h' -n 1) |
| 12 | +# Check if we are in protected branch, if yes use `protected_branch_name-sha` as app version. |
| 13 | +# Else check if we are in a release tag, if yes use the tag as app version, else use `dev-sha` as app version. |
| 14 | +APP_VERSION ?= $(shell if [ $(PROTECTED_BRANCH) = $(CURRENT_BRANCH) ]; then echo $(PROTECTED_BRANCH); else (git describe --abbrev=0 --exact-match --tags 2>/dev/null || echo dev-$(APP_COMMIT)) ; fi) |
| 15 | + |
| 16 | +# Get current date and format like: 2022-04-27 11:32 |
| 17 | +BUILD_DATE := $(shell date +%Y-%m-%d\ %H:%M) |
| 18 | + |
| 19 | +## General Configuration Variables |
| 20 | +# We don't need make's built-in rules. |
| 21 | +MAKEFLAGS += --no-builtin-rules |
| 22 | +# Be pedantic about undefined variables. |
| 23 | +MAKEFLAGS += --warn-undefined-variables |
| 24 | +# Set help as default target |
| 25 | +.DEFAULT_GOAL := help |
| 26 | + |
| 27 | +# App Code location |
| 28 | +CONFIG_APP_CODE += ./cmd/offloader |
| 29 | + |
| 30 | +## Docker Variables |
| 31 | +# Docker executable |
| 32 | +DOCKER := $(shell which docker) |
| 33 | +# Docker options to inherit for all docker run commands |
| 34 | +DOCKER_OPTS += --rm -u $$(id -u):$$(id -g) --platform "linux/amd64" |
| 35 | +# Registry to upload images |
| 36 | +DOCKER_REGISTRY ?= docker.io |
| 37 | +DOCKER_REGISTRY_REPO ?= mattermost/${APP_NAME}-daily |
| 38 | +# Registry credentials |
| 39 | +DOCKER_USER ?= user |
| 40 | +DOCKER_PASSWORD ?= password |
| 41 | +## Docker Images |
| 42 | +DOCKER_IMAGE_GO += "golang:${GO_VERSION}@sha256:fa71e1447cb0241324162a6c51297206928d755b16142eceec7b809af55061e5" |
| 43 | +DOCKER_IMAGE_GOLINT += "golangci/golangci-lint:v1.50.1@sha256:94388e00f07c64262b138a7508f857473e30fdf0f59d04b546a305fc12cb5961" |
| 44 | +DOCKER_IMAGE_DOCKERLINT += "hadolint/hadolint:v2.9.2@sha256:d355bd7df747a0f124f3b5e7b21e9dafd0cb19732a276f901f0fdee243ec1f3b" |
| 45 | +DOCKER_IMAGE_COSIGN += "bitnami/cosign:1.8.0@sha256:8c2c61c546258fffff18b47bb82a65af6142007306b737129a7bd5429d53629a" |
| 46 | +DOCKER_IMAGE_GH_CLI += "registry.internal.mattermost.com/images/build-ci:3.16.0@sha256:f6a229a9ababef3c483f237805ee4c3dbfb63f5de4fbbf58f4c4b6ed8fcd34b6" |
| 47 | + |
| 48 | +## Cosign Variables |
| 49 | +# The public key |
| 50 | +COSIGN_PUBLIC_KEY ?= akey |
| 51 | +# The private key |
| 52 | +COSIGN_KEY ?= akey |
| 53 | +# The passphrase used to decrypt the private key |
| 54 | +COSIGN_PASSWORD ?= password |
| 55 | + |
| 56 | +## Go Variables |
| 57 | +# Go executable |
| 58 | +GO := $(shell which go) |
| 59 | +# Extract GO version from go.mod file |
| 60 | +GO_VERSION ?= $(shell grep -E '^go' go.mod | awk {'print $$2'}) |
| 61 | +# LDFLAGS |
| 62 | +GO_LDFLAGS += -X "github.com/mattermost/${APP_NAME}/service.buildHash=$(APP_COMMIT)" |
| 63 | +GO_LDFLAGS += -X "github.com/mattermost/${APP_NAME}/service.buildVersion=$(APP_VERSION)" |
| 64 | +GO_LDFLAGS += -X "github.com/mattermost/${APP_NAME}/service.buildDate=$(BUILD_DATE)" |
| 65 | +GO_LDFLAGS += -X "github.com/mattermost/${APP_NAME}/service.goVersion=$(GO_VERSION)" |
| 66 | +# Architectures to build for |
| 67 | +GO_BUILD_PLATFORMS ?= linux-amd64 linux-arm64 darwin-amd64 darwin-arm64 freebsd-amd64 |
| 68 | +GO_BUILD_PLATFORMS_ARTIFACTS = $(foreach cmd,$(addprefix go-build/,${APP_NAME}),$(addprefix $(cmd)-,$(GO_BUILD_PLATFORMS))) |
| 69 | +# Build options |
| 70 | +GO_BUILD_OPTS += -mod=readonly -trimpath |
| 71 | +GO_TEST_OPTS += -mod=readonly -failfast -race |
| 72 | +# Temporary folder to output compiled binaries artifacts |
| 73 | +GO_OUT_BIN_DIR := ./dist |
| 74 | + |
| 75 | +## Github Variables |
| 76 | +# A github access token that provides access to upload artifacts under releases |
| 77 | +GITHUB_TOKEN ?= a_token |
| 78 | +# Github organization |
| 79 | +GITHUB_ORG := mattermost |
| 80 | +# Most probably the name of the repo |
| 81 | +GITHUB_REPO := ${APP_NAME} |
| 82 | + |
| 83 | +# ==================================================================================== |
| 84 | +# Colors |
| 85 | + |
| 86 | +BLUE := $(shell printf "\033[34m") |
| 87 | +YELLOW := $(shell printf "\033[33m") |
| 88 | +RED := $(shell printf "\033[31m") |
| 89 | +GREEN := $(shell printf "\033[32m") |
| 90 | +CYAN := $(shell printf "\033[36m") |
| 91 | +CNone := $(shell printf "\033[0m") |
| 92 | + |
| 93 | +# ==================================================================================== |
| 94 | +# Logger |
| 95 | + |
| 96 | +TIME_LONG = `date +%Y-%m-%d' '%H:%M:%S` |
| 97 | +TIME_SHORT = `date +%H:%M:%S` |
| 98 | +TIME = $(TIME_SHORT) |
| 99 | + |
| 100 | +INFO = echo ${TIME} ${BLUE}[ .. ]${CNone} |
| 101 | +WARN = echo ${TIME} ${YELLOW}[WARN]${CNone} |
| 102 | +ERR = echo ${TIME} ${RED}[FAIL]${CNone} |
| 103 | +OK = echo ${TIME} ${GREEN}[ OK ]${CNone} |
| 104 | +FAIL = (echo ${TIME} ${RED}[FAIL]${CNone} && false) |
| 105 | + |
| 106 | +# ==================================================================================== |
| 107 | +# Verbosity control hack |
| 108 | + |
| 109 | +VERBOSE ?= 0 |
| 110 | +AT_0 := @ |
| 111 | +AT_1 := |
| 112 | +AT = $(AT_$(VERBOSE)) |
| 113 | + |
| 114 | +# ==================================================================================== |
| 115 | +# Targets |
| 116 | + |
| 117 | +help: ## to get help |
| 118 | + @echo "Usage:" |
| 119 | + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) |\ |
| 120 | + awk 'BEGIN {FS = ":.*?## "}; {printf "make ${CYAN}%-30s${CNone} %s\n", $$1, $$2}' |
| 121 | + |
| 122 | +.PHONY: build |
| 123 | +build: go-build-docker ## to build |
| 124 | + |
| 125 | +.PHONY: release |
| 126 | +release: build github-release ## to build and release artifacts |
| 127 | + |
| 128 | +.PHONY: lint |
| 129 | +lint: go-lint docker-lint ## to lint |
| 130 | + |
| 131 | +.PHONY: test |
| 132 | +test: go-test ## to test |
| 133 | + |
| 134 | +go-build: $(GO_BUILD_PLATFORMS_ARTIFACTS) ## to build binaries |
| 135 | + |
| 136 | +.PHONY: go-build |
| 137 | +go-build/%: |
| 138 | + @$(INFO) go build $*... |
| 139 | + $(AT)target="$*"; \ |
| 140 | + command="${APP_NAME}"; \ |
| 141 | + platform_ext="$${target#$$command-*}"; \ |
| 142 | + platform="$${platform_ext%.*}"; \ |
| 143 | + export GOOS="$${platform%%-*}"; \ |
| 144 | + export GOARCH="$${platform#*-}"; \ |
| 145 | + echo export GOOS=$${GOOS}; \ |
| 146 | + echo export GOARCH=$${GOARCH}; \ |
| 147 | + CGO_ENABLED=0 \ |
| 148 | + $(GO) build ${GO_BUILD_OPTS} \ |
| 149 | + -ldflags '${GO_LDFLAGS}' \ |
| 150 | + -o ${GO_OUT_BIN_DIR}/$* \ |
| 151 | + ${CONFIG_APP_CODE} || ${FAIL} |
| 152 | + @$(OK) go build $* |
| 153 | + |
| 154 | +.PHONY: go-build-docker |
| 155 | +go-build-docker: # to build binaries under a controlled docker dedicated go container using DOCKER_IMAGE_GO |
| 156 | + @$(INFO) go build docker |
| 157 | + $(AT)$(DOCKER) run ${DOCKER_OPTS} \ |
| 158 | + -v $(PWD):/app -w /app \ |
| 159 | + -e GOCACHE="/tmp" \ |
| 160 | + $(DOCKER_IMAGE_GO) \ |
| 161 | + /bin/sh -c \ |
| 162 | + "cd /app && \ |
| 163 | + make go-build" || ${FAIL} |
| 164 | + @$(OK) go build docker |
| 165 | + |
| 166 | +.PHONY: go-run |
| 167 | +go-run: ## to run locally for development |
| 168 | + @$(INFO) running locally... |
| 169 | + $(AT)$(GO) run ${GO_BUILD_OPTS} ${CONFIG_APP_CODE} || ${FAIL} |
| 170 | + @$(OK) running locally |
| 171 | + |
| 172 | +.PHONY: go-test |
| 173 | +go-test: ## to run tests |
| 174 | + @$(INFO) testing... |
| 175 | + $(AT)$(DOCKER) run ${DOCKER_OPTS} \ |
| 176 | + -v $(PWD):/app -w /app \ |
| 177 | + -e GOCACHE="/tmp" \ |
| 178 | + $(DOCKER_IMAGE_GO) \ |
| 179 | + /bin/sh -c \ |
| 180 | + "cd /app && \ |
| 181 | + go test ${GO_TEST_OPTS} ./... " || ${FAIL} |
| 182 | + @$(OK) testing |
| 183 | + |
| 184 | +.PHONY: go-mod-check |
| 185 | +go-mod-check: ## to check go mod files consistency |
| 186 | + @$(INFO) Checking go mod files consistency... |
| 187 | + $(AT)$(GO) mod tidy |
| 188 | + $(AT)git --no-pager diff --exit-code go.mod go.sum || \ |
| 189 | + (${WARN} Please run "go mod tidy" and commit the changes in go.mod and go.sum. && ${FAIL} ; exit 128 ) |
| 190 | + @$(OK) Checking go mod files consistency |
| 191 | + |
| 192 | +.PHONY: go-update-dependencies |
| 193 | +go-update-dependencies: ## to update go dependencies (vendor) |
| 194 | + @$(INFO) updating go dependencies... |
| 195 | + $(AT)$(GO) get -u ./... && \ |
| 196 | + $(AT)$(GO) mod vendor && \ |
| 197 | + $(AT)$(GO) mod tidy || ${FAIL} |
| 198 | + @$(OK) updating go dependencies |
| 199 | + |
| 200 | +.PHONY: go-lint |
| 201 | +go-lint: ## to lint go code |
| 202 | + @$(INFO) App linting... |
| 203 | + $(AT)GOCACHE="/tmp" $(DOCKER) run ${DOCKER_OPTS} \ |
| 204 | + -v $(PWD):/app -w /app \ |
| 205 | + -e GOCACHE="/tmp" \ |
| 206 | + -e GOLANGCI_LINT_CACHE="/tmp" \ |
| 207 | + ${DOCKER_IMAGE_GOLINT} \ |
| 208 | + golangci-lint run ./... || ${FAIL} |
| 209 | + @$(OK) App linting |
| 210 | + |
| 211 | +.PHONY: go-fmt |
| 212 | +go-fmt: ## to perform formatting |
| 213 | + @$(INFO) App code formatting... |
| 214 | + $(AT)$(GO) fmt ./... || ${FAIL} |
| 215 | + @$(OK) App code formatting... |
| 216 | + |
| 217 | +.PHONY: github-release |
| 218 | +github-release: ## to publish a release and relevant artifacts to GitHub |
| 219 | + @$(INFO) Generating github-release http://github.com/$(GITHUB_ORG)/$(GITHUB_REPO)/releases/tag/$(APP_VERSION) ... |
| 220 | +ifeq ($(shell echo $(APP_VERSION) | egrep '^v([0-9]+\.){0,2}(\*|[0-9]+)'),) |
| 221 | + $(error "We only support releases from semver tags") |
| 222 | +else |
| 223 | + $(AT)$(DOCKER) run \ |
| 224 | + -v $(PWD):/app -w /app \ |
| 225 | + -e GITHUB_TOKEN=${GITHUB_TOKEN} \ |
| 226 | + $(DOCKER_IMAGE_GH_CLI) \ |
| 227 | + /bin/sh -c \ |
| 228 | + "cd /app && \ |
| 229 | + gh release create $(APP_VERSION) --generate-notes $(GO_OUT_BIN_DIR)/*" || ${FAIL} |
| 230 | +endif |
| 231 | + @$(OK) Generating github-release http://github.com/$(GITHUB_ORG)/$(GITHUB_REPO)/releases/tag/$(APP_VERSION) ... |
| 232 | + |
| 233 | +.PHONY: clean |
| 234 | +clean: ## to clean-up |
| 235 | + @$(INFO) cleaning /${GO_OUT_BIN_DIR} folder... |
| 236 | + $(AT)rm -rf ${GO_OUT_BIN_DIR} || ${FAIL} |
| 237 | + @$(OK) cleaning /${GO_OUT_BIN_DIR} folder |
0 commit comments