Files
Warp/Makefile
T
tajniak81andClaude Opus 5.5 3356089c13 Android app (apps/mobile) with Flutter
apps/mobile is a Matrix client for Android on the famedly Matrix Dart SDK,
with vodozemac (compiled from Rust during the build) for end-to-end
encryption. It speaks the plain Client-Server API and uses the web
client's design tokens, fonts and symbol.

- Sign in by server name (.well-known), homeserver address or full user ID;
  sign up with the dummy and registration token stages. Sessions survive
  restarts: SQLite in private storage, credentials also in the Keystore,
  both excluded from backups and device transfers.
- Room list with unread and mention counts, invites, search and filters.
  Timeline with grouping, day separators, notices, history on scroll,
  links, images and files (authenticated media). Sending text, photos,
  camera shots and files, with Sending/Sent/Read/Not sent and Retry.
  Typing, receipts, deleting. New rooms and DMs, encrypted by default;
  joining by address; room info with members, invite, rename, topic,
  notification level, leave.
- Encryption: one-step setup behind a recovery key, verifying a new session
  with the recovery key (restoring the backup) or another session, emoji
  verification of people and sessions, reset. Undecryptable messages say
  why. Session list with verify and sign out.
- Notifications while running, and push through UnifiedPush (no Firebase):
  the distributor's endpoint becomes an event_id_only pusher, the gateway
  is discovered, and a push starts the app headless to fetch, decrypt and
  show the event.

Make targets: mobile (release APKs per ABI into bin/), mobile-run,
mobile-test. Kotlin incremental compilation is off (Windows, project and
pub cache on different drives), and Tink's JVM artifact is excluded in
favour of tink-android.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 22:45:06 +02:00

294 lines
11 KiB
Makefile

# 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
# The Android app. Needs Flutter, the Android SDK, and Rust with the Android
# targets (flutter_vodozemac compiles the crypto from source); see
# apps/mobile/README.md. The APKs land in bin/.
FLUTTER ?= flutter
MOBILE_DIR := apps/mobile
MOBILE_APKS := $(MOBILE_DIR)/build/app/outputs/flutter-apk
.PHONY: mobile
mobile: ## Build the Android app (release APKs, one per ABI, into bin/)
cd $(MOBILE_DIR) && $(FLUTTER) build apk --release --split-per-abi
mkdir -p $(BIN_DIR)
for abi in arm64-v8a armeabi-v7a x86_64; do \
cp $(MOBILE_APKS)/app-$$abi-release.apk $(BIN_DIR)/warp-android-$$abi.apk || exit 1; \
done
.PHONY: mobile-run
mobile-run: ## Run the Android app on a connected device or emulator
cd $(MOBILE_DIR) && $(FLUTTER) run $(ARGS)
.PHONY: mobile-test
mobile-test: ## Analyze and test the Android app
cd $(MOBILE_DIR) && $(FLUTTER) analyze && $(FLUTTER) test
.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