GOPATH ?= $(HOME)/.local/share/go WAILS := $(GOPATH)/bin/wails SERVER := root@178.20.40.99 RELEASES_DIR := /opt/vpnem/data/releases export GOPATH .PHONY: all server client-linux client-windows installer vpnemctl test test-control test-hy2 clean deploy release release-assets release-verify install-ruleset-timer all: server client-linux # --- Server --- server: go build -o build/vpnem-server ./cmd/server # --- Client --- client-linux: cd cmd/client && $(WAILS) build -platform linux/amd64 -o vpnem -tags with_gvisor,with_utls,with_quic cp cmd/client/build/bin/vpnem build/vpnem-linux-amd64 client-windows: cd cmd/client && CC=x86_64-w64-mingw32-gcc $(WAILS) build -platform windows/amd64 -o vpnem.exe -tags with_gvisor,with_utls,with_quic cp cmd/client/build/bin/vpnem.exe build/vpnem-windows-amd64.exe installer: CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "-H windowsgui" -o build/vpnem-installer.exe ./cmd/installer vpnemctl: go build -o build/vpnemctl ./cmd/vpnemctl # --- Test --- test: go test ./... -v test-control: go test ./internal/control -v test-hy2: go test ./internal/config/ -run TestBuildConfigHysteria2 -v go test ./internal/control/ -run TestHysteria2Bundle -v .PHONY: test-multi test-multi: go test ./internal/config/ -run "TestBuildConfig(VLESSReality|Hysteria2|SplitRealityHysteria2)" -v go test ./internal/control/ -run "Test(RenderRuntimeBundleReality|Hysteria2Bundle|RenderRuntimeBundleMultiProtocol)" -v go test ./internal/sync/ -run "TestCatalogToServers(MultiProtocolNode)?" -v # --- Deploy: server code only --- deploy: rsync -avz --exclude '.git' --exclude 'build' --exclude '*.srs' --exclude '.claude' --exclude '.env' --exclude 'VPNUI_ADMIN_TOKEN.txt' \ ./ $(SERVER):/opt/vpnem/ ssh $(SERVER) "cd /opt/vpnem && docker compose up -d --build" @echo "Verify: curl https://vpn.em-sysadmin.xyz/health" # --- Release: build all + deploy binaries + bump version --- release-assets: client-linux client-windows installer rm -f build/vpnem-linux-amd64 cp cmd/client/build/bin/vpnem build/vpnem-linux-amd64 test -f build/sing-box.exe test -f build/wintun.dll scp build/vpnem-linux-amd64 build/vpnem-windows-amd64.exe build/vpnem-installer.exe build/sing-box.exe build/wintun.dll \ $(SERVER):$(RELEASES_DIR)/ scp data/version.json $(SERVER):/opt/vpnem/data/version.json release-verify: @echo "" @echo "Verifying health..." @ok=0; \ for attempt in 1 2 3 4 5; do \ if curl -fSs https://vpn.em-sysadmin.xyz/health; then \ ok=1; \ break; \ fi; \ echo "retry $$attempt for /health"; \ sleep 2; \ done; \ if [ "$$ok" -ne 1 ]; then \ echo "release verify failed for /health"; \ exit 1; \ fi @echo "" @echo "Verifying version..." @ok=0; \ for attempt in 1 2 3 4 5; do \ if curl -fSs https://vpn.em-sysadmin.xyz/api/v1/version; then \ ok=1; \ break; \ fi; \ echo "retry $$attempt for /api/v1/version"; \ sleep 2; \ done; \ if [ "$$ok" -ne 1 ]; then \ echo "release verify failed for /api/v1/version"; \ exit 1; \ fi @echo "" @echo "Verifying release assets..." @for url in \ https://vpn.em-sysadmin.xyz/releases/vpnem-windows-amd64.exe \ https://vpn.em-sysadmin.xyz/releases/vpnem-installer.exe \ https://vpn.em-sysadmin.xyz/releases/sing-box.exe \ https://vpn.em-sysadmin.xyz/releases/wintun.dll; do \ ok=0; \ for attempt in 1 2 3 4 5; do \ if curl -fSs -I "$$url" | sed -n '1,5p'; then \ ok=1; \ break; \ fi; \ echo "retry $$attempt for $$url"; \ sleep 2; \ done; \ if [ "$$ok" -ne 1 ]; then \ echo "release verify failed for $$url"; \ exit 1; \ fi; \ echo ""; \ done release: release-assets rsync -avz --exclude '.git' --exclude 'build' --exclude '*.srs' --exclude '.claude' --exclude '.env' --exclude 'VPNUI_ADMIN_TOKEN.txt' \ ./ $(SERVER):/opt/vpnem/ ssh $(SERVER) "cd /opt/vpnem && docker compose up -d --build" $(MAKE) release-verify @echo "Release deployed." install-ruleset-timer: chmod +x scripts/install-ruleset-timer.sh rsync -avz deploy/systemd/vpnem-rulesets-update.service deploy/systemd/vpnem-rulesets-update.timer scripts/install-ruleset-timer.sh \ $(SERVER):/opt/vpnem/ ssh $(SERVER) "cd /opt/vpnem && ./scripts/install-ruleset-timer.sh" # --- Clean --- clean: rm -rf build/ cmd/client/build/