# Warp — build, test and lint. # # Everything Go lives in ./server; the frontend packages (apps/*) get their # own targets as they are created. SHELL := /bin/sh GO ?= go BIN_DIR := bin BINARY := warp SERVER_DIR := server COMPLEMENT_IMAGE ?= complement-warp VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo 0.0.0-dev) COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown) DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ) PKG := github.com/dariuszjaniak/warp/server/internal/buildinfo LDFLAGS := -X $(PKG).Version=$(VERSION) -X $(PKG).Commit=$(COMMIT) -X $(PKG).BuildDate=$(DATE) # Windows builds need the .exe suffix for `make run` to work from MSYS. ifeq ($(OS),Windows_NT) EXE := .exe else EXE := endif .DEFAULT_GOAL := build .PHONY: help help: ## List the targets @grep -hE '^[a-zA-Z_-]+:.*?## ' $(MAKEFILE_LIST) | \ awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-16s\033[0m %s\n", $$1, $$2}' .PHONY: build build: ## Build the warp binary into bin/ cd $(SERVER_DIR) && $(GO) build -ldflags "$(LDFLAGS)" -o ../$(BIN_DIR)/$(BINARY)$(EXE) ./cmd/warp .PHONY: run run: build ## Build and run the server ./$(BIN_DIR)/$(BINARY)$(EXE) serve .PHONY: test test: ## Run the unit tests (sqlite only) cd $(SERVER_DIR) && $(GO) test ./... .PHONY: test-race test-race: ## Run the tests with the race detector (needs cgo) cd $(SERVER_DIR) && CGO_ENABLED=1 $(GO) test -race ./... .PHONY: test-postgres test-postgres: ## Run the storage tests against PostgreSQL too @test -n "$(WARP_TEST_POSTGRES_DSN)" || \ { echo "set WARP_TEST_POSTGRES_DSN, e.g. postgres://warp:warp@localhost/warp_test?sslmode=disable"; exit 1; } cd $(SERVER_DIR) && WARP_TEST_POSTGRES_DSN="$(WARP_TEST_POSTGRES_DSN)" $(GO) test ./internal/storage/... .PHONY: cover cover: ## Run the tests and write coverage.out / coverage.html cd $(SERVER_DIR) && $(GO) test -coverprofile=../coverage.out -covermode=count ./... $(GO) tool cover -html=coverage.out -o coverage.html @echo "wrote coverage.html" .PHONY: fmt fmt: ## Format the Go code cd $(SERVER_DIR) && $(GO) fmt ./... .PHONY: vet vet: ## Run go vet cd $(SERVER_DIR) && $(GO) vet ./... .PHONY: lint lint: ## Run golangci-lint cd $(SERVER_DIR) && golangci-lint run .PHONY: tidy tidy: ## Tidy the Go module files cd $(SERVER_DIR) && $(GO) mod tidy .PHONY: check check: vet test ## What CI runs on every push (minus the linter) .PHONY: generate-keys generate-keys: build ## Create the ed25519 signing key ./$(BIN_DIR)/$(BINARY)$(EXE) generate-keys .PHONY: migrate migrate: build ## Apply pending database migrations ./$(BIN_DIR)/$(BINARY)$(EXE) migrate .PHONY: create-account create-account: build ## Create an account: make create-account ACCOUNT=alice ARGS=--admin @test -n "$(ACCOUNT)" || { echo "set ACCOUNT, e.g. make create-account ACCOUNT=alice ARGS=--admin"; exit 1; } ./$(BIN_DIR)/$(BINARY)$(EXE) create-account --username "$(ACCOUNT)" $(ARGS) # --- Admin panel (apps/admin) ------------------------------------------- # The panel is optional and runs as its own process, warp-admin, which # serves the built frontend and proxies to the homeserver. PNPM ?= pnpm ADMIN_DIR := apps/admin ADMIN_IMAGE ?= warp-admin .PHONY: admin-deps admin-deps: ## Install the frontend dependencies (pnpm) $(PNPM) install --frozen-lockfile .PHONY: admin-web admin-web: ## Build the admin panel frontend into apps/admin/internal/panel/build/dist $(PNPM) --filter @warp/admin build .PHONY: admin admin: admin-web ## Build bin/warp-admin with the panel embedded cd $(ADMIN_DIR) && $(GO) build -ldflags "-X main.version=$(VERSION)" -o ../../$(BIN_DIR)/warp-admin$(EXE) ./cmd/warp-admin .PHONY: admin-run admin-run: admin ## Run warp-admin against http://localhost:8008 ./$(BIN_DIR)/warp-admin$(EXE) -homeserver http://localhost:8008 .PHONY: admin-dev admin-dev: ## Run the panel with hot reload on :5174, proxied to localhost:8008 $(PNPM) --filter @warp/admin dev .PHONY: admin-test admin-test: ## Typecheck the frontend and test warp-admin $(PNPM) -r typecheck cd $(ADMIN_DIR) && $(GO) vet ./... && $(GO) test ./... .PHONY: admin-docker admin-docker: ## Build the warp-admin container image docker build -t $(ADMIN_IMAGE):$(VERSION) -f $(ADMIN_DIR)/Dockerfile . # --- Web client (apps/web) -------------------------------------------- # Optional too: warp-web serves the built client and proxies its Matrix # requests to the homeserver. WEB_DIR := apps/web WEB_IMAGE ?= warp-web .PHONY: web-web web-web: ## Build the web client frontend into apps/web/client/build/dist $(PNPM) --filter @warp/web build .PHONY: web web: web-web ## Build bin/warp-web with the client embedded cd $(WEB_DIR) && $(GO) build -ldflags "-X main.version=$(VERSION)" -o ../../$(BIN_DIR)/warp-web$(EXE) ./cmd/warp-web .PHONY: web-run web-run: web ## Run warp-web against http://localhost:8008 ./$(BIN_DIR)/warp-web$(EXE) -homeserver http://localhost:8008 .PHONY: web-dev web-dev: ## Run the client with hot reload on :5175, proxied to localhost:8008 $(PNPM) --filter @warp/web dev .PHONY: web-test web-test: ## Typecheck the frontend and test warp-web $(PNPM) -r typecheck cd $(WEB_DIR) && $(GO) vet ./... && $(GO) test ./... .PHONY: web-docker web-docker: ## Build the warp-web container image docker build -t $(WEB_IMAGE):$(VERSION) -f $(WEB_DIR)/Dockerfile . # --- Desktop client (apps/desktop) ---------------------------------------- # The web client in a native window (Wails v3). It embeds the same build as # warp-web, so `make desktop` builds the web frontend first. DESKTOP_DIR := apps/desktop # Windows builds are GUI programs: no console window behind the app. ifeq ($(OS),Windows_NT) DESKTOP_LDFLAGS := -H windowsgui else DESKTOP_LDFLAGS := endif .PHONY: desktop desktop: web-web ## Build bin/warp-desktop with the web client embedded cd $(DESKTOP_DIR) && $(GO) build -tags production -ldflags "-X main.version=$(VERSION) $(DESKTOP_LDFLAGS)" -o ../../$(BIN_DIR)/warp-desktop$(EXE) ./cmd/warp-desktop .PHONY: desktop-run desktop-run: web-web ## Run the desktop client with the developer tools on cd $(DESKTOP_DIR) && $(GO) run ./cmd/warp-desktop $(ARGS) .PHONY: desktop-test desktop-test: ## Vet and test the desktop client's Go code cd $(DESKTOP_DIR) && $(GO) vet ./... && $(GO) test ./... # Packaging. The inputs are in apps/desktop/build. The wails3 CLI, at the # version go.mod pins, makes the icons and the Windows .syso and builds the # Linux packages; `go run` fetches it, so there is nothing to install. # DESKTOP_VERSION is the numeric version the OS sees (Windows version info, # Info.plist, package version); `-version` still prints $(VERSION). WAILS3 ?= $(GO) run github.com/wailsapp/wails/v3/cmd/wails3@v3.0.0-beta.27 DESKTOP_VERSION ?= 0.1.0 DESKTOP_MAINTAINER ?= $(shell git config user.name) <$(shell git config user.email)> DESKTOP_FORMATS ?= deb rpm archlinux DESKTOP_GEN := $(BIN_DIR)/desktop-build DESKTOP_APP := $(BIN_DIR)/Warp.app # The .syso files are committed, so `make desktop` needs none of this; run # it after changing the icon, the manifest or DESKTOP_VERSION. .PHONY: desktop-resources desktop-resources: ## Regenerate the desktop icons and the Windows .syso files mkdir -p $(DESKTOP_GEN) cd $(DESKTOP_DIR) && $(WAILS3) generate icons -input build/appicon.png -sizes 256,128,64 \ -windowsfilename ../../$(DESKTOP_GEN)/tile.ico -macfilename build/darwin/icons.icns cd $(DESKTOP_DIR) && $(GO) run build/windows/mkico.go -small build/windows/favicon.ico \ -large ../../$(DESKTOP_GEN)/tile.ico -out build/windows/icon.ico sed 's/{{VERSION}}/$(DESKTOP_VERSION)/g' $(DESKTOP_DIR)/build/windows/info.json > $(DESKTOP_GEN)/info.json sed 's/{{VERSION}}/$(DESKTOP_VERSION)/g' $(DESKTOP_DIR)/build/windows/warp-desktop.exe.manifest > $(DESKTOP_GEN)/warp-desktop.exe.manifest cd $(DESKTOP_DIR) && for arch in amd64 arm64; do \ $(WAILS3) generate syso -arch $$arch -icon build/windows/icon.ico \ -manifest ../../$(DESKTOP_GEN)/warp-desktop.exe.manifest -info ../../$(DESKTOP_GEN)/info.json \ -out cmd/warp-desktop/rsrc_windows_$$arch.syso || exit 1; \ done # Run on a Mac: the binary needs cgo. Ad-hoc signed, so it runs on the # machine that built it; distributing it needs a Developer ID and notarizing. .PHONY: desktop-macos desktop-macos: desktop ## Build bin/Warp.app (on macOS) @test "$$(uname -s)" = Darwin || { echo "desktop-macos runs on macOS"; exit 1; } rm -rf $(DESKTOP_APP) mkdir -p $(DESKTOP_APP)/Contents/MacOS $(DESKTOP_APP)/Contents/Resources cp $(BIN_DIR)/warp-desktop $(DESKTOP_APP)/Contents/MacOS/ cp $(DESKTOP_DIR)/build/darwin/icons.icns $(DESKTOP_APP)/Contents/Resources/ sed 's/{{VERSION}}/$(DESKTOP_VERSION)/g' $(DESKTOP_DIR)/build/darwin/Info.plist > $(DESKTOP_APP)/Contents/Info.plist codesign --force --deep --sign - $(DESKTOP_APP) # Run on Linux: the binary needs cgo. Packages land in bin/. .PHONY: desktop-linux desktop-linux: desktop ## Build Linux packages of the desktop client (on Linux) @test "$$(uname -s)" = Linux || { echo "desktop-linux runs on Linux"; exit 1; } cd $(DESKTOP_DIR) && for format in $(DESKTOP_FORMATS); do \ VERSION=$(DESKTOP_VERSION) GOARCH=$$($(GO) env GOARCH) MAINTAINER="$(DESKTOP_MAINTAINER)" \ $(WAILS3) tool package -name warp-desktop -format $$format \ -config build/linux/nfpm.yaml -out ../../$(BIN_DIR) || exit 1; \ done .PHONY: complement-image complement-image: ## Build the Complement homeserver image docker build -t $(COMPLEMENT_IMAGE) -f $(SERVER_DIR)/test/complement/Dockerfile . .PHONY: complement complement: ## Run the Complement C-S subset (federation off) bash $(SERVER_DIR)/test/complement/run.sh .PHONY: complement-federation complement-federation: ## Run the Complement federation subset COMPLEMENT_PROFILE=federation bash $(SERVER_DIR)/test/complement/run.sh .PHONY: docker docker: ## Build the container image docker build -t warp:$(VERSION) . .PHONY: loadtest loadtest: ## Load a test server: make loadtest ARGS="-url http://localhost:8008 -users 50" cd $(SERVER_DIR) && $(GO) run ./cmd/warp-loadtest $(ARGS) .PHONY: compose-up compose-up: ## Run Warp, PostgreSQL and the observability stack with Docker Compose cd deploy/compose && docker compose --profile observability up -d --build .PHONY: helm-lint helm-lint: ## Lint and render the Helm chart (needs helm) helm lint deploy/helm/warp helm template warp deploy/helm/warp > /dev/null .PHONY: clean clean: ## Remove build output rm -rf $(BIN_DIR) coverage.out coverage.html