pre-commit 代码检查改为委托 _backend-lint / _versionctl-lint / _frontend-check,新增 LFS 指针校验;commit-msg 新增多行空行格式校验和模板注释忽略,移除 CJK/Python 字符集检测;新增 prepare-commit-msg 提交信息模板;hooks-install 增加 source 文件存在性校验;前端 check 补入 tsc -b 类型检查并修复暴露的类型错误
521 lines
20 KiB
Makefile
521 lines
20 KiB
Makefile
.PHONY: \
|
|
lint test clean hooks-install hooks-check hooks-test \
|
|
version-sync version-check version-bump \
|
|
server-run server-build server-lint server-test server-clean \
|
|
desktop-build-mac desktop-build-win desktop-build-linux \
|
|
desktop-lint desktop-test desktop-clean \
|
|
release-assets-check release-assets-web release-assets-linux release-assets-windows release-assets-macos release-assets-checksums \
|
|
release-assets-server-linux release-assets-server-windows release-assets-server-macos \
|
|
release-assets-desktop-linux release-assets-desktop-windows release-assets-desktop-macos \
|
|
_backend-lint _backend-test _backend-clean _backend-build \
|
|
_versionctl-lint _versionctl-test \
|
|
_frontend-install _frontend-build _frontend-check _frontend-test _frontend-dev _frontend-clean \
|
|
_hooks-pre-commit _check-clean-worktree \
|
|
_desktop-test _desktop-clean _desktop-prepare-frontend _desktop-prepare-embedfs _desktop-prepare-windows-resource \
|
|
_server-run-backend _server-run-frontend \
|
|
_check-linux-target-arch _check-windows-target-arch _ensure-appimagetool \
|
|
_package-linux-tar _package-linux-appimage _package-linux-deb _package-linux-rpm \
|
|
_package-macos-zip _package-macos-dmg
|
|
|
|
# Delay shell lookups until a target needs them, then cache the result for this make run.
|
|
lazy_shell = $(or $($(1)),$(eval $(1) := $(shell $(2)))$($(1)))
|
|
|
|
VERSION = $(call lazy_shell,_VERSION,go run ./versionctl print)
|
|
GIT_COMMIT ?= $(call lazy_shell,_GIT_COMMIT,git rev-parse --short HEAD 2>/dev/null || printf 'unknown')
|
|
BUILD_TIME ?= $(call lazy_shell,_BUILD_TIME,date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
TARGET_ARCH ?= $(call lazy_shell,_TARGET_ARCH,go env GOARCH)
|
|
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
|
|
LINUX_DESKTOP_BINARY = build/nex-linux-$(TARGET_ARCH)
|
|
WINDOWS_DESKTOP_BINARY = build/nex-win-$(TARGET_ARCH).exe
|
|
WINDOWS_SERVER_BINARY = build/nex-server-windows-$(TARGET_ARCH).exe
|
|
WINDRES ?= windres
|
|
|
|
ifeq ($(TARGET_ARCH),arm64)
|
|
APPIMAGE_ARCH := aarch64
|
|
DEB_ARCH := arm64
|
|
RPM_ARCH := aarch64
|
|
else
|
|
APPIMAGE_ARCH := x86_64
|
|
DEB_ARCH := amd64
|
|
RPM_ARCH := x86_64
|
|
endif
|
|
|
|
WINDOWS_WINDRES_FORMAT_BFD := pe-x86-64
|
|
WINDOWS_WINDRES_FORMAT_LLVM := x86_64-w64-mingw32
|
|
WINDOWS_RESOURCE := rsrc_windows_amd64.syso
|
|
|
|
APPIMAGETOOL_PATH := build/tools/appimagetool-$(APPIMAGE_ARCH).AppImage
|
|
APPIMAGETOOL_URL ?= https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-$(APPIMAGE_ARCH).AppImage
|
|
APPIMAGETOOL ?= $(APPIMAGETOOL_PATH)
|
|
|
|
# ============================================
|
|
# 全局命令
|
|
# ============================================
|
|
|
|
lint: _backend-lint _frontend-check _versionctl-lint
|
|
@printf 'Lint complete\n'
|
|
|
|
test: _backend-test _frontend-test _desktop-test _versionctl-test
|
|
@printf 'All tests passed\n'
|
|
|
|
clean: _backend-clean _frontend-clean _desktop-clean
|
|
@printf 'Clean complete\n'
|
|
|
|
# ============================================
|
|
# Git hooks
|
|
# ============================================
|
|
|
|
hooks-install:
|
|
@hooks_dir=$$(git rev-parse --git-path hooks); \
|
|
mkdir -p "$$hooks_dir"; \
|
|
for hook in pre-commit commit-msg prepare-commit-msg; do \
|
|
src="scripts/git-hooks/$$hook"; \
|
|
if [ ! -f "$$src" ]; then \
|
|
printf 'ERROR: source hook not found: %s\n' "$$src" >&2; \
|
|
exit 1; \
|
|
fi; \
|
|
cp "$$src" "$$hooks_dir/$$hook"; \
|
|
chmod +x "$$hooks_dir/$$hook"; \
|
|
done; \
|
|
printf 'Installed Git hooks to %s\n' "$$hooks_dir"
|
|
|
|
hooks-check:
|
|
@hooks_dir=$$(git rev-parse --git-path hooks); \
|
|
status=0; \
|
|
for hook in pre-commit commit-msg prepare-commit-msg; do \
|
|
if [ -x "$$hooks_dir/$$hook" ]; then \
|
|
printf 'OK: %s\n' "$$hook"; \
|
|
else \
|
|
printf 'MISSING: %s (%s/%s)\n' "$$hook" "$$hooks_dir" "$$hook"; \
|
|
status=1; \
|
|
fi; \
|
|
done; \
|
|
exit $$status
|
|
|
|
hooks-test:
|
|
@scripts/git-hooks/test-hooks.sh
|
|
|
|
_hooks-pre-commit:
|
|
@set -ef; \
|
|
staged_files=$$(git diff --cached --name-only --diff-filter=ACM); \
|
|
if [ -z "$$staged_files" ]; then \
|
|
printf 'No staged files to check\n'; \
|
|
exit 0; \
|
|
fi; \
|
|
run_backend_lint=; \
|
|
run_versionctl_lint=; \
|
|
run_frontend_check=; \
|
|
lfs_patterns=$$(grep 'filter=lfs' .gitattributes 2>/dev/null | awk '{print $$1}' || true); \
|
|
for file in $$staged_files; do \
|
|
[ -n "$$file" ] || continue; \
|
|
if git show ":$$file" 2>/dev/null | grep -Eq '^(<<<<<<<|=======|>>>>>>>)'; then \
|
|
printf 'Found conflict markers in staged file: %s\n' "$$file" >&2; \
|
|
printf 'Resolve conflict markers before committing.\n' >&2; \
|
|
exit 1; \
|
|
fi; \
|
|
size=$$(git cat-file -s ":$$file" 2>/dev/null || printf '0'); \
|
|
if [ "$$size" -gt 512000 ] 2>/dev/null; then \
|
|
if git show ":$$file" 2>/dev/null | LC_ALL=C grep -Iq .; then \
|
|
printf 'Warning: large staged text file (%s bytes): %s\n' "$$size" "$$file" >&2; \
|
|
fi; \
|
|
fi; \
|
|
if [ -n "$$lfs_patterns" ]; then \
|
|
for lfs_pat in $$lfs_patterns; do \
|
|
case "$$file" in $$lfs_pat) \
|
|
content=$$(git show ":$$file" 2>/dev/null | head -1); \
|
|
case "$$content" in \
|
|
"version https://git-lfs.github.com/spec/v1"*) ;; \
|
|
*) \
|
|
printf 'LFS-tracked file not using LFS pointer: %s\n' "$$file" >&2; \
|
|
printf 'Run "git lfs install" and re-add this file.\n' >&2; \
|
|
exit 1; \
|
|
;; \
|
|
esac; \
|
|
break; \
|
|
;; \
|
|
esac; \
|
|
done; \
|
|
fi; \
|
|
case "$$file" in \
|
|
backend/*.go) run_backend_lint=1 ;; \
|
|
versionctl/*.go) run_versionctl_lint=1 ;; \
|
|
frontend/*.ts|frontend/*.tsx|frontend/*.scss) run_frontend_check=1 ;; \
|
|
esac; \
|
|
done; \
|
|
if [ -n "$$run_backend_lint" ]; then \
|
|
printf 'Running backend lint...\n'; \
|
|
$(MAKE) _backend-lint; \
|
|
fi; \
|
|
if [ -n "$$run_versionctl_lint" ]; then \
|
|
printf 'Running versionctl lint...\n'; \
|
|
$(MAKE) _versionctl-lint; \
|
|
fi; \
|
|
if [ -n "$$run_frontend_check" ]; then \
|
|
printf 'Running frontend check...\n'; \
|
|
$(MAKE) _frontend-check; \
|
|
fi; \
|
|
printf 'Pre-commit checks passed\n'
|
|
|
|
# ============================================
|
|
# 版本管理
|
|
# ============================================
|
|
|
|
version-sync:
|
|
go run ./versionctl sync
|
|
|
|
version-check:
|
|
go run ./versionctl check
|
|
|
|
version-bump: BUMP ?= patch
|
|
version-bump: lint test _check-clean-worktree
|
|
@set -e; \
|
|
bump_arg="$(if $(SET_VERSION),$(SET_VERSION),$(BUMP))"; \
|
|
new_version=$$(go run ./versionctl bump "$$bump_arg"); \
|
|
git add VERSION frontend/; \
|
|
git commit -m "chore: 版本升迁 v$$new_version"; \
|
|
git tag "v$$new_version"; \
|
|
printf '版本升迁完成: v%s\n' "$$new_version"
|
|
|
|
_check-clean-worktree:
|
|
@if [ -n "$$(git status --porcelain)" ]; then \
|
|
printf '工作区不干净,请先提交或清理改动后再执行版本升迁。\n' >&2; \
|
|
git status --short; \
|
|
exit 1; \
|
|
fi
|
|
|
|
# ============================================
|
|
# Server 模式
|
|
# ============================================
|
|
|
|
server-run:
|
|
@$(MAKE) -j2 _server-run-backend _server-run-frontend
|
|
|
|
server-build: version-check _backend-build _frontend-build
|
|
@printf 'Server build complete\n'
|
|
|
|
server-lint: _backend-lint _frontend-check
|
|
@printf 'Server lint complete\n'
|
|
|
|
server-test: _backend-test _frontend-test
|
|
@printf 'Server tests passed\n'
|
|
|
|
server-clean: _backend-clean _frontend-clean
|
|
@printf 'Server artifacts cleaned\n'
|
|
|
|
_server-run-backend:
|
|
@$(MAKE) -C backend run
|
|
|
|
_server-run-frontend: _frontend-install
|
|
cd frontend && bun run dev
|
|
|
|
# ============================================
|
|
# Desktop 模式
|
|
# ============================================
|
|
|
|
desktop-build-mac: version-check _desktop-prepare-frontend _desktop-prepare-embedfs
|
|
@printf 'Building macOS desktop...\n'
|
|
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
|
|
lipo -info build/nex-mac-universal | grep -q 'x86_64 arm64'
|
|
rm -f build/nex-mac-arm64 build/nex-mac-amd64
|
|
@printf 'Packaging macOS app bundle...\n'
|
|
rm -rf build/Nex.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 \
|
|
printf 'Missing assets/icon.icns\n'; \
|
|
exit 1; \
|
|
fi
|
|
@MIN_MACOS_VERSION=$$(vtool -show-build build/nex-mac-universal | awk '/minos / {print $$2; exit}'); \
|
|
if [ -z "$$MIN_MACOS_VERSION" ]; then \
|
|
printf 'Unable to read macOS minimum version\n'; \
|
|
exit 1; \
|
|
fi; \
|
|
go run ./versionctl macos-plist "$$MIN_MACOS_VERSION" > build/Nex.app/Contents/Info.plist
|
|
chmod +x build/Nex.app/Contents/MacOS/nex
|
|
@printf 'macOS desktop build complete\n'
|
|
|
|
desktop-build-win: version-check _desktop-prepare-frontend _desktop-prepare-embedfs _desktop-prepare-windows-resource _check-windows-target-arch
|
|
@printf 'Building Windows desktop $(TARGET_ARCH)...\n'
|
|
mkdir -p build
|
|
cd backend && CGO_ENABLED=1 GOOS=windows GOARCH=$(TARGET_ARCH) go build -ldflags "$(GO_LDFLAGS_WIN)" -o ../$(WINDOWS_DESKTOP_BINARY) ./cmd/desktop
|
|
@printf 'Windows desktop build complete\n'
|
|
|
|
desktop-build-linux: version-check _desktop-prepare-frontend _desktop-prepare-embedfs _check-linux-target-arch
|
|
@printf 'Building Linux desktop $(TARGET_ARCH)...\n'
|
|
mkdir -p build
|
|
cd backend && CGO_ENABLED=1 GOOS=linux GOARCH=$(TARGET_ARCH) go build -ldflags "$(GO_LDFLAGS)" -o ../$(LINUX_DESKTOP_BINARY) ./cmd/desktop
|
|
@printf 'Linux desktop build complete\n'
|
|
|
|
desktop-lint: _backend-lint _frontend-check
|
|
@printf 'Desktop lint complete\n'
|
|
|
|
desktop-test: _desktop-test
|
|
@printf 'Desktop tests passed\n'
|
|
|
|
desktop-clean: _desktop-clean
|
|
@printf 'Desktop artifacts cleaned\n'
|
|
|
|
_desktop-test:
|
|
cd backend && go test ./cmd/desktop/... -v
|
|
|
|
_desktop-clean:
|
|
rm -rf build/ embedfs/assets embedfs/frontend-dist backend/cmd/desktop/rsrc_windows_amd64.syso
|
|
|
|
_desktop-prepare-frontend: _frontend-install
|
|
@printf 'Preparing frontend for desktop...\n'
|
|
cd frontend && cp .env.desktop .env.production.local
|
|
cd frontend && bun run build
|
|
rm -f frontend/.env.production.local
|
|
|
|
_desktop-prepare-embedfs:
|
|
@printf 'Preparing embedded filesystem...\n'
|
|
rm -rf embedfs/assets embedfs/frontend-dist
|
|
cp -r assets embedfs/assets
|
|
cp -r frontend/dist embedfs/frontend-dist
|
|
|
|
_desktop-prepare-windows-resource: _check-windows-target-arch
|
|
@printf 'Preparing Windows $(TARGET_ARCH) executable icon...\n'
|
|
@WINDRES_CMD="$(WINDRES)"; \
|
|
WINDRES_FMT="$(WINDOWS_WINDRES_FORMAT_BFD)"; \
|
|
if command -v llvm-windres >/dev/null 2>&1; then \
|
|
WINDRES_CMD=llvm-windres; \
|
|
WINDRES_FMT="$(WINDOWS_WINDRES_FORMAT_LLVM)"; \
|
|
elif "$$WINDRES_CMD" --version 2>&1 | grep -qi LLVM; then \
|
|
WINDRES_FMT="$(WINDOWS_WINDRES_FORMAT_LLVM)"; \
|
|
fi; \
|
|
command -v "$$WINDRES_CMD" >/dev/null 2>&1 || { printf 'Missing windres tool: %s\n' "$$WINDRES_CMD"; exit 1; }; \
|
|
cd backend/cmd/desktop && "$$WINDRES_CMD" -O coff -F "$$WINDRES_FMT" -i icon_windows.rc -o $(WINDOWS_RESOURCE)
|
|
|
|
# ============================================
|
|
# 发布资产
|
|
# ============================================
|
|
|
|
release-assets-check:
|
|
go run ./versionctl release-assets-check
|
|
@printf 'Release assets check passed\n'
|
|
|
|
release-assets-web: version-check release-assets-check _frontend-build
|
|
rm -rf "$(RELEASE_DIR)"
|
|
mkdir -p "$(RELEASE_DIR)"
|
|
asset=$$(go run ./versionctl asset-name web tar.gz); \
|
|
tar -C frontend -czf "$(RELEASE_DIR)/$$asset" dist
|
|
|
|
release-assets-linux: version-check release-assets-check _check-linux-target-arch
|
|
rm -rf "$(RELEASE_DIR)"
|
|
mkdir -p "$(RELEASE_DIR)"
|
|
@$(MAKE) release-assets-server-linux TARGET_ARCH=$(TARGET_ARCH) RELEASE_DIR="$(RELEASE_DIR)"
|
|
@$(MAKE) release-assets-desktop-linux TARGET_ARCH=$(TARGET_ARCH) RELEASE_DIR="$(RELEASE_DIR)"
|
|
|
|
release-assets-windows: version-check release-assets-check _check-windows-target-arch
|
|
rm -rf "$(RELEASE_DIR)"
|
|
mkdir -p "$(RELEASE_DIR)"
|
|
@$(MAKE) release-assets-server-windows TARGET_ARCH=$(TARGET_ARCH) RELEASE_DIR="$(RELEASE_DIR)"
|
|
@$(MAKE) release-assets-desktop-windows TARGET_ARCH=$(TARGET_ARCH) RELEASE_DIR="$(RELEASE_DIR)"
|
|
|
|
release-assets-macos: version-check release-assets-check
|
|
rm -rf "$(RELEASE_DIR)"
|
|
mkdir -p "$(RELEASE_DIR)"
|
|
@$(MAKE) release-assets-server-macos RELEASE_DIR="$(RELEASE_DIR)"
|
|
@$(MAKE) release-assets-desktop-macos RELEASE_DIR="$(RELEASE_DIR)"
|
|
|
|
release-assets-server-linux: version-check _check-linux-target-arch
|
|
mkdir -p build "$(RELEASE_DIR)"
|
|
cd backend && CGO_ENABLED=1 GOOS=linux GOARCH=$(TARGET_ARCH) go build -ldflags "$(GO_LDFLAGS)" -o ../build/nex-server-linux-$(TARGET_ARCH) ./cmd/server
|
|
asset=$$(go run ./versionctl asset-name server linux $(TARGET_ARCH) tar.gz); \
|
|
tar -C build -czf "$(RELEASE_DIR)/$$asset" nex-server-linux-$(TARGET_ARCH)
|
|
|
|
release-assets-server-windows: version-check _check-windows-target-arch
|
|
mkdir -p build "$(RELEASE_DIR)"
|
|
cd backend && CGO_ENABLED=1 GOOS=windows GOARCH=$(TARGET_ARCH) go build -ldflags "$(GO_LDFLAGS)" -o ../$(WINDOWS_SERVER_BINARY) ./cmd/server
|
|
asset=$$(go run ./versionctl asset-name server windows $(TARGET_ARCH) zip); \
|
|
if command -v powershell.exe >/dev/null 2>&1; then POWERSHELL=powershell.exe; else POWERSHELL=powershell; fi; \
|
|
"$$POWERSHELL" -NoProfile -Command "Compress-Archive -LiteralPath '$(WINDOWS_SERVER_BINARY)' -DestinationPath '$(RELEASE_DIR)/$$asset' -Force"
|
|
|
|
release-assets-server-macos: version-check
|
|
mkdir -p build "$(RELEASE_DIR)"
|
|
cd backend && CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -ldflags "$(GO_LDFLAGS)" -o ../build/nex-server-macos-amd64 ./cmd/server
|
|
cd backend && CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -ldflags "$(GO_LDFLAGS)" -o ../build/nex-server-macos-arm64 ./cmd/server
|
|
lipo -create build/nex-server-macos-amd64 build/nex-server-macos-arm64 -output build/nex-server-macos-universal
|
|
lipo -info build/nex-server-macos-universal | grep -q 'x86_64 arm64'
|
|
asset=$$(go run ./versionctl asset-name server macos amd64 tar.gz); \
|
|
tar -C build -czf "$(RELEASE_DIR)/$$asset" nex-server-macos-amd64
|
|
asset=$$(go run ./versionctl asset-name server macos arm64 tar.gz); \
|
|
tar -C build -czf "$(RELEASE_DIR)/$$asset" nex-server-macos-arm64
|
|
asset=$$(go run ./versionctl asset-name server macos universal tar.gz); \
|
|
tar -C build -czf "$(RELEASE_DIR)/$$asset" nex-server-macos-universal
|
|
rm -f build/nex-server-macos-amd64 build/nex-server-macos-arm64 build/nex-server-macos-universal
|
|
|
|
release-assets-desktop-linux: version-check release-assets-check desktop-build-linux _package-linux-tar _package-linux-appimage _package-linux-deb _package-linux-rpm
|
|
|
|
release-assets-desktop-windows: version-check release-assets-check desktop-build-win
|
|
mkdir -p "$(RELEASE_DIR)"
|
|
asset=$$(go run ./versionctl asset-name desktop windows $(TARGET_ARCH) zip); \
|
|
if command -v powershell.exe >/dev/null 2>&1; then POWERSHELL=powershell.exe; else POWERSHELL=powershell; fi; \
|
|
"$$POWERSHELL" -NoProfile -Command "Compress-Archive -LiteralPath '$(WINDOWS_DESKTOP_BINARY)' -DestinationPath '$(RELEASE_DIR)/$$asset' -Force"
|
|
|
|
release-assets-desktop-macos: version-check release-assets-check desktop-build-mac _package-macos-zip _package-macos-dmg
|
|
rm -rf build/Nex.app build/dmg
|
|
|
|
release-assets-checksums:
|
|
@cd "$(RELEASE_DIR)" && \
|
|
rm -f SHA256SUMS && \
|
|
for asset in *; do \
|
|
[ -f "$$asset" ] || continue; \
|
|
if command -v sha256sum >/dev/null 2>&1; then \
|
|
sha256sum "$$asset"; \
|
|
elif command -v shasum >/dev/null 2>&1; then \
|
|
shasum -a 256 "$$asset"; \
|
|
else \
|
|
printf 'Missing sha256sum or shasum\n' >&2; \
|
|
exit 1; \
|
|
fi; \
|
|
done > SHA256SUMS && \
|
|
test -s SHA256SUMS
|
|
|
|
_check-linux-target-arch:
|
|
@if [ "$(TARGET_ARCH)" != "amd64" ] && [ "$(TARGET_ARCH)" != "arm64" ]; then \
|
|
printf 'Unsupported Linux TARGET_ARCH: %s\n' "$(TARGET_ARCH)"; \
|
|
exit 1; \
|
|
fi
|
|
|
|
_check-windows-target-arch:
|
|
@if [ "$(TARGET_ARCH)" != "amd64" ]; then \
|
|
printf 'Unsupported Windows TARGET_ARCH: %s\n' "$(TARGET_ARCH)"; \
|
|
exit 1; \
|
|
fi
|
|
|
|
_ensure-appimagetool:
|
|
@mkdir -p build/tools
|
|
@if [ ! -x "$(APPIMAGETOOL)" ]; then \
|
|
printf 'Downloading appimagetool for %s...\n' "$(APPIMAGE_ARCH)"; \
|
|
command -v curl >/dev/null 2>&1 || { printf 'Missing curl for appimagetool download\n'; exit 1; }; \
|
|
curl -L "$(APPIMAGETOOL_URL)" -o "$(APPIMAGETOOL)"; \
|
|
chmod +x "$(APPIMAGETOOL)"; \
|
|
fi; \
|
|
printf 'Using appimagetool: %s\n' "$(APPIMAGETOOL)"
|
|
|
|
_package-linux-tar:
|
|
mkdir -p "$(RELEASE_DIR)"
|
|
asset=$$(go run ./versionctl asset-name desktop linux $(TARGET_ARCH) tar.gz); \
|
|
tar -C build -czf "$(RELEASE_DIR)/$$asset" nex-linux-$(TARGET_ARCH)
|
|
|
|
_package-linux-appimage: _ensure-appimagetool
|
|
mkdir -p "$(RELEASE_DIR)"
|
|
appdir="build/appimage/nex-$(TARGET_ARCH).AppDir"; \
|
|
rm -rf "$$appdir"; \
|
|
mkdir -p "$$appdir/usr/bin" "$$appdir/usr/share/applications" "$$appdir/usr/share/icons"; \
|
|
install -m 0755 "$(LINUX_DESKTOP_BINARY)" "$$appdir/usr/bin/nex"; \
|
|
install -m 0644 packaging/linux/nex.desktop "$$appdir/nex.desktop"; \
|
|
install -m 0644 packaging/linux/nex.desktop "$$appdir/usr/share/applications/nex.desktop"; \
|
|
install -m 0755 packaging/linux/AppRun "$$appdir/AppRun"; \
|
|
cp -R assets/icons/hicolor "$$appdir/usr/share/icons/"; \
|
|
cp assets/icon.png "$$appdir/nex.png"; \
|
|
asset=$$(go run ./versionctl asset-name desktop linux $(TARGET_ARCH) AppImage); \
|
|
ARCH=$(APPIMAGE_ARCH) APPIMAGE_EXTRACT_AND_RUN=1 "$(APPIMAGETOOL)" "$$appdir" "$(RELEASE_DIR)/$$asset"; \
|
|
chmod +x "$(RELEASE_DIR)/$$asset"; \
|
|
test -s "$(RELEASE_DIR)/$$asset"
|
|
|
|
_package-linux-deb:
|
|
mkdir -p "$(RELEASE_DIR)"
|
|
pkgdir="build/pkg/deb/nex-$(TARGET_ARCH)"; \
|
|
rm -rf "$$pkgdir"; \
|
|
mkdir -p "$$pkgdir/DEBIAN" "$$pkgdir/usr/bin" "$$pkgdir/usr/share/applications" "$$pkgdir/usr/share/icons"; \
|
|
install -m 0755 "$(LINUX_DESKTOP_BINARY)" "$$pkgdir/usr/bin/nex"; \
|
|
install -m 0644 packaging/linux/nex.desktop "$$pkgdir/usr/share/applications/nex.desktop"; \
|
|
cp -R assets/icons/hicolor "$$pkgdir/usr/share/icons/"; \
|
|
printf '%s\n' \
|
|
'Package: nex' \
|
|
'Version: $(VERSION)' \
|
|
'Section: utils' \
|
|
'Priority: optional' \
|
|
'Architecture: $(DEB_ARCH)' \
|
|
'Maintainer: Nex Maintainers <noreply@example.com>' \
|
|
'Depends: libgtk-3-0, libayatana-appindicator3-1, xdg-utils' \
|
|
'Description: AI Gateway desktop application' \
|
|
' Nex is an AI Gateway desktop application.' \
|
|
> "$$pkgdir/DEBIAN/control"; \
|
|
asset=$$(go run ./versionctl asset-name desktop linux $(TARGET_ARCH) deb); \
|
|
dpkg-deb --build --root-owner-group "$$pkgdir" "$(RELEASE_DIR)/$$asset"; \
|
|
dpkg-deb -I "$(RELEASE_DIR)/$$asset" >/dev/null
|
|
|
|
_package-linux-rpm:
|
|
mkdir -p "$(RELEASE_DIR)"
|
|
topdir="$(abspath build/rpmbuild-$(TARGET_ARCH))"; \
|
|
rm -rf "$$topdir"; \
|
|
mkdir -p "$$topdir/BUILD" "$$topdir/BUILDROOT" "$$topdir/RPMS" "$$topdir/SOURCES" "$$topdir/SPECS" "$$topdir/SRPMS"; \
|
|
rpmbuild -bb --target "$(RPM_ARCH)" \
|
|
--define "_topdir $$topdir" \
|
|
--define "nex_version $(VERSION)" \
|
|
--define "nex_binary $(abspath $(LINUX_DESKTOP_BINARY))" \
|
|
--define "nex_desktop_file $(abspath packaging/linux/nex.desktop)" \
|
|
--define "nex_icons_dir $(abspath assets/icons/hicolor)" \
|
|
packaging/linux/nex.spec; \
|
|
rpm_file=$$(find "$$topdir/RPMS" -type f -name '*.rpm' | sort | tail -n 1); \
|
|
test -n "$$rpm_file"; \
|
|
asset=$$(go run ./versionctl asset-name desktop linux $(TARGET_ARCH) rpm); \
|
|
cp "$$rpm_file" "$(RELEASE_DIR)/$$asset"; \
|
|
rpm -qip "$(RELEASE_DIR)/$$asset" >/dev/null
|
|
|
|
_package-macos-zip:
|
|
mkdir -p "$(RELEASE_DIR)"
|
|
asset=$$(go run ./versionctl asset-name desktop macos universal zip); \
|
|
ditto -c -k --keepParent build/Nex.app "$(RELEASE_DIR)/$$asset"
|
|
|
|
_package-macos-dmg:
|
|
mkdir -p "$(RELEASE_DIR)"
|
|
dmgdir="build/dmg/Nex"; \
|
|
rm -rf "$$dmgdir"; \
|
|
mkdir -p "$$dmgdir"; \
|
|
cp -R build/Nex.app "$$dmgdir/Nex.app"; \
|
|
ln -s /Applications "$$dmgdir/Applications"; \
|
|
asset=$$(go run ./versionctl asset-name desktop macos universal dmg); \
|
|
hdiutil create -volname Nex -srcfolder "$$dmgdir" -ov -format UDZO "$(RELEASE_DIR)/$$asset"; \
|
|
hdiutil verify "$(RELEASE_DIR)/$$asset" >/dev/null && \
|
|
rm -rf "$$dmgdir"
|
|
|
|
# ============================================
|
|
# 共享 helper targets
|
|
# ============================================
|
|
|
|
_backend-build:
|
|
@$(MAKE) -C backend build
|
|
|
|
_backend-lint:
|
|
@$(MAKE) -C backend lint
|
|
|
|
_backend-test:
|
|
@$(MAKE) -C backend test
|
|
|
|
_backend-clean:
|
|
@$(MAKE) -C backend clean
|
|
|
|
_versionctl-lint:
|
|
@$(MAKE) -C versionctl lint
|
|
|
|
_versionctl-test:
|
|
@$(MAKE) -C versionctl test
|
|
|
|
_frontend-install:
|
|
cd frontend && bun install
|
|
|
|
_frontend-build: _frontend-install
|
|
cd frontend && bun run build
|
|
|
|
_frontend-check: _frontend-install
|
|
cd frontend && bun run check
|
|
|
|
_frontend-test: _frontend-install
|
|
cd frontend && bun run test
|
|
|
|
_frontend-dev: _frontend-install
|
|
cd frontend && bun run dev
|
|
|
|
_frontend-clean:
|
|
rm -rf frontend/dist frontend/.next frontend/coverage frontend/playwright-report frontend/test-results frontend/tsconfig.tsbuildinfo
|