forked from dynatrace-oss/dtctl
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmakefile
More file actions
197 lines (165 loc) · 6.98 KB
/
Copy pathmakefile
File metadata and controls
197 lines (165 loc) · 6.98 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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
.PHONY: all build clean test test-unit test-integration test-all test-coverage test-update-golden install lint lint-strict fmt markdownlint markdownlint-fix security-scan check release release-snapshot test-sdk vet-sdk lint-sdk sdk-check-deps sdk-check-imports sdk-check
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
# Minimum test coverage percentage. Raise as coverage improves: 60 -> 70 -> 80 -> 85.
COVERAGE_THRESHOLD ?= 60
LDFLAGS = -ldflags "-X github.com/dynatrace-oss/dtctl/pkg/version.Version=$(VERSION) -X github.com/dynatrace-oss/dtctl/pkg/version.Commit=$(COMMIT) -X github.com/dynatrace-oss/dtctl/pkg/version.Date=$(DATE) -s -w"
INSTALL_BIN_DIR ?= $(if $(GOBIN),$(GOBIN),$(shell go env GOPATH)/bin)
MD_LINT_CLI_IMAGE := "ghcr.io/igorshubovych/markdownlint-cli:v0.31.1"
all: build
# Build the binary
build:
@echo "Building dtctl..."
@go build $(LDFLAGS) -o bin/dtctl .
# Build for macOS (arm64)
build-darwin-arm64:
@echo "Building dtctl for darwin/arm64..."
@env GOOS=darwin GOARCH=arm64 CGO_ENABLED=0 go build $(LDFLAGS) -o bin/dtctl-darwin-arm64 .
# Convenience target: build for current host OS/ARCH
build-host:
@echo "Building dtctl for host: $(shell go env GOOS)/$(shell go env GOARCH)..."
@env GOOS=$(shell go env GOOS) GOARCH=$(shell go env GOARCH) CGO_ENABLED=0 go build $(LDFLAGS) -o bin/dtctl-host .
# Run unit tests (default test target)
test:
@echo "Running unit tests..."
@go test -v -race -coverprofile=coverage.out ./...
# Run only unit tests (excludes integration tests)
test-unit:
@echo "Running unit tests..."
@go test -v -race -coverprofile=coverage.out ./...
# Run integration tests (requires DTCTL_INTEGRATION_ENV and DTCTL_INTEGRATION_TOKEN)
# Environment variables can be set via:
# 1. .integrationtests.env file (recommended, gitignored)
# 2. Shell environment variables
# 3. Command line: DTCTL_INTEGRATION_ENV=... make test-integration
test-integration:
@echo "Running integration tests..."
@# Load .integrationtests.env if it exists
@if [ -f .integrationtests.env ]; then \
echo "Loading environment from .integrationtests.env"; \
export $$(cat .integrationtests.env | grep -v '^#' | xargs); \
fi; \
if [ -z "$$DTCTL_INTEGRATION_ENV" ]; then \
echo "Error: DTCTL_INTEGRATION_ENV not set."; \
echo ""; \
echo "Create .integrationtests.env with your credentials:"; \
echo " cp .integrationtests.env.example .integrationtests.env"; \
echo " # Edit .integrationtests.env with your environment URL and token"; \
echo ""; \
echo "Or set environment variables:"; \
echo " export DTCTL_INTEGRATION_ENV=https://your-env.apps.dynatrace.com"; \
echo " export DTCTL_INTEGRATION_TOKEN=dt0s16.XXX"; \
exit 1; \
fi; \
if [ -z "$$DTCTL_INTEGRATION_TOKEN" ]; then \
echo "Error: DTCTL_INTEGRATION_TOKEN not set."; \
echo "See .integrationtests.env.example for setup instructions."; \
exit 1; \
fi; \
go test -v -race -count=1 -tags integration ./test/e2e/...
# Regenerate golden files (run after intentional output changes)
test-update-golden:
@echo "Updating golden files..."
@go test ./... -update
@echo "Golden files updated. Review changes with: git diff pkg/output/testdata/"
# Run all tests (unit + integration)
test-all: test-unit test-integration
# Run tests and enforce coverage threshold
test-coverage:
@echo "Running tests with coverage..."
@go test -race -coverprofile=coverage.out -covermode=atomic ./...
@echo ""
@echo "=== Package Coverage ==="
@go tool cover -func=coverage.out | grep -E "^(total|.*\t)" | tail -30
@echo ""
@COVERAGE=$$(go tool cover -func=coverage.out | grep total | awk '{print $$3}' | sed 's/%//'); \
COVERAGE_INT=$${COVERAGE%.*}; \
echo "Total coverage: $${COVERAGE}% (threshold: $(COVERAGE_THRESHOLD)%)"; \
if [ "$$COVERAGE_INT" -lt "$(COVERAGE_THRESHOLD)" ]; then \
echo "FAIL: Coverage $${COVERAGE}% is below the $(COVERAGE_THRESHOLD)% threshold"; \
exit 1; \
fi; \
echo "OK: Coverage meets threshold"
# Install locally
install:
@echo "Installing dtctl to $(INSTALL_BIN_DIR)..."
@mkdir -p "$(INSTALL_BIN_DIR)"
@go build $(LDFLAGS) -o "$(INSTALL_BIN_DIR)/dtctl" .
@if case ":$$PATH:" in *":$(INSTALL_BIN_DIR):"*) false;; *) true;; esac; then \
echo ""; \
echo "dtctl installed, but $(INSTALL_BIN_DIR) is not in PATH."; \
echo "Add it with:"; \
echo ' export PATH="$$PATH:$(INSTALL_BIN_DIR)"'; \
fi
# Clean build artifacts
clean:
@rm -rf bin/ dist/ coverage.out
# Run linter
lint:
@golangci-lint run
# Run strict linter (matches CI behavior — zero tolerance)
lint-strict:
@echo "Checking goimports formatting..."
@goimports_output=$$(goimports -local github.com/dynatrace-oss/dtctl -l .); \
if [ -n "$$goimports_output" ]; then \
echo "The following files are not properly formatted:"; \
echo "$$goimports_output"; \
echo ""; \
echo "Run 'make fmt' to fix formatting."; \
exit 1; \
fi
@echo "Checking go mod tidy..."
@go mod tidy && git diff --exit-code go.mod go.sum > /dev/null 2>&1 || \
(echo "go.mod or go.sum is not tidy. Run 'go mod tidy' and commit the changes." && exit 1)
@echo "Running golangci-lint (zero tolerance)..."
@golangci-lint run
# Run security vulnerability scan
security-scan:
@echo "Running govulncheck..."
@govulncheck ./...
# Run all checks (lint-strict + security)
check: lint-strict security-scan
# Format code
fmt:
@go fmt ./...
@goimports -local github.com/dynatrace-oss/dtctl -w .
# Markdown linting
markdownlint:
docker run -v $(CURDIR):/workdir:ro --rm \
--network=none --read-only --security-opt=no-new-privileges --cap-drop ALL \
$(MD_LINT_CLI_IMAGE) "**/*.md"
markdownlint-fix:
docker run -v $(CURDIR):/workdir --rm \
--network=none --security-opt=no-new-privileges --cap-drop ALL --cap-add DAC_OVERRIDE \
$(MD_LINT_CLI_IMAGE) "**/*.md" --fix
# Release (using goreleaser)
release:
@goreleaser release --clean
# Release snapshot (local testing)
release-snapshot:
@goreleaser release --snapshot --clean
# --- SDK targets ---
# Build and test the SDK module
test-sdk:
@echo "Running SDK tests..."
@cd sdk && go test -v -race ./...
vet-sdk:
@cd sdk && go vet ./...
lint-sdk:
@cd sdk && golangci-lint run ./...
# Check that the SDK does not depend on forbidden heavy dependencies
sdk-check-deps:
@echo "Checking SDK dependencies..."
@cd sdk && go list -m all | grep -E '(cobra|viper|logrus|opentelemetry|asciigraph|toon-go)' && \
echo "FORBIDDEN dependency found in sdk/" && exit 1 || echo "sdk/ deps OK"
# Check that the SDK does not import from the CLI module
sdk-check-imports:
@echo "Checking SDK imports..."
@cd sdk && ! grep -rE '"github.com/dynatrace-oss/dtctl[^/]' --include='*.go' . || \
(echo "FORBIDDEN: sdk/ imports from CLI module" && exit 1)
@cd sdk && ! grep -rE '"github.com/dynatrace-oss/dtctl/(cmd|pkg)' --include='*.go' . || \
(echo "FORBIDDEN: sdk/ imports from CLI cmd/ or pkg/" && exit 1)
@echo "sdk/ imports OK"
# Run all SDK checks
sdk-check: test-sdk vet-sdk sdk-check-deps sdk-check-imports