Repository navigation
Expand file tree
/
Copy pathmakefile
More file actions
161 lines (131 loc) · 8.18 KB
/
Copy pathmakefile
File metadata and controls
161 lines (131 loc) · 8.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# recipes use bash for pipefail support (ubuntu's default sh is dash)
SHELL := /bin/bash
GIT_COMMIT=$(shell git describe --always --long --dirty)
GIT_VERSION=$(shell git describe --tags --dirty 2>/dev/null | sed 's/-\([0-9]*\)-g/+\1@g/' || echo dev)
TEST_TIMEOUT?=15m
# dev tool binaries are built into .tools/bin (gitignored) from the versions pinned in
# .tools/go.mod - the single source of truth for make and CI; dependabot keeps them updated
TOOLS_BIN=.tools/bin
ACTIONLINT=$(TOOLS_BIN)/actionlint
GOFUMPT=$(TOOLS_BIN)/gofumpt
GOLANGCI_LINT=$(TOOLS_BIN)/golangci-lint
# non-Go tools also live in .tools/bin at pinned versions, but the pins are here (dependabot
# cannot bump them): shellcheck, typos and zizmor are static binaries downloaded from their github releases,
# yamllint is python installed into a repo-local venv. all rebuild when this makefile changes.
SHELLCHECK_VERSION=v0.11.0
TYPOS_VERSION=v1.50.1
YAMLLINT_VERSION=1.38.0
ZIZMOR_VERSION=v1.30.1
SHELLCHECK=$(TOOLS_BIN)/shellcheck
TYPOS=$(TOOLS_BIN)/typos
YAMLLINT=$(TOOLS_BIN)/yamllint
ZIZMOR=$(TOOLS_BIN)/zizmor
# golangci-lint with the azproviderlint module plugin compiled in (.tools/.custom-gcl.yml);
# lint runs use this binary, the plain go.mod one exists to bootstrap `golangci-lint custom`
GOLANGCI_LINT_MODULES=$(TOOLS_BIN)/golangci-with-modules
# one rule builds any Go tool: the import path comes from the tool directives in .tools/go.mod
# (via go list tool), so the makefile never repeats it - add a tool there and a variable above
$(TOOLS_BIN)/%: .tools/go.mod .tools/go.sum
@echo "==> building $* (version pinned in .tools/go.mod)..."
@cd .tools && go build -o bin/$* $$(go list tool | grep "/$*$$")
# explicit rules take precedence over the pattern rule above for the non-Go tools
$(GOLANGCI_LINT_MODULES): .tools/.custom-gcl.yml $(GOLANGCI_LINT)
@echo "==> building golangci-lint with plugins (versions pinned in .tools/.custom-gcl.yml)..."
@cd .tools && bin/golangci-lint custom
$(SHELLCHECK): makefile
@echo "==> downloading shellcheck $(SHELLCHECK_VERSION)..."
@mkdir -p $(TOOLS_BIN)
@os=$$(uname | tr 'A-Z' 'a-z'); arch=$$(uname -m); [ "$$arch" = "arm64" ] && arch=aarch64; \
curl -sSfL "https://github.com/koalaman/shellcheck/releases/download/$(SHELLCHECK_VERSION)/shellcheck-$(SHELLCHECK_VERSION).$$os.$$arch.tar.xz" \
| tar -xJ -O shellcheck-$(SHELLCHECK_VERSION)/shellcheck > $@ && chmod +x $@
$(TYPOS): makefile
@echo "==> downloading typos $(TYPOS_VERSION)..."
@mkdir -p $(TOOLS_BIN)
@case "$$(uname)" in Darwin) target=apple-darwin;; *) target=unknown-linux-musl;; esac; \
arch=$$(uname -m); [ "$$arch" = "arm64" ] && arch=aarch64; \
curl -sSfL "https://github.com/crate-ci/typos/releases/download/$(TYPOS_VERSION)/typos-$(TYPOS_VERSION)-$$arch-$$target.tar.gz" \
| tar -xz -O ./typos > $@ && chmod +x $@
$(YAMLLINT): makefile
@command -v python3 >/dev/null || (echo "python3 is required to install yamllint (macOS: xcode CLT; Debian/Ubuntu: apt install python3-venv)" && exit 1)
@echo "==> installing yamllint $(YAMLLINT_VERSION) into .tools/venv..."
@mkdir -p $(TOOLS_BIN)
@python3 -m venv .tools/venv && .tools/venv/bin/pip install -q yamllint==$(YAMLLINT_VERSION) && ln -sf ../venv/bin/yamllint $@
$(ZIZMOR): makefile
@echo "==> downloading zizmor $(ZIZMOR_VERSION)..."
@mkdir -p $(TOOLS_BIN)
@case "$$(uname)" in Darwin) target=apple-darwin;; *) target=unknown-linux-gnu;; esac; \
arch=$$(uname -m); [ "$$arch" = "arm64" ] && arch=aarch64; \
curl -sSfL "https://github.com/zizmorcore/zizmor/releases/download/$(ZIZMOR_VERSION)/zizmor-$$arch-$$target.tar.gz" \
| tar -xz -O zizmor > $@ && chmod +x $@
default: fmt build
all: fmt build
help: ## Show this help
@awk 'BEGIN {FS = ":.*##"; printf "Usage: make \033[36m<target>\033[0m\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-24s\033[0m%s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) }' $(MAKEFILE_LIST)
##@ Build
build: ## Compile tctest with version info from git
@echo "==> building..."
go build -ldflags "-X github.com/katbyte/tctest/lib/version.GitCommit=${GIT_COMMIT} -X github.com/katbyte/tctest/lib/version.Version=${GIT_VERSION}"
install: ## Install tctest into GOPATH/bin with version info from git
@echo "==> installing..."
go install -ldflags "-X github.com/katbyte/tctest/lib/version.GitCommit=${GIT_COMMIT} -X github.com/katbyte/tctest/lib/version.Version=${GIT_VERSION}" .
tools: $(ACTIONLINT) $(GOFUMPT) $(GOLANGCI_LINT) $(GOLANGCI_LINT_MODULES) $(SHELLCHECK) $(TYPOS) $(YAMLLINT) $(ZIZMOR) ## Install all pinned dev tools into .tools/bin
##@ Formatting
fmt: $(GOFUMPT) $(GOLANGCI_LINT) ## Fix Go formatting (gofmt, gofumpt, goimports)
@echo "==> Fixing source code with gofmt..."
find . -name '*.go' | grep -v vendor | xargs gofmt -s -w
@echo "==> Fixing source code with gofumpt..."
find . -name '*.go' | grep -v vendor | xargs $(GOFUMPT) -w
@echo "==> Fixing imports with golangci-lint (goimports)..."
$(GOLANGCI_LINT) fmt -E goimports ./...
goimports: $(GOLANGCI_LINT) ## Fix imports with golangci-lint (goimports)
@echo "==> Fixing imports with golangci-lint (goimports)..."
$(GOLANGCI_LINT) fmt -E goimports ./...
##@ Linting & Dependencies
lint: $(GOLANGCI_LINT_MODULES) ## Check source code with the golangci linters (incl. azproviderlint)
@echo "==> Checking source code against linters..."
$(GOLANGCI_LINT_MODULES) run ./...
actionlint: $(ACTIONLINT) $(SHELLCHECK) ## Check GitHub workflows with actionlint (incl. shellcheck on run blocks)
@echo "==> Checking workflows with actionlint..."
@$(ACTIONLINT) -shellcheck=$(SHELLCHECK)
lint-fix: $(GOLANGCI_LINT_MODULES) ## Fix source code with all golangci linters
@echo "==> Checking source code against linters (applying autofixes)..."
$(GOLANGCI_LINT_MODULES) run --fix ./...
yamllint: $(YAMLLINT) ## Check YAML files with yamllint (config in .yamllint.yml)
@echo "==> Checking YAML files with yamllint..."
@$(YAMLLINT) -s .
shellcheck: $(SHELLCHECK) ## Check shell scripts with shellcheck
@echo "==> Checking shell scripts with shellcheck..."
@$(SHELLCHECK) scripts/*.sh .github/images/*.sh
typos: $(TYPOS) ## Check all files for spelling mistakes with typos (config in .typos.toml)
@echo "==> Checking for typos..."
@$(TYPOS)
typos-fix: $(TYPOS) ## Fix spelling mistakes found by typos
@echo "==> Fixing typos..."
@$(TYPOS) --write-changes
zizmor: $(ZIZMOR) ## Audit GitHub workflows for security issues with zizmor
@echo "==> Auditing workflows with zizmor..."
@$(ZIZMOR) .
depscheck: ## Check that go.mod/go.sum and vendor/ are in sync
@echo "==> Checking source code with go mod tidy..."
@go mod tidy
@git diff --exit-code -- go.mod go.sum || \
(echo; echo "Unexpected difference in go.mod/go.sum files. Run 'go mod tidy' command or revert any go.mod/go.sum changes and commit."; exit 1)
@echo "==> Checking source code with go mod vendor..."
@go mod vendor
@git diff --compact-summary --exit-code -- vendor || \
(echo; echo "Unexpected difference in vendor/ directory. Run 'go mod vendor' command or revert any go.mod/go.sum/vendor changes and commit."; exit 1)
@echo "==> Checking .tools/go.mod with go mod tidy..."
@cd .tools && go mod tidy
@git diff --exit-code -- .tools/go.mod .tools/go.sum || \
(echo; echo "Unexpected difference in .tools/go.mod/go.sum. Run 'cd .tools && go mod tidy' and commit."; exit 1)
@echo "==> Checking .tools/.custom-gcl.yml golangci-lint version matches .tools/go.mod..."
@modv=$$(cd .tools && go list -m -f '{{.Version}}' github.com/golangci/golangci-lint/v2); \
gclv=$$(grep '^version:' .tools/.custom-gcl.yml | awk '{print $$2}'); \
[ "$$modv" = "$$gclv" ] || \
(echo; echo "golangci-lint version mismatch: .tools/go.mod has $$modv but .tools/.custom-gcl.yml has $$gclv - update .custom-gcl.yml to match."; exit 1)
##@ Testing
test: build ## Run unit and integration tests under the race detector
go test -race $$(go list ./... | grep -v '/integration$$') -timeout ${TEST_TIMEOUT}
@set -o pipefail; go test -race ./integration/ -v -timeout ${TEST_TIMEOUT} | grep -vE "^=== |--- PASS|^PASS$$"
check-all: build test lint actionlint yamllint shellcheck typos depscheck ## Run build + test + all linters + depscheck
.PHONY: default all help fmt goimports build lint lint-fix actionlint yamllint shellcheck typos typos-fix zizmor depscheck check-all install tools test