引入 VERSION 作为统一版本源,避免前端、后端、桌面打包和发布资产之间的版本漂移。 新增 tag 驱动的 Draft Release 流程与版本化资产命名,使本地演进和 GitHub 发布共享同一套约束。
305 lines
12 KiB
Makefile
305 lines
12 KiB
Makefile
.PHONY: all dev build test lint clean \
|
||
version-sync version-check \
|
||
backend-build backend-run backend-dev backend-test backend-test-all backend-test-unit backend-test-integration backend-test-coverage \
|
||
backend-lint backend-clean backend-deps backend-generate \
|
||
backend-db-up backend-db-down backend-db-status backend-db-create \
|
||
test-mysql-up test-mysql-down test-mysql test-mysql-quick \
|
||
frontend-build frontend-dev frontend-test frontend-test-watch frontend-test-coverage frontend-test-e2e frontend-lint frontend-clean \
|
||
desktop-build desktop-build-mac desktop-build-win desktop-build-linux \
|
||
desktop-dev desktop-test desktop-clean \
|
||
desktop-prepare-frontend desktop-prepare-embedfs desktop-prepare-windows-resource \
|
||
release-assets-linux release-assets-windows release-assets-macos
|
||
|
||
VERSION := $(shell go run ./backend/cmd/versionctl print)
|
||
GIT_COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || printf 'unknown')
|
||
BUILD_TIME ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||
GO_LDFLAGS := -X nex/backend/pkg/buildinfo.version=$(VERSION) -X nex/backend/pkg/buildinfo.commit=$(GIT_COMMIT) -X nex/backend/pkg/buildinfo.buildTime=$(BUILD_TIME)
|
||
GO_LDFLAGS_WIN := $(GO_LDFLAGS) -H=windowsgui
|
||
RELEASE_DIR := build/release
|
||
SERVER_LINUX_ASSET := $(shell go run ./backend/cmd/versionctl asset-name server linux amd64)
|
||
SERVER_WINDOWS_ASSET := $(shell go run ./backend/cmd/versionctl asset-name server windows amd64)
|
||
SERVER_DARWIN_AMD64_ASSET := $(shell go run ./backend/cmd/versionctl asset-name server darwin amd64)
|
||
SERVER_DARWIN_ARM64_ASSET := $(shell go run ./backend/cmd/versionctl asset-name server darwin arm64)
|
||
DESKTOP_LINUX_ASSET := $(shell go run ./backend/cmd/versionctl asset-name desktop linux)
|
||
DESKTOP_WINDOWS_ASSET := $(shell go run ./backend/cmd/versionctl asset-name desktop windows)
|
||
DESKTOP_MACOS_ASSET := $(shell go run ./backend/cmd/versionctl asset-name desktop macos)
|
||
|
||
# ============================================
|
||
# 顶层便捷命令
|
||
# ============================================
|
||
|
||
dev:
|
||
@echo "🚀 Starting development environment..."
|
||
@$(MAKE) -j2 backend-dev frontend-dev
|
||
|
||
build: backend-build frontend-build
|
||
@echo "✅ Build complete"
|
||
|
||
test: backend-test desktop-test frontend-test
|
||
@echo "✅ All tests passed"
|
||
|
||
lint: backend-lint frontend-lint
|
||
@echo "✅ Lint complete"
|
||
|
||
all: build test lint
|
||
|
||
# ============================================
|
||
# 版本管理
|
||
# ============================================
|
||
|
||
version-sync:
|
||
go run ./backend/cmd/versionctl sync
|
||
|
||
version-check:
|
||
go run ./backend/cmd/versionctl check
|
||
|
||
# ============================================
|
||
# 后端
|
||
# ============================================
|
||
|
||
backend-build: version-check
|
||
cd backend && go build -ldflags "$(GO_LDFLAGS)" -o bin/server ./cmd/server
|
||
|
||
backend-run: version-check
|
||
cd backend && go run -ldflags "$(GO_LDFLAGS)" ./cmd/server
|
||
|
||
backend-dev: version-check
|
||
cd backend && go run -ldflags "$(GO_LDFLAGS)" ./cmd/server
|
||
|
||
backend-test:
|
||
cd backend && go test ./internal/... ./pkg/... ./tests/... ./cmd/server/... -v
|
||
|
||
backend-test-all:
|
||
cd backend && go test ./... -v
|
||
|
||
backend-test-unit:
|
||
cd backend && go test ./internal/... ./pkg/... -v
|
||
|
||
backend-test-integration:
|
||
cd backend && go test ./tests/... -v
|
||
|
||
backend-test-coverage:
|
||
cd backend && go test ./... -coverprofile=coverage.out
|
||
cd backend && go tool cover -html=coverage.out -o coverage.html
|
||
@echo "Coverage report generated: backend/coverage.html"
|
||
|
||
backend-lint:
|
||
cd backend && go tool golangci-lint run ./...
|
||
|
||
backend-clean:
|
||
rm -rf backend/bin/ backend/coverage.out backend/coverage.html
|
||
|
||
backend-deps:
|
||
cd backend && go mod tidy
|
||
|
||
backend-generate:
|
||
cd backend && go generate ./...
|
||
|
||
backend-db-up:
|
||
@echo "Running database migration up..."
|
||
cd backend && goose -dir migrations/sqlite sqlite3 "$(DB_PATH)" up
|
||
|
||
backend-db-down:
|
||
@echo "Running database migration down..."
|
||
cd backend && goose -dir migrations/sqlite sqlite3 "$(DB_PATH)" down
|
||
|
||
backend-db-status:
|
||
@echo "Checking database migration status..."
|
||
cd backend && goose -dir migrations/sqlite sqlite3 "$(DB_PATH)" status
|
||
|
||
backend-db-create:
|
||
@read -p "Migration name: " name; \
|
||
cd backend && goose -dir migrations/sqlite create $$name sql; \
|
||
cd backend && goose -dir migrations/mysql create $$name sql
|
||
|
||
# ============================================
|
||
# MySQL 专项测试
|
||
# ============================================
|
||
|
||
test-mysql-up:
|
||
@echo "Starting MySQL test container..."
|
||
cd backend/tests/mysql && docker-compose up -d
|
||
@echo "Waiting for MySQL to be ready..."
|
||
@for i in $$(seq 1 30); do \
|
||
if docker exec nex-mysql-test mysqladmin ping -h localhost -u root -ptestpass --silent 2>/dev/null; then \
|
||
echo "MySQL is ready!"; \
|
||
exit 0; \
|
||
fi; \
|
||
echo "Waiting... ($$i/30)"; \
|
||
sleep 1; \
|
||
done; \
|
||
echo "MySQL failed to start"; \
|
||
exit 1
|
||
|
||
test-mysql-down:
|
||
@echo "Stopping MySQL test container..."
|
||
cd backend/tests/mysql && docker-compose down -v
|
||
|
||
test-mysql: test-mysql-up
|
||
@echo "Running MySQL tests..."
|
||
cd backend && go test -tags=mysql ./tests/mysql/... -v -count=1
|
||
$(MAKE) test-mysql-down
|
||
|
||
test-mysql-quick:
|
||
@echo "Running MySQL tests (without container management)..."
|
||
cd backend && go test -tags=mysql ./tests/mysql/... -v -count=1
|
||
|
||
# ============================================
|
||
# 前端
|
||
# ============================================
|
||
|
||
frontend-install:
|
||
cd frontend && bun install
|
||
|
||
frontend-build: frontend-install version-sync
|
||
cd frontend && bun run build
|
||
|
||
frontend-dev: frontend-install version-sync
|
||
cd frontend && bun dev
|
||
|
||
frontend-test: frontend-install
|
||
cd frontend && bun run test
|
||
|
||
frontend-test-watch: frontend-install
|
||
cd frontend && bun run test:watch
|
||
|
||
frontend-test-coverage: frontend-install
|
||
cd frontend && bun run test:coverage
|
||
|
||
frontend-test-e2e: frontend-install
|
||
cd frontend && bun run test:e2e
|
||
|
||
frontend-lint: frontend-install
|
||
cd frontend && bun run lint
|
||
|
||
frontend-clean:
|
||
rm -rf frontend/dist frontend/.next frontend/node_modules frontend/coverage frontend/playwright-report frontend/test-results frontend/tsconfig.tsbuildinfo
|
||
|
||
# ============================================
|
||
# 桌面应用
|
||
# ============================================
|
||
|
||
desktop-build: desktop-build-mac desktop-build-win desktop-build-linux
|
||
@echo "✅ Desktop builds complete for all platforms"
|
||
|
||
desktop-prepare-frontend: frontend-install version-sync
|
||
@echo "📦 Preparing frontend for desktop..."
|
||
ifeq ($(OS),Windows_NT)
|
||
powershell -NoProfile -Command "Copy-Item -LiteralPath 'frontend/.env.desktop' -Destination 'frontend/.env.production.local' -Force"
|
||
cd frontend && bun run build
|
||
powershell -NoProfile -Command "Remove-Item -LiteralPath 'frontend/.env.production.local' -Force -ErrorAction SilentlyContinue"
|
||
else
|
||
cd frontend && cp .env.desktop .env.production.local
|
||
cd frontend && bun run build
|
||
rm -f frontend/.env.production.local
|
||
endif
|
||
|
||
desktop-prepare-embedfs:
|
||
@echo "📦 Preparing embedded filesystem..."
|
||
ifeq ($(OS),Windows_NT)
|
||
powershell -NoProfile -Command "Remove-Item -LiteralPath 'embedfs/assets' -Recurse -Force -ErrorAction SilentlyContinue; Remove-Item -LiteralPath 'embedfs/frontend-dist' -Recurse -Force -ErrorAction SilentlyContinue; Copy-Item -LiteralPath 'assets' -Destination 'embedfs/assets' -Recurse; Copy-Item -LiteralPath 'frontend/dist' -Destination 'embedfs/frontend-dist' -Recurse"
|
||
else
|
||
rm -rf embedfs/assets embedfs/frontend-dist
|
||
cp -r assets embedfs/assets
|
||
cp -r frontend/dist embedfs/frontend-dist
|
||
endif
|
||
|
||
desktop-prepare-windows-resource:
|
||
@echo "📦 Preparing Windows executable icon..."
|
||
ifeq ($(OS),Windows_NT)
|
||
cd backend/cmd/desktop && windres -O coff -F pe-x86-64 -i icon_windows.rc -o rsrc_windows_amd64.syso
|
||
else
|
||
@if command -v x86_64-w64-mingw32-windres >/dev/null 2>&1; then \
|
||
cd backend/cmd/desktop && x86_64-w64-mingw32-windres -O coff -F pe-x86-64 -i icon_windows.rc -o rsrc_windows_amd64.syso; \
|
||
elif command -v windres >/dev/null 2>&1; then \
|
||
cd backend/cmd/desktop && windres -O coff -F pe-x86-64 -i icon_windows.rc -o rsrc_windows_amd64.syso; \
|
||
else \
|
||
echo "❌ 未找到 windres,无法生成 Windows exe 图标资源"; \
|
||
exit 1; \
|
||
fi
|
||
endif
|
||
|
||
desktop-build-mac: desktop-prepare-frontend desktop-prepare-embedfs
|
||
@echo "🍎 Building macOS..."
|
||
cd backend && CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -ldflags "$(GO_LDFLAGS)" -o ../build/nex-mac-arm64 ./cmd/desktop
|
||
cd backend && CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -ldflags "$(GO_LDFLAGS)" -o ../build/nex-mac-amd64 ./cmd/desktop
|
||
lipo -create build/nex-mac-arm64 build/nex-mac-amd64 -output build/nex-mac-universal
|
||
@echo "📦 Packaging macOS .app..."
|
||
mkdir -p build/Nex.app/Contents/MacOS build/Nex.app/Contents/Resources
|
||
cp build/nex-mac-universal build/Nex.app/Contents/MacOS/nex
|
||
@if [ -f assets/icon.icns ]; then \
|
||
cp assets/icon.icns build/Nex.app/Contents/Resources/; \
|
||
else \
|
||
echo "⚠️ 未找到 assets/icon.icns"; \
|
||
fi
|
||
@MIN_MACOS_VERSION=$$(vtool -show-build build/nex-mac-universal | awk '/minos / {print $$2; exit}'); \
|
||
if [ -z "$$MIN_MACOS_VERSION" ]; then \
|
||
echo "❌ 无法读取 macOS 最低系统版本"; \
|
||
exit 1; \
|
||
fi; \
|
||
go run ./backend/cmd/versionctl macos-plist "$$MIN_MACOS_VERSION" > build/Nex.app/Contents/Info.plist
|
||
chmod +x build/Nex.app/Contents/MacOS/nex
|
||
@echo "✅ macOS app packaged: build/Nex.app"
|
||
|
||
desktop-build-win: desktop-prepare-frontend desktop-prepare-embedfs desktop-prepare-windows-resource
|
||
@echo "🪟 Building Windows..."
|
||
ifeq ($(OS),Windows_NT)
|
||
powershell -NoProfile -Command "New-Item -ItemType Directory -Path 'build' -Force | Out-Null"
|
||
cd backend && set "CGO_ENABLED=1"&& set "GOOS=windows"&& set "GOARCH=amd64"&& go build -ldflags "$(GO_LDFLAGS_WIN)" -o ../build/nex-win-amd64.exe ./cmd/desktop
|
||
else
|
||
mkdir -p build
|
||
cd backend && CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build -ldflags "$(GO_LDFLAGS_WIN)" -o ../build/nex-win-amd64.exe ./cmd/desktop
|
||
endif
|
||
|
||
desktop-build-linux: desktop-prepare-frontend desktop-prepare-embedfs
|
||
@echo "🐧 Building Linux..."
|
||
cd backend && CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags "$(GO_LDFLAGS)" -o ../build/nex-linux-amd64 ./cmd/desktop
|
||
|
||
desktop-dev: desktop-prepare-frontend desktop-prepare-embedfs
|
||
@echo "🖥️ Starting desktop app in dev mode..."
|
||
cd backend && go run -ldflags "$(GO_LDFLAGS)" ./cmd/desktop
|
||
|
||
# ============================================
|
||
# 发布资产
|
||
# ============================================
|
||
|
||
release-assets-linux: version-sync version-check desktop-build-linux
|
||
rm -rf "$(RELEASE_DIR)"
|
||
mkdir -p "$(RELEASE_DIR)"
|
||
cd backend && CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags "$(GO_LDFLAGS)" -o ../build/nex-server-linux-amd64 ./cmd/server
|
||
tar -C build -czf "$(RELEASE_DIR)/$(SERVER_LINUX_ASSET)" nex-server-linux-amd64
|
||
tar -C build -czf "$(RELEASE_DIR)/$(DESKTOP_LINUX_ASSET)" nex-linux-amd64
|
||
|
||
release-assets-windows: version-sync version-check desktop-build-win
|
||
ifeq ($(OS),Windows_NT)
|
||
powershell -NoProfile -Command "Remove-Item -LiteralPath '$(RELEASE_DIR)' -Recurse -Force -ErrorAction SilentlyContinue; New-Item -ItemType Directory -Path '$(RELEASE_DIR)' -Force | Out-Null"
|
||
cd backend && set "CGO_ENABLED=1"&& set "GOOS=windows"&& set "GOARCH=amd64"&& go build -ldflags "$(GO_LDFLAGS_WIN)" -o ../build/nex-server-win-amd64.exe ./cmd/server
|
||
powershell -NoProfile -Command "Compress-Archive -LiteralPath 'build/nex-server-win-amd64.exe' -DestinationPath '$(RELEASE_DIR)/$(SERVER_WINDOWS_ASSET)' -Force"
|
||
powershell -NoProfile -Command "Compress-Archive -LiteralPath 'build/nex-win-amd64.exe' -DestinationPath '$(RELEASE_DIR)/$(DESKTOP_WINDOWS_ASSET)' -Force"
|
||
else
|
||
@echo "❌ release-assets-windows 需要在 Windows 环境执行"
|
||
@exit 1
|
||
endif
|
||
|
||
release-assets-macos: version-sync version-check desktop-build-mac
|
||
rm -rf "$(RELEASE_DIR)"
|
||
mkdir -p "$(RELEASE_DIR)"
|
||
cd backend && CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -ldflags "$(GO_LDFLAGS)" -o ../build/nex-server-darwin-amd64 ./cmd/server
|
||
cd backend && CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -ldflags "$(GO_LDFLAGS)" -o ../build/nex-server-darwin-arm64 ./cmd/server
|
||
tar -C build -czf "$(RELEASE_DIR)/$(SERVER_DARWIN_AMD64_ASSET)" nex-server-darwin-amd64
|
||
tar -C build -czf "$(RELEASE_DIR)/$(SERVER_DARWIN_ARM64_ASSET)" nex-server-darwin-arm64
|
||
ditto -c -k --keepParent build/Nex.app "$(RELEASE_DIR)/$(DESKTOP_MACOS_ASSET)"
|
||
|
||
desktop-test:
|
||
cd backend && go test ./cmd/desktop/... -v
|
||
|
||
desktop-clean:
|
||
rm -rf build/ embedfs/assets embedfs/frontend-dist
|
||
|
||
# ============================================
|
||
# 清理
|
||
# ============================================
|
||
|
||
clean: backend-clean frontend-clean desktop-clean
|
||
@echo "✅ Clean complete"
|