1
0
Files
nex/Makefile
lanyuanxiaoyao a9972360c2 feat: 增加版本化构建与发布流程
引入 VERSION 作为统一版本源,避免前端、后端、桌面打包和发布资产之间的版本漂移。
新增 tag 驱动的 Draft Release 流程与版本化资产命名,使本地演进和 GitHub 发布共享同一套约束。
2026-04-28 14:20:27 +08:00

305 lines
12 KiB
Makefile
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
.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"