-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMakefile
More file actions
254 lines (216 loc) · 9.94 KB
/
Copy pathMakefile
File metadata and controls
254 lines (216 loc) · 9.94 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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
.PHONY: help plugin-powerdns plugin-powerdns-smoke install test build run clean docker-build docker-run build-offline release go-check gopls-logs lint-backend lint-agent lint-fast lint-staticcheck-only security-local
# Default target
help:
@echo "Charon Build System"
@echo ""
@echo "Available targets:"
@echo " install - Install all dependencies (backend + frontend)"
@echo " test - Run all tests (backend + frontend)"
@echo " build - Build backend and frontend"
@echo " run - Run backend in development mode"
@echo " clean - Clean build artifacts"
@echo " docker-build - Build Docker image"
@echo " docker-build-versioned - Build Docker image with version from .version file"
@echo " docker-run - Run Docker container"
@echo " docker-dev - Run Docker in development mode"
@echo " release - Create a new semantic version release (interactive)"
@echo " dev - Run both backend and frontend in dev mode (requires tmux)"
@echo " go-check - Verify backend build readiness (runs scripts/check_go_build.sh)"
@echo " gopls-logs - Collect gopls diagnostics (runs scripts/gopls_collect.sh)"
@echo " local-patch-report - Generate local patch coverage report"
@echo " plugin-powerdns - Build and test the PowerDNS plugin"
@echo " plugin-powerdns-smoke - plugin.Open smoke test against a fresh PowerDNS plugin build"
@echo ""
@echo "Security targets:"
@echo " security-scan - Quick security scan (govulncheck on Go deps)"
@echo " security-local - Run govulncheck + semgrep (p/golang) locally before push"
@echo " security-scan-full - Full container scan with Trivy"
@echo " security-scan-deps - Check for outdated Go dependencies"
# Install all dependencies
install:
@echo "Installing backend dependencies..."
cd backend && go mod download
@echo "Installing frontend dependencies..."
cd frontend && npm install --ignore-scripts
# Install Go development tools
install-tools:
@echo "Installing Go development tools..."
go install gotest.tools/gotestsum@latest
@echo "Tools installed successfully"
# Install go 1.26.0 system-wide and setup GOPATH/bin
install-go:
@echo "Installing go 1.26.0 and gopls (requires sudo)"
sudo ./scripts/install-go-1.26.0.sh
# Clear Go and gopls caches
clear-go-cache:
@echo "Clearing Go and gopls caches"
./scripts/clear-go-cache.sh
# Run all tests
test:
@echo "Running backend tests..."
cd backend && go test -v ./...
@echo "Running frontend lint..."
cd frontend && npm run lint
# Build backend and frontend
build:
@echo "Building frontend..."
cd frontend && npm run build
@echo "Building backend..."
cd backend && go build -o bin/api ./cmd/api
build-versioned:
@echo "Building frontend (versioned)..."
cd frontend && VITE_APP_VERSION=$$(git describe --tags --always --dirty) npm run build
@echo "Building backend (versioned)..."
cd backend && \
VERSION=$$(git describe --tags --always --dirty); \
GIT_COMMIT=$$(git rev-parse --short HEAD); \
BUILD_DATE=$$(date -u +'%Y-%m-%dT%H:%M:%SZ'); \
go build -ldflags "-X github.com/Wikid82/charon/backend/internal/version.Version=$$VERSION -X github.com/Wikid82/charon/backend/internal/version.GitCommit=$$GIT_COMMIT -X github.com/Wikid82/charon/backend/internal/version.BuildTime=$$BUILD_DATE" -o bin/api ./cmd/api
# Run backend in development mode
run:
cd backend && go run ./cmd/api
# Run frontend in development mode
run-frontend:
cd frontend && npm run dev
# Clean build artifacts
clean:
@echo "Cleaning build artifacts..."
rm -rf backend/bin backend/data
rm -rf frontend/dist frontend/node_modules
go clean -cache
# Build Docker image
docker-build:
docker compose -f .docker/compose/docker-compose.yml build
# Build Docker image with version
docker-build-versioned:
@VERSION=$$(cat .version 2>/dev/null || git describe --tags --always --dirty 2>/dev/null || echo "dev"); \
BUILD_DATE=$$(date -u +'%Y-%m-%dT%H:%M:%SZ'); \
VCS_REF=$$(git rev-parse HEAD 2>/dev/null || echo "unknown"); \
docker build \
--build-arg VERSION=$$VERSION \
--build-arg BUILD_DATE=$$BUILD_DATE \
--build-arg VCS_REF=$$VCS_REF \
-t charon:$$VERSION \
-t charon:latest \
.
# Build the image WITHOUT pulling the prebuilt toolchain image — compiles the
# custom Caddy + CrowdSec binaries from source (caddy-inline / crowdsec-inline).
# Use offline / air-gapped, or when not logged in to GHCR. Slow (~14 min extra).
#
# The two --build-arg selectors below are the single source of truth for "build
# the inline path". Overridable knobs (used by .github/workflows/build-offline.yml):
# DOCKER_BUILD - builder command (default "docker build"; CI passes
# "docker buildx build" for GHA layer caching)
# BUILD_OFFLINE_ARGS - extra flags (e.g. --platform, --load, --cache-from/to)
DOCKER_BUILD ?= docker build
BUILD_OFFLINE_ARGS ?=
build-offline:
$(DOCKER_BUILD) \
--build-arg CADDY_BUILDER_SRC=caddy-inline \
--build-arg CROWDSEC_BUILDER_SRC=crowdsec-inline \
$(BUILD_OFFLINE_ARGS) \
-t charon:offline \
.
# Run Docker containers (production)
docker-run:
docker compose -f .docker/compose/docker-compose.yml up -d
# Run Docker containers (development)
docker-dev:
docker compose -f .docker/compose/docker-compose.yml -f .docker/compose/docker-compose.dev.yml up
# Stop Docker containers
docker-stop:
docker compose -f .docker/compose/docker-compose.yml down
# View Docker logs
docker-logs:
docker compose -f .docker/compose/docker-compose.yml logs -f
# Development mode (requires tmux)
dev:
@command -v tmux >/dev/null 2>&1 || { echo "tmux is required for dev mode"; exit 1; }
tmux new-session -d -s charon 'cd backend && go run ./cmd/api'
tmux split-window -h -t charon 'cd frontend && npm run dev'
tmux attach -t charon
# Create a new release (interactive script)
release:
@./scripts/release.sh
go-check:
./scripts/check_go_build.sh
gopls-logs:
./scripts/gopls_collect.sh
local-patch-report:
bash scripts/local-patch-report.sh
# Security scanning targets
security-scan:
@echo "Running security scan (govulncheck)..."
@./scripts/security-scan.sh
security-local: ## Run govulncheck + semgrep (p/golang) before push — fast local gate
@echo "[1/2] Running govulncheck..."
@./scripts/security-scan.sh
@echo "[2/2] Running Semgrep (p/golang, ERROR+WARNING)..."
@SEMGREP_CONFIG=p/golang ./scripts/pre-commit-hooks/semgrep-scan.sh
security-scan-full:
@echo "Building local Docker image for security scan..."
docker build --build-arg VCS_REF=$(shell git rev-parse HEAD) -t charon:local .
@echo "Running Trivy container scan..."
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(HOME)/.cache/trivy:/root/.cache/trivy \
aquasec/trivy:latest image \
--severity CRITICAL,HIGH \
charon:local
security-scan-deps:
@echo "Scanning Go dependencies..."
cd backend && go list -m -json all | docker run --rm -i aquasec/trivy:latest sbom --format json - 2>/dev/null || true
@echo "Checking for Go module updates..."
cd backend && go list -m -u all | grep -E '\[.*\]' || echo "All modules up to date"
# Quality Assurance targets
# Full golangci-lint config (backend/.golangci.yml) is shared by backend and agent.
# The version pin below is tracked by Renovate and must match .github/workflows/quality-checks.yml.
lint-backend:
@echo "Running golangci-lint (full config) on backend..."
@# renovate: datasource=github-releases depName=golangci/golangci-lint
docker run --rm -v $(PWD):/app -w /app/backend golangci/golangci-lint:v2.14.0 golangci-lint run -v --timeout=5m ./...
lint-agent:
@echo "Running golangci-lint (full config, shared from backend/) on agent..."
@# renovate: datasource=github-releases depName=golangci/golangci-lint
docker run --rm -v $(PWD):/app -w /app/agent golangci/golangci-lint:v2.14.0 golangci-lint run -v --timeout=5m --config ../backend/.golangci.yml ./...
lint-fast:
@echo "Running fast linters (staticcheck, govet, errcheck, ineffassign, unused) — backend + agent..."
cd backend && golangci-lint run --config ../.golangci-fast.yml ./...
cd agent && golangci-lint run --config ../.golangci-fast.yml ./...
lint-staticcheck-only:
@echo "Running staticcheck only — backend + agent..."
cd backend && golangci-lint run --config ../.golangci-fast.yml --enable-only staticcheck ./...
cd agent && golangci-lint run --config ../.golangci-fast.yml --enable-only staticcheck ./...
lint-docker:
@echo "Running Hadolint..."
docker run --rm -i hadolint/hadolint < Dockerfile
test-race:
@echo "Running Go tests with race detection..."
cd backend && go test -race -v ./...
check-module-coverage:
@echo "Running module-specific coverage checks (backend + agent)"
@bash scripts/check-module-coverage.sh
benchmark:
@echo "Running Go benchmarks..."
cd backend && go test -bench=. -benchmem ./...
integration-test:
@echo "Running integration tests..."
@./scripts/integration-test.sh
# Build the bundled PowerDNS plugin and run its tests.
# The plugin MUST be built with the same toolchain, flags and dependency
# versions as the host binary (no -trimpath, -race or -cover), otherwise
# plugin.Open rejects it. The workspace (go.work) pins the shared dependencies.
plugin-powerdns:
@echo "Building and testing the PowerDNS plugin..."
@tmp=$$(mktemp -d) && trap 'rm -rf "$$tmp"' EXIT && \
cd plugins/powerdns && \
CGO_ENABLED=1 go build -buildmode=plugin -o "$$tmp/powerdns.so" . && \
CGO_ENABLED=1 go test -count=1 ./...
# Prove a freshly rebuilt powerdns.so loads into the host (plugin.Open).
# Always rebuilds into a temp dir; never reuses plugins/powerdns/powerdns.so.
plugin-powerdns-smoke:
@echo "Smoke-testing plugin.Open against a freshly built PowerDNS plugin..."
@tmp=$$(mktemp -d) && trap 'rm -rf "$$tmp"' EXIT && \
(cd plugins/powerdns && CGO_ENABLED=1 go build -buildmode=plugin -o "$$tmp/powerdns.so" .) && \
cd backend && CGO_ENABLED=1 CHARON_SMOKE_PLUGIN_SO="$$tmp/powerdns.so" \
go test -tags plugin_smoke -run TestPluginSmoke ./internal/services -count=1