2023-11-25 21:57:49 +00:00
GO_PACKAGE ?= git.kle.li/tools/go-import-redirector
BINARY_BASE_NAME ?= $( shell echo ${ GO_PACKAGE } | rev | cut -d'/' -f1 | rev)
DIST := dist
DIST_BIN_DIR := $( DIST) /binaries
DIST_RELEASE_DIR := $( DIST) /release
DIST_DOCKER_DIR := $( DIST) /docker
DIST_DIRS := $( DIST_BIN_DIR) $( DIST_RELEASE_DIR) $( DIST_DOCKER_DIR)
# Tool packages
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@latest
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@latest
GXZ_PAGAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11
# Allow overriding the go binary
GO ?= go
SHASUM ?= shasum -a 256
# Construct the version strings
2023-12-26 21:21:27 +00:00
# VERSION default to dev or in CI next for default branch, and branch name for everything else...
2023-11-25 21:57:49 +00:00
i f n e q ( $( CI ) , )
# in CI
2023-12-26 21:21:27 +00:00
ifeq ( $( CI_REPO_DEFAULT_BRANCH) ,$( CI_COMMIT_BRANCH) )
VERSION ?= next
else
VERSION ?= $( CI_COMMIT_BRANCH)
endif
2023-11-25 21:57:49 +00:00
e l s e
# not in CI
VERSION ?= dev
e n d i f
# VERSION_NUMBER semver compliant without the v prefix
VERSION_NUMBER ?= 0.0.0
# Use CI_COMMIT_TAG from CI if set as version and version number
i f n e q ( $( CI_COMMIT_TAG ) , )
2023-12-26 21:21:27 +00:00
ISTAG := "true"
2023-11-25 21:57:49 +00:00
VERSION := $( CI_COMMIT_TAG:v%= %)
VERSION_NUMBER := ${ VERSION }
2023-12-26 21:21:27 +00:00
e l s e
ISTAG := "false"
2023-11-25 21:57:49 +00:00
e n d i f
# Use CI provided SHA, else use git
i f n e q ( $( CI_COMMIT_SHA ) , )
SOURCE_SHA := $( CI_COMMIT_SHA)
e n d i f
SOURCE_SHA ?= $( shell git rev-parse HEAD)
SOURCE_SHA_SHORT := $( shell echo ${ SOURCE_SHA } | head -c 8)
2023-12-26 21:21:27 +00:00
COMMITTIME = $( shell git log -1 --format= %ct | xargs -I{ } date -u +%Y%m%d%H%M%S -d "@{}" )
2023-11-25 21:57:49 +00:00
# VERSIONED_BINARY is the base output name for xgo
VERSIONED_BINARY := $( BINARY_BASE_NAME) -$( VERSION)
# https://docs.gitlab.com/ee/ci/variables/predefined_variables.html
# https://woodpecker-ci.org/docs/next/usage/environment
# gl GITLAB_CI CI CI_COMMIT_TAG CI_DEFAULT_BRANCH CI_COMMIT_SHA CI_COMMIT_SHORT_SHA CI_MERGE_REQUEST_IID CI_PIPELINE_SOURCE
# WP CI=woodpecker CI_COMMIT_TAG CI_REPO_DEFAULT_BRANCH CI_COMMIT_SHA CI_COMMIT_PULL_REQUEST
# Default LDFlags, stripping, dwarfing, statically linking and adding the version and commit to pkg/meta, extendable via LDFLAGS
2023-12-26 21:21:27 +00:00
LDFLAGS := $( LDFLAGS) -s -w
LDFLAGS := $( LDFLAGS) -X ${ GO_PACKAGE } /pkg/meta.version= ${ VERSION }
LDFLAGS := $( LDFLAGS) -X ${ GO_PACKAGE } /pkg/meta.commit= ${ SOURCE_SHA }
LDFLAGS := $( LDFLAGS) -X ${ GO_PACKAGE } /pkg/meta.commitTime= ${ COMMITTIME }
LDFLAGS := $( LDFLAGS) -X ${ GO_PACKAGE } /pkg/meta.isTag= ${ ISTAG }
LDFLAGS := $( LDFLAGS) -X ${ GO_PACKAGE } /pkg/meta.branch= ${ CI_COMMIT_BRANCH }
LDFLAGS := $( LDFLAGS) -X ${ GO_PACKAGE } /pkg/meta.defaultBranch= ${ CI_REPO_DEFAULT_BRANCH }
2023-11-25 21:57:49 +00:00
# Disable cgo, but overridable
CGO_ENABLED ?= 0
HAS_GO = $( shell hash go > /dev/null 2>& 1 && echo "GO" || echo "NOGO" )
i f e q ( $( HAS_GO ) , G O )
GOPATH ?= $( shell $( GO) env GOPATH)
export PATH := $( GOPATH) /bin:$( PATH)
CGO_CFLAGS ?= $( shell $( GO) env CGO_CFLAGS) $( CGO_EXTRA_CFLAGS)
e n d i f
GOFLAGS := -v -trimpath
EXECUTABLE ?= $( BINARY_BASE_NAME)
# Release packagin stuffs...
STORED_VERSION_FILE := VERSION
TAR_EXCLUDES := .git $( EXECUTABLE) $( DIST)
# just print the help instead of running any builds...
all : help
##@ Prerequisites
.PHONY : go -check
go-check : ## Check Go version >= go.mod version
$( eval MIN_GO_VERSION_STR := $( shell grep -Eo '^go\s+[0-9]+\.[0-9]+' go.mod | cut -d' ' -f2) )
$( eval MIN_GO_VERSION := $( shell printf "%03d%03d" $( shell echo '$(MIN_GO_VERSION_STR)' | tr '.' ' ' ) ) )
$( eval GO_VERSION := $( shell printf "%03d%03d" $( shell $( GO) version | grep -Eo '[0-9]+\.[0-9]+' | tr '.' ' ' ) ; ) )
@if [ " $( GO_VERSION) " -lt " $( MIN_GO_VERSION) " ] ; then \
echo " This project requires Go $( MIN_GO_VERSION_STR) or greater to build. You can get it at https://go.dev/dl/ " ; \
exit 1; \
fi
##@ Convention Checking
.PHONY : checks ## Run all checks
checks : tidy -check security -check
.PHONY : tidy -check
tidy-check : tidy ## Check that mods have been cleaned up before checking in
@diff= $$ ( git diff --color= always go.mod go.sum) ; \
if [ -n " $$ diff " ] ; then \
echo "Please run 'make tidy' and commit the result:" ; \
echo " $$ {diff} " ; \
exit 1; \
fi
.PHONY : security -check
security-check :
go run $( GOVULNCHECK_PACKAGE) ./...
##@ Linting
.PHONY : lint
lint : ## Lint code
@echo "Running golangci-lint"
go run $( GOLANGCI_LINT_PACKAGE) run --timeout 10m
##@ Others
# Help prints all targets (identified by ##) and categories (identified by ##@)
.PHONY : help
help : ## Display this help.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $( MAKEFILE_LIST)
.PHONY : clean
clean : ## Cleanup
$( GO) clean -i ./...
rm -rf $( EXECUTABLE) $( DIST) vendor
.PHONY : tidy
tidy : ## Tidy mods
$( eval MIN_GO_VERSION := $( shell grep -Eo '^go\s+[0-9]+\.[0-9.]+' go.mod | cut -d' ' -f2) )
$( GO) mod tidy -compat= $( MIN_GO_VERSION)
vendor : go .mod go .sum ## Download mods to vendor
$( GO) mod vendor
@touch vendor
.PHONY : build
build : go -check build -linux ## Build the binary matching the local system
$(DIST_DIRS) :
mkdir -p $( DIST_DIRS)
.PHONY : build -linux
build-linux : | $( DIST_DIRS )
CGO_ENABLED = " $( CGO_ENABLED) " CGO_CFLAGS = " $( CGO_CFLAGS) " $( GO) build $( GOFLAGS) -tags 'netgo osusergo tzdata $(TAGS)' -ldflags '$(LDFLAGS)' -o $( DIST_BIN_DIR) /$( VERSIONED_BINARY)
.PHONY : release -copy
release-copy : | $( DIST_DIRS )
cd $( DIST) ; for file in ` find . -type f -name "*" ` ; do cp $$ { file} ./release/; done ;
.PHONY : release -check
release-check : | $( DIST_DIRS )
cd $( DIST) /release/; for file in ` find . -type f -name "*" ` ; do echo " checksumming $$ {file} " && $( SHASUM) ` echo $$ { file} | sed 's/^..//' ` > $$ { file} .sha256; done ;
.PHONY : release -compress
release-compress : | $( DIST_DIRS )
cd $( DIST) /release/; for file in ` find . -type f -name "*" ` ; do echo " compressing $$ {file} " && $( GO) run $( GXZ_PAGAGE) -k -9 $$ { file} ; done ;
.PHONY : release -sources
release-sources : | $( DIST_DIRS )
echo $( VERSION) > $( STORED_VERSION_FILE)
# bsdtar needs a ^ to prevent matching subdirectories
$( eval EXCL := --exclude= $( shell tar --help | grep -q bsdtar && echo "^" ) ./)
# use transform to a add a release-folder prefix; in bsdtar the transform parameter equivalent is -s
$( eval TRANSFORM := $( shell tar --help | grep -q bsdtar && echo " -s '/^./ $( BINARY_BASE_NAME) -src- $( VERSION) /' " || echo " --transform 's|^./| $( BINARY_BASE_NAME) -src- $( VERSION) /|' " ) )
tar $( addprefix $( EXCL) ,$( TAR_EXCLUDES) ) $( TRANSFORM) -czf $( DIST) /release/$( BINARY_BASE_NAME) -src-$( VERSION) .tar.gz .
rm -f $( STORED_VERSION_FILE)
.PHONY : release ## Prepare a full release
2023-12-26 21:45:39 +00:00
release : build -linux # release-copy release-compress vendor release-sources release-check
2023-11-25 21:57:49 +00:00
.PHONY : dockerize
dockerize : | $( DIST_DIRS )
cp -R docker/fscopy/* $( DIST_DOCKER_DIR) /
cp $( DIST_BIN_DIR) /$( VERSIONED_BINARY) $( DIST_DOCKER_DIR) /bin/$( BINARY_BASE_NAME)
docker/make_dockerfile.sh > $( DIST_DOCKER_DIR) /Dockerfile