Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
138 lines (117 loc) · 6.66 KB
/
Copy pathMakefile
File metadata and controls
138 lines (117 loc) · 6.66 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
.PHONY: build agent test fmt lint lint-version-check verify-template corrections-base verify check ci clean release-check bump site site-serve
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
LDFLAGS := -s -w -X main.version=$(VERSION)
# golangci-lint's release, read from mise.toml, the single source of tool pins
# (frostyard/core ADR-0043): `mise install` provisions it, and CI installs the
# same mise.lock-verified release. The Go patch level is not compared: release
# binaries are built with the current Go patch, and it does not change gofmt
# output or the type checker's major/minor language version.
GOLANGCI_LINT_VERSION := $(strip $(shell sed -n 's/^golangci-lint = "\(.*\)"/\1/p' mise.toml))
GO_VERSION := $(strip $(shell sed -n 's/^go \([0-9.]*\)$$/\1/p' go.mod))
# The major version of the Node on PATH (mise.toml pins it), checked by
# make verify-template so the template gate needs no package install.
NODE_MAJOR := $(shell node -p "process.versions.node.split('.')[0]" 2>/dev/null)
# The repository's Go files, tracked or new, so gofmt skips ignored local
# scratch such as build/.
GO_FILES = $(shell git ls-files --cached --others --exclude-standard '*.go')
build:
go build -trimpath -ldflags '$(LDFLAGS)' -o build/nsl .
# The VM image embeds the agent; it runs on x86-64 VMs whatever the host.
agent:
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags '-s -w' -o build/nsl-agent ./cmd/nsl-agent
test:
go test ./...
fmt:
gofmt -w $(GO_FILES)
lint: lint-version-check
golangci-lint run
lint-version-check:
@test -n "$(GOLANGCI_LINT_VERSION)" || { echo "mise.toml pins no golangci-lint"; exit 1; }
@installed="$$(golangci-lint version --short 2>/dev/null)" || { \
echo "golangci-lint $(GOLANGCI_LINT_VERSION) is required (install with: mise install)"; exit 1; }; \
if [ "$$installed" != "$(GOLANGCI_LINT_VERSION)" ]; then \
echo "expected golangci-lint $(GOLANGCI_LINT_VERSION), found $$installed (install with: mise install)"; exit 1; \
fi; \
built="$$(golangci-lint version 2>/dev/null | sed -n 's/.*built with go\([0-9.]*\).*/\1/p')"; \
built_minor="$$(printf '%s\n' "$$built" | sed -n 's/^\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/p')"; \
go_minor="$$(printf '%s\n' "$(GO_VERSION)" | sed -n 's/^\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/p')"; \
if [ -n "$$built_minor" ] && [ -n "$$go_minor" ] && [ "$$(printf '%s\n%s\n' "$$go_minor" "$$built_minor" | sort -V | head -1)" != "$$go_minor" ]; then \
echo "golangci-lint $(GOLANGCI_LINT_VERSION) was built with go$$built, older than go.mod's go$(GO_VERSION)"; exit 1; \
fi
# The gate triad (frostyard/core ADR-0043, ADR-0044). verify is credential-free
# and leaves a clean checkout clean: what a read-only reviewer runs. check is the
# developer gate and may format. ci is verify plus what CI alone adds.
verify:
go mod tidy -diff
python3 scripts/license-notices.py --check
go vet ./...
test -z "$$(gofmt -l $(GO_FILES))"
$(MAKE) --no-print-directory lint
$(MAKE) --no-print-directory verify-template
python3 -m unittest discover -s scripts -p 'test_*.py'
go test ./...
check: fmt verify
# Check the agent surfaces, docs index, risk paths, corrections and vendored
# copies (needs Node.js 22 or later, from mise.toml)
verify-template:
@if ! command -v node >/dev/null 2>&1; then echo "FAIL: verify-template requires Node.js 22 or later (run: mise install)"; exit 1; fi
@if [ "$(NODE_MAJOR)" = "" ] || [ "$(NODE_MAJOR)" -lt 22 ]; then echo "FAIL: verify-template requires Node.js 22 or later (found: $$(node --version 2>/dev/null || echo missing)); run: mise install"; exit 1; fi
node scripts/check-template.mjs
node --test test/*.test.mjs
# The corrections check compares .memory/corrections.jsonl with BASE: lines
# are append-only (only an empty promoted_to may be filled in). The contract
# starts with the gate: a BASE that does not hold
# scripts/check-corrections.mjs had no such rule, so the comparison is skipped
# with a notice. Every BASE after the adoption holds the script.
#
# A BASE that does not resolve to a commit is an error, never an old base: a
# typo or an unfetched ref must not turn the comparison into a silent pass.
corrections-base:
@if [ -z "$(BASE)" ]; then exit 0; fi; \
if ! git rev-parse --verify --quiet "$(BASE)^{commit}" >/dev/null; then \
echo "FAIL: BASE $(BASE) does not resolve to a commit (fetch it first)"; \
exit 1; \
fi; \
if git cat-file -e "$(BASE):scripts/check-corrections.mjs" 2>/dev/null; then \
node scripts/check-corrections.mjs --base "$(BASE)"; \
else \
echo "==> corrections: BASE $(BASE) predates the corrections gate; append-only comparison skipped"; \
fi
# verify runs the tests under the caller's umask and ci runs the race tests
# under a strict one, so no test depends on the umask of the machine that runs it.
ci: verify corrections-base
mkdir -p build
umask 0077 && go test -race -coverprofile=build/coverage.out ./...
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -o build/nsl-linux-amd64 .
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -trimpath -o build/nsl-linux-arm64 .
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -o build/nsl-agent ./cmd/nsl-agent
release-check:
goreleaser check
# Tag the next release and push it; release.yml builds it. svu derives the
# version from conventional commits (.svu.yml) and is pinned in mise.toml.
# Only a clean main that matches origin/main, after make ci, is tagged.
bump:
@command -v svu >/dev/null 2>&1 || { echo "svu is required for make bump (install with: mise install)"; exit 1; }
@test -z "$$(git status --porcelain)" || { echo "The working tree is not clean; commit or stash before bumping."; exit 1; }
@test "$$(git branch --show-current)" = main || { echo "Bump from main."; exit 1; }
git fetch --quiet --tags origin main
@test "$$(git rev-parse HEAD)" = "$$(git rev-parse origin/main)" || { echo "HEAD is not origin/main; pull or push first."; exit 1; }
$(MAKE) ci
@test -z "$$(git status --porcelain)" || { echo "make ci changed the working tree; not tagging."; exit 1; }
@version=$$(svu next); \
git tag -a "$$version" -m "Version $$version"; \
echo "Tagged $$version; pushing it to origin"; \
git push origin "$$version"
# The documentation site (site/), built with pinned ProperDocs and MaterialX.
SITE_VENV := build/site-venv
$(SITE_VENV)/bin/properdocs: site/requirements.txt
python3 -m venv $(SITE_VENV)
$(SITE_VENV)/bin/pip install -q --require-hashes -r site/requirements.txt
touch $@
site: $(SITE_VENV)/bin/properdocs
$(SITE_VENV)/bin/properdocs build --strict -f site/properdocs.yml
site-serve: $(SITE_VENV)/bin/properdocs
$(SITE_VENV)/bin/properdocs serve -f site/properdocs.yml
clean:
go clean
rm -f build/nsl build/nsl-agent build/nsl-linux-amd64 build/nsl-linux-arm64