-
Notifications
You must be signed in to change notification settings - Fork 265
Expand file tree
/
Copy pathMakefile
More file actions
190 lines (166 loc) · 7.78 KB
/
Makefile
File metadata and controls
190 lines (166 loc) · 7.78 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
.PHONY: build run install clean dev release-local test fmt lint ci css tools css-verify test-web test-web-unit test-web-e2e test-web-install
BINARY_NAME=agent-deck
BUILD_DIR=./build
VERSION=$(shell git describe --tags --always --dirty 2>/dev/null | sed 's/^v//' || echo "dev")
LDFLAGS=-ldflags "-X main.Version=$(VERSION)"
# Tailwind v4 standalone CLI (PERF-01)
TAILWIND_VERSION=v4.2.2
TAILWIND_BIN=$(HOME)/.local/bin/tailwindcss
# Pin Go toolchain to 1.24.0 to prevent Go 1.25+ runtime regression on macOS
export GOTOOLCHAIN=go1.24.0
# Build the binary (requires compiled CSS via `make css`)
build: css
go build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME) ./cmd/agent-deck
# Download the pinned Tailwind v4 standalone CLI binary if missing or wrong version
tools:
@mkdir -p $(HOME)/.local/bin
@OS=$$(uname -s | tr '[:upper:]' '[:lower:]'); \
ARCH=$$(uname -m); \
case "$$OS-$$ARCH" in \
linux-x86_64) ASSET=tailwindcss-linux-x64 ;; \
linux-aarch64) ASSET=tailwindcss-linux-arm64 ;; \
darwin-arm64) ASSET=tailwindcss-macos-arm64 ;; \
darwin-x86_64) ASSET=tailwindcss-macos-x64 ;; \
*) echo "ERROR: unsupported host $$OS-$$ARCH for Tailwind binary" && exit 1 ;; \
esac; \
if [ -x "$(TAILWIND_BIN)" ] && "$(TAILWIND_BIN)" --help 2>&1 | grep -q "$(TAILWIND_VERSION)"; then \
echo "tailwindcss $(TAILWIND_VERSION) already installed at $(TAILWIND_BIN)"; \
else \
echo "Downloading tailwindcss $(TAILWIND_VERSION) ($$ASSET) ..."; \
curl -sSL -o "$(TAILWIND_BIN)" \
"https://github.com/tailwindlabs/tailwindcss/releases/download/$(TAILWIND_VERSION)/$$ASSET"; \
chmod +x "$(TAILWIND_BIN)"; \
echo "Installed: $$( "$(TAILWIND_BIN)" --help 2>&1 | head -1 )"; \
fi
# Compile Tailwind CSS (PERF-01 — replaces vendor/tailwind.js Play CDN runtime)
# Runs the brute-force diff gate (Pitfall #1 mitigation): generate twice and
# diff. Fails on any class present in brute-force output but missing from
# targeted globs unless explicitly allowlisted.
#
# Brute-force gate details:
# - The brute src CSS must be semantically identical to styles.src.css
# (same @theme, @variant dark, folded rules) so Tailwind can RECOGNISE
# tn-* / sp-* / dark:* utilities. Without those, the diff is meaningless.
# - Tailwind v4 resolves @source paths relative to the CSS source file's
# directory, so the brute src MUST live inside internal/web/static/.
# We copy styles.src.css to a hidden sibling and append a broader
# @source glob. Any class the broader scan picks up that the targeted
# scan missed will show up in the diff.
# - The hidden copy is removed on success AND failure (trap).
css: tools
@echo "==> Compiling Tailwind CSS (targeted globs)"
$(TAILWIND_BIN) -i ./internal/web/static/styles.src.css \
-o ./internal/web/static/styles.css \
--minify
@echo "==> Brute-force globbing diff (Pitfall #1 gate)"
@trap 'rm -f ./internal/web/static/.brute-tw.src.css' EXIT INT TERM; \
cp ./internal/web/static/styles.src.css ./internal/web/static/.brute-tw.src.css; \
printf '\n/* --- brute-force additional @source (Pitfall #1 gate) --- */\n@source "./**/*.{js,mjs,html}";\n@source not "./vendor/**";\n@source not "./chart.umd.min.js";\n@source not "./sw.js";\n' \
>> ./internal/web/static/.brute-tw.src.css; \
$(TAILWIND_BIN) -i ./internal/web/static/.brute-tw.src.css \
-o /tmp/agent-deck-tw-brute.css \
--minify; \
rm -f ./internal/web/static/.brute-tw.src.css; \
if ! diff -q ./internal/web/static/styles.css /tmp/agent-deck-tw-brute.css >/dev/null 2>&1; then \
if [ -f ./internal/web/static/.tailwind-allowlist.txt ]; then \
echo "Brute-force diff non-empty but allowlist file present; review manually."; \
else \
echo "ERROR: brute-force @source diff non-empty (Pitfall #1). Add classes to internal/web/static/.tailwind-allowlist.txt or fix @source globs in styles.src.css." >&2; \
diff ./internal/web/static/styles.css /tmp/agent-deck-tw-brute.css | head -40; \
exit 1; \
fi; \
fi
@SIZE=$$(gzip -c ./internal/web/static/styles.css | wc -c); \
echo "==> Compiled styles.css gzipped size: $$SIZE bytes"; \
if [ "$$SIZE" -gt 10240 ]; then \
echo "ERROR: gzipped size $$SIZE exceeds 10240-byte sanity ceiling"; \
exit 1; \
fi
# Drift gate: regenerate CSS and fail if committed file differs from generated
css-verify: css
@git diff --exit-code -- ./internal/web/static/styles.css || \
(echo "ERROR: internal/web/static/styles.css drifted from generated output. Run 'make css' and commit." && exit 1)
# Run in development
run:
go run ./cmd/agent-deck
# Install to /usr/local/bin (requires sudo)
install: build
sudo cp $(BUILD_DIR)/$(BINARY_NAME) /usr/local/bin/$(BINARY_NAME)
@echo "✅ Installed to /usr/local/bin/$(BINARY_NAME)"
@echo "Run 'agent-deck' to start"
# Install to user's local bin (no sudo required)
install-user: build
mkdir -p $(HOME)/.local/bin
cp $(BUILD_DIR)/$(BINARY_NAME) $(HOME)/.local/bin/$(BINARY_NAME)
@echo "✅ Installed to $(HOME)/.local/bin/$(BINARY_NAME)"
@echo "Make sure $(HOME)/.local/bin is in your PATH"
@echo "Run 'agent-deck' to start"
# Uninstall from /usr/local/bin
uninstall:
sudo rm -f /usr/local/bin/$(BINARY_NAME)
@echo "✅ Uninstalled $(BINARY_NAME)"
# Uninstall from user's local bin
uninstall-user:
rm -f $(HOME)/.local/bin/$(BINARY_NAME)
@echo "✅ Uninstalled $(BINARY_NAME)"
# Clean build artifacts
clean:
rm -rf $(BUILD_DIR)
go clean
# Development with auto-reload
dev:
@which air > /dev/null || go install github.com/air-verse/air@latest
$(shell go env GOPATH)/bin/air
# Run tests (with race detector)
test:
go test -race -v ./...
# Format code
fmt:
go fmt ./...
# Lint
lint:
@which golangci-lint > /dev/null || go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
golangci-lint run
# Run local CI checks (same as pre-push hook: lint + test + build in parallel)
ci:
@which lefthook > /dev/null || (echo "ERROR: lefthook not found. Run: brew install lefthook" && exit 1)
lefthook run pre-push --force --no-auto-install
# Local release using GoReleaser
# Prerequisites: brew install goreleaser
# Required env: GITHUB_TOKEN, HOMEBREW_TAP_GITHUB_TOKEN
release-local:
@echo "=== Pre-flight checks ==="
@which goreleaser > /dev/null || (echo "ERROR: goreleaser not found. Run: brew install goreleaser" && exit 1)
@test -n "$$GITHUB_TOKEN" || (echo "ERROR: GITHUB_TOKEN not set" && exit 1)
@test -n "$$HOMEBREW_TAP_GITHUB_TOKEN" || (echo "ERROR: HOMEBREW_TAP_GITHUB_TOKEN not set" && exit 1)
@TAG=$$(git describe --tags --exact-match 2>/dev/null) || (echo "ERROR: HEAD is not tagged. Run: git tag vX.Y.Z" && exit 1); \
CODE_VERSION=$$(grep 'var Version' cmd/agent-deck/main.go | sed 's/.*"\(.*\)".*/\1/'); \
TAG_VERSION=$${TAG#v}; \
if [ "$$TAG_VERSION" != "$$CODE_VERSION" ]; then \
echo "ERROR: Tag $$TAG ($$TAG_VERSION) != code Version $$CODE_VERSION"; \
exit 1; \
fi; \
echo "Version: $$CODE_VERSION"
@echo "=== Running tests ==="
go test -race ./...
@echo "=== Running GoReleaser ==="
goreleaser release --clean
@echo "=== Release complete ==="
@echo "Verify: gh release view $$(git describe --tags --exact-match) --repo asheshgoplani/agent-deck"
# Web UI test targets
# Vitest (unit) + Playwright (e2e + screenshot regression). Both run against
# the in-memory web fixture binary at tests/web/fixtures/cmd/web-fixture/.
# See documentation/webui-overhaul-plan.md for the parity strategy.
# One-shot install for fresh clones / CI. Installs npm deps + chromium browser.
test-web-install:
cd tests/web && npm install --no-audit --no-fund
cd tests/web && npx playwright install --with-deps chromium
# Unit tests (Vitest, jsdom). Fast (<5s on warm cache).
test-web-unit:
cd tests/web && npm run test:unit
# End-to-end tests (Playwright). Builds the fixture binary, boots it,
# runs every spec including screenshot regression.
test-web-e2e:
cd tests/web && npm run test:e2e
# Full suite (default): unit + e2e.
test-web: test-web-unit test-web-e2e