-
Notifications
You must be signed in to change notification settings - Fork 152
Expand file tree
/
Copy pathMakefile
More file actions
290 lines (242 loc) · 10.9 KB
/
Copy pathMakefile
File metadata and controls
290 lines (242 loc) · 10.9 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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# Makefile for roborev development builds
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
LDFLAGS := -X go.kenn.io/roborev/internal/version.Version=$(VERSION)
ACP_TEST_COMMAND ?= $(abspath scripts/acp-agent)
ACP_TEST_ADAPTER ?= codex
ACP_TEST_ARGS ?=
ACP_TEST_DISABLE_MODE ?=
ACP_TEST_MODE ?=
ACP_TEST_MODEL ?=
CODEX_SKILL_EVAL_MODELS ?= gpt-5.6-sol
# Pinned golangci-lint version. Single source of truth: CI reads it via
# `make print-golangci-lint-version` (see .github/workflows/ci.yml), and
# `make lint`/`make lint-ci` refuse to run unless the local binary matches.
# A mismatched version can silently apply different formatting/fixes.
GOLANGCI_LINT_VERSION := 2.12.2
# Keep the golangci-lint cache per-checkout. The default user-global cache
# stores raw linter findings keyed by package content with absolute file
# paths from whichever checkout computed them. Post-processors (nolint,
# generated-file exclusion) re-read files at those paths on every run; if
# another worktree with identical content populated the cache and was later
# deleted, those reads fail and suppressed findings leak through as errors
# (golangci-lint #3502). A per-checkout cache dies with its checkout.
export GOLANGCI_LINT_CACHE := $(CURDIR)/.golangci-lint-cache
.PHONY: build web-build web-dev web-test-e2e web-assets-check web-embed web-restore web-release-check release-snapshot-check install clean test test-git-isolation test-codex-skill-eval test-integration test-acp-integration test-acp-integration-codex test-acp-integration-claude test-postgres test-all postgres-up postgres-down test-postgres-ci api-generate api-check lint lint-ci markdown markdown-ci check-golangci-lint print-golangci-lint-version check-actions check-renovate-config install-hooks docs-install docs-build docs-serve docs-check docs-screenshots docs-assets-branch docs-generated-assets-branch docs-deploy-staging docs-deploy
build: web-embed
@set -e; trap '$(MAKE) web-restore' EXIT; \
mkdir -p bin; \
go build -ldflags="$(LDFLAGS)" -o bin/roborev ./cmd/roborev
web-build:
cd web && bun run build
web-dev:
cd web && bun run dev:full
web-test-e2e:
cd web && bun run test:e2e
web-assets-check: web-build
cd web && bun run assets:check
web-embed: web-assets-check
cd web && bun run assets:embed
web-restore:
cd web && bun run assets:restore
web-release-check: web-embed
@set -e; trap '$(MAKE) web-restore' EXIT; \
ROBOREV_RUN_WEB_RELEASE_CHECK=1 CGO_ENABLED=0 \
go test ./internal/web -run '^TestEmbeddedRelease' -count=1
release-snapshot-check:
@set -e; trap 'cd web && bun run assets:restore' EXIT; \
goreleaser build --snapshot --clean --single-target; \
executables="$$(find dist -type f -name roborev)"; \
test "$$(printf '%s\n' "$$executables" | sed '/^$$/d' | wc -l | tr -d ' ')" = "1"; \
chmod u+x "$$executables"; \
"$$executables" verify-web-assets; \
goreleaser release --snapshot --clean; \
cd web && bun run assets:restore; \
cd .. && git diff --exit-code -- internal/web/dist
install:
@set -e; $(MAKE) web-embed; trap '$(MAKE) web-restore' EXIT; \
if [ -z "$(HOME)" ]; then echo "error: HOME is not set" >&2; exit 1; fi; \
mkdir -p "$(HOME)/.local/bin"; \
go build -ldflags="$(LDFLAGS)" -o "$(HOME)/.local/bin/roborev" ./cmd/roborev; \
echo "Installed to ~/.local/bin/roborev"
clean:
rm -rf bin/
docs-install:
cd docs && uv sync --frozen --no-dev
docs-build:
cd docs && uv run --frozen bash ./vercel-build.sh
docs-serve:
cd docs && bash assets/hydrate-assets.sh && uv run bash ./zensical-docs.sh serve
docs-check:
bash scripts/check-docs.sh
markdown:
cd docs && uv run --frozen python scripts/format_markdown.py
markdown-ci:
cd docs && uv run --frozen python -m unittest scripts/test_format_markdown.py
cd docs && uv run --frozen python scripts/format_markdown.py --check
docs-screenshots:
bash docs/screenshots/screenshot-all.sh
docs-assets-branch:
bash docs/assets/update-static-assets-branch.sh
docs-generated-assets-branch:
bash docs/screenshots/update-generated-assets-branch.sh
docs-deploy-staging:
vercel deploy docs
docs-deploy:
vercel deploy docs --prod
# Regenerate the checked-in OpenAPI document and public Go client.
api-generate:
go generate ./pkg/client/generated
cd web && bun run generate
api-check:
@set -e; tmp="$$(mktemp -d)"; trap 'chmod -R u+w "$$tmp"; rm -rf "$$tmp"' EXIT; \
mkdir -p "$$tmp/pkg/client/generated"; \
cp pkg/client/generated/config.yaml "$$tmp/pkg/client/generated/config.yaml"; \
go run ./internal/daemon_client/openapi_generate -format yaml -o "$$tmp/pkg/client/openapi.yaml"; \
(cd "$$tmp/pkg/client/generated" && \
go run github.com/doordash-oss/oapi-codegen-dd/v3/cmd/oapi-codegen@v3.75.5 \
-config config.yaml ../openapi.yaml); \
diff -u pkg/client/openapi.yaml "$$tmp/pkg/client/openapi.yaml"; \
diff -ru --exclude=config.yaml --exclude=generate.go \
pkg/client/generated "$$tmp/pkg/client/generated"
cd web && bun run generate:check
# Unit tests only (excludes integration and postgres tests)
test:
go test ./...
test-git-isolation:
go test -run '^TestGitUsingTestPackagesUseIsolatedTestMain$$' .
test-codex-skill-eval:
ROBOREV_RUN_CODEX_SKILL_EVAL=1 ROBOREV_CODEX_SKILL_EVAL_MODELS="$(CODEX_SKILL_EVAL_MODELS)" go test -tags=codexeval ./internal/skills -run TestCodexSkillExplicitInvocation -count=1 -v
# Unit + slow integration tests (no postgres required)
test-integration:
go test -tags=integration ./...
# ACP adapter integration smoke test (opt-in external dependency)
# Usage:
# make test-acp-integration
# make test-acp-integration ACP_TEST_ADAPTER=claude
# make test-acp-integration ACP_TEST_COMMAND=codex-acp
# make test-acp-integration ACP_TEST_ARGS="--provider codex"
# make test-acp-integration ACP_TEST_DISABLE_MODE=1
# make test-acp-integration ACP_TEST_MODE=plan ACP_TEST_MODEL=gpt-5
test-acp-integration:
ROBOREV_RUN_ACP_INTEGRATION=1 \
ROBOREV_ACP_ADAPTER="$(ACP_TEST_ADAPTER)" \
ROBOREV_ACP_TEST_COMMAND="$(ACP_TEST_COMMAND)" \
ROBOREV_ACP_TEST_ARGS="$(ACP_TEST_ARGS)" \
ROBOREV_ACP_TEST_DISABLE_MODE="$(ACP_TEST_DISABLE_MODE)" \
ROBOREV_ACP_TEST_MODE="$(ACP_TEST_MODE)" \
ROBOREV_ACP_TEST_MODEL="$(ACP_TEST_MODEL)" \
go test -tags="integration acp" ./internal/agent -run TestACPReviewViaExternalAdapter -count=1 -v
test-acp-integration-codex:
@if [ "$(ACP_TEST_COMMAND)" = "$(abspath scripts/acp-agent)" ] && \
[ -z "$$ROBOREV_ACP_ADAPTER_COMMAND" ] && \
! command -v codex-acp >/dev/null 2>&1; then \
echo "error: codex-acp was not found on PATH."; \
echo ""; \
echo "Install it with:"; \
echo " npm install -g @zed-industries/codex-acp"; \
echo ""; \
echo "Or override the wrapper command:"; \
echo " make test-acp-integration-codex ACP_TEST_COMMAND=/path/to/your/acp-wrapper"; \
echo " export ROBOREV_ACP_ADAPTER_COMMAND=/path/to/your/acp-wrapper"; \
exit 127; \
fi
@$(MAKE) test-acp-integration ACP_TEST_ADAPTER=codex ACP_TEST_DISABLE_MODE=1
test-acp-integration-claude:
@if [ "$(ACP_TEST_COMMAND)" = "$(abspath scripts/acp-agent)" ] && \
[ -z "$$ROBOREV_ACP_ADAPTER_COMMAND" ] && \
! command -v claude-agent-acp >/dev/null 2>&1; then \
echo "error: claude-agent-acp was not found on PATH."; \
echo ""; \
echo "Install it with:"; \
echo " npm install -g @zed-industries/claude-agent-acp"; \
echo ""; \
echo "Then rerun this target."; \
echo ""; \
echo "Or override the wrapper command:"; \
echo " make test-acp-integration-claude ACP_TEST_COMMAND=/path/to/your/acp-wrapper"; \
echo " export ROBOREV_ACP_ADAPTER_COMMAND=/path/to/your/acp-wrapper"; \
exit 127; \
fi
@$(MAKE) test-acp-integration ACP_TEST_ADAPTER=claude ACP_TEST_DISABLE_MODE=1
test-acp-integration-gemini:
@if [ "$(ACP_TEST_COMMAND)" = "$(abspath scripts/acp-agent)" ] && \
[ -z "$$ROBOREV_ACP_ADAPTER_COMMAND" ] && \
! command -v gemini >/dev/null 2>&1; then \
echo "error: gemini was not found on PATH."; \
echo ""; \
echo "Install it with:"; \
echo " npm install -g @google/gemini-cli"; \
echo ""; \
echo "Then rerun this target."; \
echo ""; \
echo "Or override the wrapper command:"; \
echo " make test-acp-integration-gemini ACP_TEST_COMMAND=/path/to/your/acp-wrapper"; \
echo " export ROBOREV_ACP_ADAPTER_COMMAND=/path/to/your/acp-wrapper"; \
exit 127; \
fi
@$(MAKE) test-acp-integration ACP_TEST_ADAPTER=gemini ACP_TEST_DISABLE_MODE=1
# Start postgres for postgres tests
postgres-up:
docker compose -f docker-compose.test.yml up -d --wait
# Stop postgres
postgres-down:
docker compose -f docker-compose.test.yml down
# Postgres tests (requires postgres running)
test-postgres: postgres-up
@echo "Waiting for postgres to be ready..."
@sleep 2
TEST_POSTGRES_URL="postgres://roborev_test:roborev_test_password@localhost:5433/roborev_test" \
go test -tags=postgres -v ./internal/storage/... -run Integration
# Run all tests (unit + integration + postgres)
test-all: test-integration test-postgres
# Lint Go code and auto-fix where possible (local development)
# Verify golangci-lint is installed and exactly matches the pinned version.
# Fails loudly on mismatch rather than letting a different version silently
# reformat files or report different findings than CI.
check-golangci-lint:
@if ! command -v golangci-lint >/dev/null 2>&1; then \
echo "golangci-lint not found. Install the pinned version:" >&2; \
echo " go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v$(GOLANGCI_LINT_VERSION)" >&2; \
exit 1; \
fi; \
have="$$(golangci-lint version --short 2>/dev/null)"; \
if [ "$$have" != "$(GOLANGCI_LINT_VERSION)" ]; then \
echo "Error: golangci-lint version mismatch (must match CI)." >&2; \
echo " found: $${have:-unknown}" >&2; \
echo " required: $(GOLANGCI_LINT_VERSION)" >&2; \
echo "Install the pinned version:" >&2; \
echo " go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v$(GOLANGCI_LINT_VERSION)" >&2; \
exit 1; \
fi
# Print the pinned golangci-lint version (consumed by CI to stay in lockstep).
print-golangci-lint-version:
@echo "$(GOLANGCI_LINT_VERSION)"
lint: check-golangci-lint
golangci-lint run --fix ./...
# Lint Go code without fixing (for CI)
lint-ci: check-golangci-lint
golangci-lint run ./...
# Validate Renovate config.
check-renovate-config:
@if ! command -v renovate-config-validator >/dev/null 2>&1; then \
echo "renovate-config-validator not found. Install with: mise use --global npm:renovate@latest" >&2; \
exit 1; \
fi
renovate-config-validator renovate.json
# Validate GitHub Actions workflows.
check-actions:
@if ! command -v actionlint >/dev/null 2>&1; then \
echo "actionlint not found. Install with: go install github.com/rhysd/actionlint/cmd/actionlint@latest" >&2; \
exit 1; \
fi
actionlint
# Install pre-commit hooks via prek.
install-hooks:
@if ! command -v prek >/dev/null 2>&1; then \
echo "prek not found. Install with: brew install prek" >&2; \
exit 1; \
fi
prek install
# CI target: run postgres tests without managing docker (assumes postgres is running)
test-postgres-ci:
go test -tags=postgres -v ./internal/storage/... -run Integration