feat: 完成 Issue #14-15 主题商店与跨平台打包
## Phase 4 - 性能与生态 (续) ### Issue #14: 个性化主题商店 ✅ - ThemeManager 主题管理器 - 4 种内置主题 (深色/浅色/护眼/高对比度) - 主题安装/卸载功能 - 自定义主题配置 - CSS 变量系统 ### Issue #15: 跨平台打包发布 ✅ - build-release.sh 打包脚本 - 支持 macOS (DMG + App Bundle) - 支持 Linux (AppImage + tar.gz) - 支持 Windows (NSIS + ZIP) - Cargo 发布配置优化 (LTO, strip) - 自动生成 RELEASE.md ## 完成状态 ✅ Phase 2: 4/4 Issues ✅ Phase 3: 4/4 Issues ✅ Phase 4: 3/3 Issues 🎉 ReadFlow MVP 全部完成!
This commit is contained in:
377
scripts/build-release.sh
Executable file
377
scripts/build-release.sh
Executable file
@@ -0,0 +1,377 @@
|
||||
#!/bin/bash
|
||||
# ReadFlow 跨平台打包发布脚本
|
||||
# 支持:macOS (Intel/Apple Silicon), Windows, Linux
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 ReadFlow 打包发布脚本"
|
||||
echo "========================"
|
||||
|
||||
# 配置
|
||||
APP_NAME="readflow"
|
||||
VERSION="0.1.0"
|
||||
AUTHOR="damai <damai@foshanhuiya.com>"
|
||||
DESCRIPTION="ReadFlow - 面向开发者和知识工作者的阅读工具"
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# 检测操作系统
|
||||
detect_os() {
|
||||
case "$(uname -s)" in
|
||||
Darwin)
|
||||
echo "macos"
|
||||
;;
|
||||
Linux)
|
||||
echo "linux"
|
||||
;;
|
||||
MINGW*|MSYS*|CYGWIN*)
|
||||
echo "windows"
|
||||
;;
|
||||
*)
|
||||
echo "unknown"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 检测 CPU 架构
|
||||
detect_arch() {
|
||||
case "$(uname -m)" in
|
||||
x86_64)
|
||||
echo "x86_64"
|
||||
;;
|
||||
arm64|aarch64)
|
||||
echo "aarch64"
|
||||
;;
|
||||
*)
|
||||
echo "unknown"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 构建 Release 版本
|
||||
build_release() {
|
||||
log_info "构建 Release 版本..."
|
||||
|
||||
# 清理之前的构建
|
||||
cargo clean
|
||||
|
||||
# 构建
|
||||
cargo build --release
|
||||
|
||||
log_info "构建完成!"
|
||||
}
|
||||
|
||||
# macOS 打包
|
||||
package_macos() {
|
||||
log_info "打包 macOS 应用..."
|
||||
|
||||
local arch=$(detect_arch)
|
||||
local target_dir="target/release"
|
||||
local package_dir="dist/${APP_NAME}-${VERSION}-macos-${arch}"
|
||||
local app_bundle="${package_dir}/${APP_NAME}.app"
|
||||
|
||||
# 创建目录结构
|
||||
mkdir -p "${app_bundle}/Contents/MacOS"
|
||||
mkdir -p "${app_bundle}/Contents/Resources"
|
||||
|
||||
# 复制二进制文件
|
||||
cp "${target_dir}/${APP_NAME}" "${app_bundle}/Contents/MacOS/"
|
||||
|
||||
# 创建 Info.plist
|
||||
cat > "${app_bundle}/Contents/Info.plist" << EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${APP_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.readflow.${APP_NAME}</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>ReadFlow</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>ReadFlow</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${VERSION}</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${VERSION}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
|
||||
# 创建 PkgInfo
|
||||
echo "APPL????" > "${app_bundle}/Contents/PkgInfo"
|
||||
|
||||
# 复制资源文件
|
||||
if [ -d "assets" ]; then
|
||||
cp -r assets "${app_bundle}/Contents/Resources/"
|
||||
fi
|
||||
|
||||
# 创建 DMG (需要 create-dmg)
|
||||
if command -v create-dmg &> /dev/null; then
|
||||
log_info "创建 DMG 文件..."
|
||||
create-dmg \
|
||||
--volname "ReadFlow" \
|
||||
--window-pos 200 120 \
|
||||
--window-size 600 400 \
|
||||
--icon-size 100 \
|
||||
--app-drop-link 450 200 \
|
||||
"dist/${APP_NAME}-${VERSION}-macos-${arch}.dmg" \
|
||||
"${app_bundle}"
|
||||
else
|
||||
log_warn "create-dmg 未安装,跳过 DMG 创建"
|
||||
log_info "安装包位于:${package_dir}"
|
||||
fi
|
||||
|
||||
log_info "macOS 打包完成!"
|
||||
}
|
||||
|
||||
# Linux 打包
|
||||
package_linux() {
|
||||
log_info "打包 Linux 应用..."
|
||||
|
||||
local arch=$(detect_arch)
|
||||
local target_dir="target/release"
|
||||
local package_dir="dist/${APP_NAME}-${VERSION}-linux-${arch}"
|
||||
|
||||
mkdir -p "${package_dir}"
|
||||
|
||||
# 复制二进制文件
|
||||
cp "${target_dir}/${APP_NAME}" "${package_dir}/"
|
||||
|
||||
# 创建 .desktop 文件
|
||||
cat > "${package_dir}/${APP_NAME}.desktop" << EOF
|
||||
[Desktop Entry]
|
||||
Name=ReadFlow
|
||||
Comment=${DESCRIPTION}
|
||||
Exec=${APP_NAME}
|
||||
Icon=${APP_NAME}
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Utility;Reading;
|
||||
EOF
|
||||
|
||||
# 创建 AppImage (需要 appimagetool)
|
||||
if command -v appimagetool &> /dev/null; then
|
||||
log_info "创建 AppImage..."
|
||||
# AppDir 结构
|
||||
local appdir="${package_dir}/AppDir"
|
||||
mkdir -p "${appdir}/usr/bin"
|
||||
mkdir -p "${appdir}/usr/share/applications"
|
||||
|
||||
cp "${target_dir}/${APP_NAME}" "${appdir}/usr/bin/"
|
||||
cp "${package_dir}/${APP_NAME}.desktop" "${appdir}/usr/share/applications/"
|
||||
|
||||
# 创建 AppRun
|
||||
cat > "${appdir}/AppRun" << EOF
|
||||
#!/bin/bash
|
||||
exec "\$(dirname "\$0")/usr/bin/${APP_NAME}" "\$@"
|
||||
EOF
|
||||
chmod +x "${appdir}/AppRun"
|
||||
|
||||
appimagetool "${appdir}" "dist/${APP_NAME}-${VERSION}-linux-${arch}.AppImage"
|
||||
else
|
||||
log_warn "appimagetool 未安装,跳过 AppImage 创建"
|
||||
fi
|
||||
|
||||
# 创建 tar.gz
|
||||
cd dist
|
||||
tar -czf "${APP_NAME}-${VERSION}-linux-${arch}.tar.gz" "${APP_NAME}-${VERSION}-linux-${arch}"
|
||||
cd ..
|
||||
|
||||
log_info "Linux 打包完成!"
|
||||
}
|
||||
|
||||
# Windows 打包
|
||||
package_windows() {
|
||||
log_info "打包 Windows 应用..."
|
||||
|
||||
local target_dir="target/release"
|
||||
local package_dir="dist/${APP_NAME}-${VERSION}-windows-x86_64"
|
||||
|
||||
mkdir -p "${package_dir}"
|
||||
|
||||
# 复制二进制文件
|
||||
cp "${target_dir}/${APP_NAME}.exe" "${package_dir}/"
|
||||
|
||||
# 复制依赖 DLL (如果需要)
|
||||
# cp "${target_dir}"/*.dll "${package_dir}/" 2>/dev/null || true
|
||||
|
||||
# 创建 NSIS 安装脚本 (需要 nsis)
|
||||
if command -v makensis &> /dev/null; then
|
||||
log_info "创建 NSIS 安装程序..."
|
||||
cat > "installer.nsi" << EOF
|
||||
!include "MUI2.nsh"
|
||||
|
||||
Name "ReadFlow"
|
||||
OutFile "dist/${APP_NAME}-${VERSION}-windows-x86_64-installer.exe"
|
||||
InstallDir "\$PROGRAMFILES\\ReadFlow"
|
||||
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
Section "Install"
|
||||
SetOutPath "\$INSTDIR"
|
||||
File "${package_dir}\\${APP_NAME}.exe"
|
||||
WriteUninstaller "\$INSTDIR\\uninstall.exe"
|
||||
|
||||
CreateDirectory "\$SMPROGRAMS\\ReadFlow"
|
||||
CreateShortCut "\$SMPROGRAMS\\ReadFlow\\ReadFlow.lnk" "\$INSTDIR\\${APP_NAME}.exe"
|
||||
CreateShortCut "\$DESKTOP\\ReadFlow.lnk" "\$INSTDIR\\${APP_NAME}.exe"
|
||||
SectionEnd
|
||||
|
||||
Section "Uninstall"
|
||||
Delete "\$INSTDIR\\${APP_NAME}.exe"
|
||||
Delete "\$INSTDIR\\uninstall.exe"
|
||||
RMDir "\$INSTDIR"
|
||||
|
||||
Delete "\$SMPROGRAMS\\ReadFlow\\ReadFlow.lnk"
|
||||
RMDir "\$SMPROGRAMS\\ReadFlow"
|
||||
|
||||
Delete "\$DESKTOP\\ReadFlow.lnk"
|
||||
SectionEnd
|
||||
EOF
|
||||
|
||||
makensis installer.nsi
|
||||
rm installer.nsi
|
||||
else
|
||||
log_warn "nsis 未安装,跳过安装程序创建"
|
||||
fi
|
||||
|
||||
# 创建 ZIP
|
||||
cd dist
|
||||
zip -r "${APP_NAME}-${VERSION}-windows-x86_64.zip" "${APP_NAME}-${VERSION}-windows-x86_64"
|
||||
cd ..
|
||||
|
||||
log_info "Windows 打包完成!"
|
||||
}
|
||||
|
||||
# 创建发布说明
|
||||
create_release_notes() {
|
||||
log_info "创建发布说明..."
|
||||
|
||||
cat > "dist/RELEASE.md" << EOF
|
||||
# ReadFlow v${VERSION} 发布说明
|
||||
|
||||
## 下载
|
||||
|
||||
### macOS
|
||||
- [Intel](${APP_NAME}-${VERSION}-macos-x86_64.dmg)
|
||||
- [Apple Silicon](${APP_NAME}-${VERSION}-macos-aarch64.dmg)
|
||||
|
||||
### Linux
|
||||
- [AppImage](${APP_NAME}-${VERSION}-linux-x86_64.AppImage)
|
||||
- [tar.gz](${APP_NAME}-${VERSION}-linux-x86_64.tar.gz)
|
||||
|
||||
### Windows
|
||||
- [Installer](${APP_NAME}-${VERSION}-windows-x86_64-installer.exe)
|
||||
- [Portable](${APP_NAME}-${VERSION}-windows-x86_64.zip)
|
||||
|
||||
## 新功能
|
||||
|
||||
### Phase 2 - 核心功能
|
||||
- ✅ EPUB/MOBI/AZW3 格式支持
|
||||
- ✅ Markdown 阅读模式
|
||||
- ✅ 双语翻译功能
|
||||
- ✅ 笔记与书签系统
|
||||
|
||||
### Phase 3 - 高级功能
|
||||
- ✅ 代码阅读器 (20+ 语言支持)
|
||||
- ✅ 全文双语对照模式
|
||||
- ✅ 阅读进度同步
|
||||
- ✅ 插件系统
|
||||
|
||||
### Phase 4 - 性能与生态
|
||||
- ✅ 性能优化与分析
|
||||
- ✅ 个性化主题商店
|
||||
- ✅ 跨平台打包发布
|
||||
|
||||
## 技术栈
|
||||
|
||||
- 语言:Rust
|
||||
- GUI: Dioxus
|
||||
- 存储:sled
|
||||
- 翻译:阿里百炼/DeepL/Ollama
|
||||
|
||||
## 系统要求
|
||||
|
||||
- macOS 10.15+
|
||||
- Windows 10+
|
||||
- Linux (glibc 2.31+)
|
||||
|
||||
## 反馈与支持
|
||||
|
||||
- GitHub: https://github.com/damai/readflow
|
||||
- Email: damai@foshanhuiya.com
|
||||
|
||||
---
|
||||
发布日期:$(date +%Y-%m-%d)
|
||||
EOF
|
||||
|
||||
log_info "发布说明已创建:dist/RELEASE.md"
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
local os=$(detect_os)
|
||||
|
||||
log_info "检测到操作系统:${os}"
|
||||
|
||||
# 构建
|
||||
build_release
|
||||
|
||||
# 根据操作系统打包
|
||||
case "${os}" in
|
||||
macos)
|
||||
package_macos
|
||||
;;
|
||||
linux)
|
||||
package_linux
|
||||
;;
|
||||
windows)
|
||||
package_windows
|
||||
;;
|
||||
*)
|
||||
log_error "不支持的操作系统:${os}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# 创建发布说明
|
||||
create_release_notes
|
||||
|
||||
log_info "🎉 打包完成!"
|
||||
log_info "发布文件位于:dist/"
|
||||
|
||||
# 列出生成的文件
|
||||
echo ""
|
||||
echo "生成的文件:"
|
||||
ls -lh dist/
|
||||
}
|
||||
|
||||
# 运行主函数
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user