forked from gastownhall/gastown
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
167 lines (153 loc) · 7.51 KB
/
Makefile
File metadata and controls
167 lines (153 loc) · 7.51 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
.PHONY: build desktop-build desktop-run install safe-install check-forward-only clean test test-e2e-container check-up-to-date
BINARY := gt
BINARY_DESKTOP := gt-desktop
BUILD_DIR := .
INSTALL_DIR := $(HOME)/.local/bin
E2E_IMAGE ?= gastown-test
E2E_BUILD_FLAGS ?=
E2E_RUN_FLAGS ?= --rm
E2E_BUILD_RETRIES ?= 1
E2E_RUN_RETRIES ?= 1
# Get version info for ldflags
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
BUILD_TIME := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
LDFLAGS := -s -w \
-X github.com/steveyegge/gastown/internal/cmd.Version=$(VERSION) \
-X github.com/steveyegge/gastown/internal/cmd.Commit=$(COMMIT) \
-X github.com/steveyegge/gastown/internal/cmd.BuildTime=$(BUILD_TIME) \
-X github.com/steveyegge/gastown/internal/cmd.BuiltProperly=1
# ICU4C detection for macOS (required by go-icu-regex transitive dependency).
# Homebrew installs icu4c as a keg-only package, so headers/libs aren't on the
# default search path. Auto-detect the prefix and export CGo flags.
ifeq ($(shell uname),Darwin)
ICU_PREFIX := $(shell brew --prefix icu4c 2>/dev/null)
ifneq ($(ICU_PREFIX),)
export CGO_CPPFLAGS += -I$(ICU_PREFIX)/include
export CGO_LDFLAGS += -L$(ICU_PREFIX)/lib
endif
endif
build:
go build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY)-proxy-server ./cmd/gt-proxy-server
go build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY)-proxy-client ./cmd/gt-proxy-client
go build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY) ./cmd/gt
desktop-build:
go build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_DESKTOP) ./cmd/gt-desktop
desktop-run:
go run ./cmd/gt-desktop
check-up-to-date:
ifndef SKIP_UPDATE_CHECK
@# Skip check on detached HEAD (tag checkouts, CI builds)
@if ! git symbolic-ref HEAD >/dev/null 2>&1; then exit 0; fi
@# Use the current branch's tracking ref (works for main, carry/operational, etc.)
@UPSTREAM=$$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null); \
if [ -z "$$UPSTREAM" ]; then \
echo "Warning: no upstream tracking branch set, skipping update check"; \
exit 0; \
fi; \
REMOTE_NAME=$$(echo "$$UPSTREAM" | cut -d/ -f1); \
REMOTE_BRANCH=$$(echo "$$UPSTREAM" | cut -d/ -f2-); \
git fetch "$$REMOTE_NAME" "$$REMOTE_BRANCH" --quiet 2>/dev/null || true; \
LOCAL=$$(git rev-parse HEAD 2>/dev/null); \
REMOTE=$$(git rev-parse "$$UPSTREAM" 2>/dev/null); \
if [ -n "$$REMOTE" ] && [ "$$LOCAL" != "$$REMOTE" ]; then \
echo "ERROR: Local branch is not up to date with $$UPSTREAM"; \
echo " Local: $$(git rev-parse --short HEAD)"; \
echo " Remote: $$(git rev-parse --short $$UPSTREAM)"; \
echo "Run 'git pull' first, or use SKIP_UPDATE_CHECK=1 to override"; \
exit 1; \
fi
endif
# check-forward-only: Ensure HEAD is a descendant of the currently installed binary's commit.
# Prevents rebuilding to an older or diverged commit, which caused a crash loop where
# the replaced binary broke session startup hooks → witness respawned → loop every 1-2 min.
check-forward-only:
ifndef SKIP_FORWARD_CHECK
@BINARY_COMMIT=$$($(INSTALL_DIR)/$(BINARY) version --verbose 2>/dev/null | grep -o '@[a-f0-9]*' | head -1 | tr -d '@'); \
if [ -n "$$BINARY_COMMIT" ] && [ "$$BINARY_COMMIT" != "unknown" ]; then \
HEAD_COMMIT=$$(git rev-parse HEAD 2>/dev/null); \
if [ "$$BINARY_COMMIT" = "$$HEAD_COMMIT" ] || [ "$$(git rev-parse --short HEAD)" = "$$BINARY_COMMIT" ]; then \
echo "Binary is already at HEAD, nothing to do"; \
exit 1; \
fi; \
if ! git merge-base --is-ancestor "$$BINARY_COMMIT" HEAD 2>/dev/null; then \
echo "ERROR: HEAD ($$(git rev-parse --short HEAD)) is NOT a descendant of installed binary ($$BINARY_COMMIT)"; \
echo "This would be a DOWNGRADE. Refusing to rebuild."; \
echo "Use SKIP_FORWARD_CHECK=1 to override (dangerous)."; \
exit 1; \
fi; \
echo "Forward-only check passed: $$BINARY_COMMIT → $$(git rev-parse --short HEAD)"; \
else \
echo "Warning: cannot determine installed binary commit, skipping forward check"; \
fi
endif
install: check-up-to-date build
@mkdir -p $(INSTALL_DIR)
@rm -f $(INSTALL_DIR)/$(BINARY)
@cp $(BUILD_DIR)/$(BINARY) $(INSTALL_DIR)/$(BINARY)
@# Nuke any stale go-install binaries that shadow the canonical location
@for bad in $(HOME)/go/bin/$(BINARY) $(HOME)/bin/$(BINARY); do \
if [ -f "$$bad" ]; then \
echo "Removing stale $$bad (use make install, not go install)"; \
rm -f "$$bad"; \
fi; \
done
@echo "Installed $(BINARY) to $(INSTALL_DIR)/$(BINARY)"
@# Restart daemon so it picks up the new binary.
@# A stale daemon is a recurring source of bugs (wrong session prefixes, etc.)
@if $(INSTALL_DIR)/$(BINARY) daemon status >/dev/null 2>&1; then \
echo "Restarting daemon to pick up new binary..."; \
$(INSTALL_DIR)/$(BINARY) daemon stop >/dev/null 2>&1 || true; \
sleep 1; \
$(INSTALL_DIR)/$(BINARY) daemon start >/dev/null 2>&1 && \
echo "Daemon restarted." || \
echo "Warning: daemon restart failed (start manually with: gt daemon start)"; \
fi
@# Sync plugins from build repo to town runtime directories.
@# Prevents drift when plugin fixes merge but runtime dirs are stale.
@$(INSTALL_DIR)/$(BINARY) plugin sync --source $(CURDIR)/plugins 2>/dev/null && \
echo "Plugins synced." || true
# safe-install: Replace binary WITHOUT restarting daemon or killing sessions.
# Use this for automated rebuilds (e.g., rebuild-gt plugin). Sessions pick up
# the new binary on their next natural cycle/handoff.
safe-install: check-up-to-date check-forward-only build
@mkdir -p $(INSTALL_DIR)
@# Atomic-ish replace: copy to temp then move (move is atomic on same filesystem)
@cp $(BUILD_DIR)/$(BINARY) $(INSTALL_DIR)/$(BINARY).new
@mv $(INSTALL_DIR)/$(BINARY).new $(INSTALL_DIR)/$(BINARY)
@# Nuke any stale go-install binaries that shadow the canonical location
@for bad in $(HOME)/go/bin/$(BINARY) $(HOME)/bin/$(BINARY); do \
if [ -f "$$bad" ]; then \
echo "Removing stale $$bad (use make install, not go install)"; \
rm -f "$$bad"; \
fi; \
done
@echo "Installed $(BINARY) to $(INSTALL_DIR)/$(BINARY) (daemon NOT restarted)"
@echo "Sessions will pick up new binary on next cycle."
clean:
rm -f $(BUILD_DIR)/$(BINARY)
test:
go test ./...
# Run e2e tests in isolated container (the only supported way to run them)
test-e2e-container:
ifeq ($(OS),Windows_NT)
@powershell -NoProfile -Command "$$max=$(E2E_BUILD_RETRIES); for($$i=1; $$i -le $$max; $$i++){ docker build $(E2E_BUILD_FLAGS) -f Dockerfile.e2e -t $(E2E_IMAGE) .; if($$LASTEXITCODE -eq 0){ break }; if($$i -eq $$max){ exit 1 }; Write-Host ('docker build failed (attempt ' + $$i + '), retrying...'); Start-Sleep -Seconds 2 }"
@powershell -NoProfile -Command "$$max=$(E2E_RUN_RETRIES); for($$i=1; $$i -le $$max; $$i++){ docker run $(E2E_RUN_FLAGS) $(E2E_IMAGE); if($$LASTEXITCODE -eq 0){ break }; if($$i -eq $$max){ exit 1 }; Write-Host ('docker run failed (attempt ' + $$i + '), retrying...'); Start-Sleep -Seconds 2 }"
else
@attempt=1; \
while [ $$attempt -le $(E2E_BUILD_RETRIES) ]; do \
docker build $(E2E_BUILD_FLAGS) -f Dockerfile.e2e -t $(E2E_IMAGE) . && break; \
if [ $$attempt -eq $(E2E_BUILD_RETRIES) ]; then exit 1; fi; \
echo "docker build failed (attempt $$attempt), retrying..."; \
attempt=$$((attempt+1)); \
sleep 2; \
done
@attempt=1; \
while [ $$attempt -le $(E2E_RUN_RETRIES) ]; do \
docker run $(E2E_RUN_FLAGS) $(E2E_IMAGE) && break; \
if [ $$attempt -eq $(E2E_RUN_RETRIES) ]; then exit 1; fi; \
echo "docker run failed (attempt $$attempt), retrying..."; \
attempt=$$((attempt+1)); \
sleep 2; \
done
endif