Browse Source

发布和构建脚本

黄中银 1 month ago
parent
commit
5feceaf5d4
4 changed files with 1078 additions and 7 deletions
  1. 78 7
      ApqInstaller/package.json
  2. 249 0
      ApqInstaller/scripts/README.md
  3. 294 0
      ApqInstaller/scripts/build.js
  4. 457 0
      ApqInstaller/scripts/release.js

+ 78 - 7
ApqInstaller/package.json

@@ -10,7 +10,15 @@
     "electron:dev": "vite --mode electron",
     "electron:build": "vite build && electron-builder",
     "typecheck": "vue-tsc --noEmit",
-    "lint": "eslint . --fix"
+    "lint": "eslint . --fix",
+    "build:win": "node scripts/build.js -p win",
+    "build:mac": "node scripts/build.js -p mac",
+    "build:linux": "node scripts/build.js -p linux",
+    "build:all": "node scripts/build.js -p all",
+    "release": "node scripts/release.js",
+    "release:patch": "node scripts/release.js patch --tag",
+    "release:minor": "node scripts/release.js minor --tag",
+    "release:major": "node scripts/release.js major --tag"
   },
   "dependencies": {
     "@element-plus/icons-vue": "^2.3.1",
@@ -46,6 +54,7 @@
   "build": {
     "appId": "com.claude.ai.installer",
     "productName": "Claude AI Installer",
+    "artifactName": "${productName}-${version}-${os}-${arch}.${ext}",
     "directories": {
       "output": "release"
     },
@@ -61,21 +70,83 @@
     ],
     "win": {
       "target": [
-        "nsis"
+        {
+          "target": "nsis",
+          "arch": ["x64"]
+        },
+        {
+          "target": "portable",
+          "arch": ["x64"]
+        }
       ],
-      "icon": "public/icons/win/icon.ico"
+      "icon": "public/icons/win/icon.ico",
+      "publisherName": "Claude AI"
+    },
+    "nsis": {
+      "oneClick": false,
+      "perMachine": false,
+      "allowToChangeInstallationDirectory": true,
+      "deleteAppDataOnUninstall": false,
+      "installerIcon": "public/icons/win/icon.ico",
+      "uninstallerIcon": "public/icons/win/icon.ico",
+      "installerHeaderIcon": "public/icons/win/icon.ico",
+      "createDesktopShortcut": true,
+      "createStartMenuShortcut": true,
+      "shortcutName": "Claude AI Installer"
     },
     "mac": {
       "target": [
-        "dmg"
+        {
+          "target": "dmg",
+          "arch": ["x64", "arm64"]
+        },
+        {
+          "target": "zip",
+          "arch": ["x64", "arm64"]
+        }
+      ],
+      "icon": "public/icons/mac/icon.icns",
+      "category": "public.app-category.developer-tools",
+      "hardenedRuntime": true,
+      "gatekeeperAssess": false
+    },
+    "dmg": {
+      "contents": [
+        {
+          "x": 130,
+          "y": 220
+        },
+        {
+          "x": 410,
+          "y": 220,
+          "type": "link",
+          "path": "/Applications"
+        }
       ],
-      "icon": "public/icons/mac/icon.icns"
+      "window": {
+        "width": 540,
+        "height": 380
+      }
     },
     "linux": {
       "target": [
-        "AppImage"
+        {
+          "target": "AppImage",
+          "arch": ["x64"]
+        },
+        {
+          "target": "deb",
+          "arch": ["x64"]
+        },
+        {
+          "target": "rpm",
+          "arch": ["x64"]
+        }
       ],
-      "icon": "public/icons/png"
+      "icon": "public/icons/png",
+      "category": "Development",
+      "maintainer": "Claude AI <[email protected]>",
+      "vendor": "Claude AI"
     }
   }
 }

+ 249 - 0
ApqInstaller/scripts/README.md

@@ -0,0 +1,249 @@
+# 构建与发布脚本
+
+本目录包含 Claude AI Installer 的构建和发布脚本。
+
+## 快速开始
+
+```bash
+# 进入项目目录
+cd ApqInstaller
+
+# 安装依赖
+npm install
+
+# 构建当前平台
+npm run build:win      # Windows
+npm run build:mac      # macOS
+npm run build:linux    # Linux
+npm run build:all      # 所有平台
+```
+
+## 脚本说明
+
+### build.js - 构建脚本
+
+多平台构建脚本,用于编译和打包应用。
+
+#### 用法
+
+```bash
+node scripts/build.js [选项]
+```
+
+#### 选项
+
+| 选项 | 简写 | 说明 | 默认值 |
+|------|------|------|--------|
+| `--platform` | `-p` | 目标平台: `win`, `mac`, `linux`, `all` | 当前平台 |
+| `--arch` | `-a` | 目标架构: `x64`, `arm64`, `all` | 当前架构 |
+| `--publish` | `-P` | 发布模式: `always`, `onTag`, `never` | `never` |
+| `--skip-build` | - | 跳过前端构建,仅打包 | - |
+| `--help` | `-h` | 显示帮助信息 | - |
+
+#### 示例
+
+```bash
+# 构建 Windows 版本
+node scripts/build.js -p win
+
+# 构建 macOS ARM64 版本
+node scripts/build.js -p mac -a arm64
+
+# 构建所有平台
+node scripts/build.js -p all
+
+# 跳过前端构建,仅打包
+node scripts/build.js -p win --skip-build
+```
+
+---
+
+### release.js - 发布脚本
+
+自动化发布脚本,支持版本更新、构建、Git tag 创建。
+
+#### 用法
+
+```bash
+node scripts/release.js [版本] [选项]
+```
+
+#### 版本参数
+
+| 参数 | 说明 | 示例 |
+|------|------|------|
+| `patch` | 补丁版本 +1 | 0.0.1 → 0.0.2 |
+| `minor` | 次版本 +1 | 0.0.1 → 0.1.0 |
+| `major` | 主版本 +1 | 0.0.1 → 1.0.0 |
+| `x.y.z` | 指定版本号 | 1.2.3 |
+
+#### 选项
+
+| 选项 | 简写 | 说明 |
+|------|------|------|
+| `--tag` | `-t` | 创建 Git tag |
+| `--push` | - | 推送 tag 到远程仓库 |
+| `--platform` | `-p` | 指定平台 (逗号分隔) |
+| `--dry-run` | - | 仅显示操作,不实际执行 |
+| `--help` | `-h` | 显示帮助信息 |
+
+#### 示例
+
+```bash
+# 更新补丁版本并构建
+node scripts/release.js patch
+
+# 设置版本为 1.0.0 并创建 tag
+node scripts/release.js 1.0.0 --tag
+
+# 更新次版本,仅构建 Windows 和 macOS
+node scripts/release.js minor -p win,mac
+
+# 完整发布流程:更新版本、构建、创建 tag、推送
+node scripts/release.js patch --tag --push
+
+# 预览发布操作(不实际执行)
+node scripts/release.js patch --dry-run
+```
+
+---
+
+## NPM Scripts
+
+在 `package.json` 中预定义了以下命令:
+
+### 构建命令
+
+| 命令 | 说明 |
+|------|------|
+| `npm run build:win` | 构建 Windows 版本 |
+| `npm run build:mac` | 构建 macOS 版本 |
+| `npm run build:linux` | 构建 Linux 版本 |
+| `npm run build:all` | 构建所有平台 |
+
+### 发布命令
+
+| 命令 | 说明 |
+|------|------|
+| `npm run release` | 发布(不更新版本) |
+| `npm run release:patch` | 发布补丁版本 + 创建 tag |
+| `npm run release:minor` | 发布次版本 + 创建 tag |
+| `npm run release:major` | 发布主版本 + 创建 tag |
+
+---
+
+## 构建产物
+
+构建完成后,安装包会输出到 `release/` 目录:
+
+### Windows
+
+| 格式 | 文件名 | 说明 |
+|------|--------|------|
+| NSIS | `Claude AI Installer-x.x.x-win-x64.exe` | 安装程序 |
+| Portable | `Claude AI Installer-x.x.x-win-x64.exe` | 便携版 |
+
+### macOS
+
+| 格式 | 文件名 | 说明 |
+|------|--------|------|
+| DMG | `Claude AI Installer-x.x.x-mac-x64.dmg` | Intel 版 |
+| DMG | `Claude AI Installer-x.x.x-mac-arm64.dmg` | Apple Silicon 版 |
+| ZIP | `Claude AI Installer-x.x.x-mac-x64.zip` | Intel 压缩包 |
+| ZIP | `Claude AI Installer-x.x.x-mac-arm64.zip` | Apple Silicon 压缩包 |
+
+### Linux
+
+| 格式 | 文件名 | 说明 |
+|------|--------|------|
+| AppImage | `Claude AI Installer-x.x.x-linux-x64.AppImage` | 通用格式 |
+| DEB | `Claude AI Installer-x.x.x-linux-x64.deb` | Debian/Ubuntu |
+| RPM | `Claude AI Installer-x.x.x-linux-x64.rpm` | Fedora/RHEL |
+
+---
+
+## 跨平台构建注意事项
+
+### 在 Windows 上构建
+
+- **Windows**: 原生支持
+- **macOS**: 不支持(需要 macOS 系统)
+- **Linux**: 需要 WSL 或 Docker
+
+### 在 macOS 上构建
+
+- **Windows**: 需要安装 Wine (`brew install --cask wine-stable`)
+- **macOS**: 原生支持
+- **Linux**: 原生支持
+
+### 在 Linux 上构建
+
+- **Windows**: 需要安装 Wine
+- **macOS**: 不支持(需要 macOS 系统)
+- **Linux**: 原生支持
+
+### 使用 CI/CD 构建所有平台
+
+推荐使用 GitHub Actions 等 CI/CD 服务在各自平台的 runner 上构建:
+
+```yaml
+# .github/workflows/build.yml 示例
+jobs:
+  build:
+    strategy:
+      matrix:
+        os: [windows-latest, macos-latest, ubuntu-latest]
+    runs-on: ${{ matrix.os }}
+    steps:
+      - uses: actions/checkout@v4
+      - uses: actions/setup-node@v4
+      - run: npm install
+      - run: npm run build
+```
+
+---
+
+## 发布流程
+
+### 标准发布流程
+
+1. 确保所有更改已提交
+2. 运行发布命令:
+   ```bash
+   npm run release:patch  # 或 minor/major
+   ```
+3. 检查 `release/` 目录中的构建产物
+4. 手动推送(如果没有使用 `--push`):
+   ```bash
+   git push && git push --tags
+   ```
+5. 在 GitHub 创建 Release,上传构建产物
+
+### 自动发布流程
+
+```bash
+# 一键完成:更新版本 → 构建 → 创建 tag → 推送
+node scripts/release.js patch --tag --push
+```
+
+---
+
+## 故障排除
+
+### 构建失败
+
+1. 确保已安装所有依赖:`npm install`
+2. 清理旧的构建文件:删除 `dist/` 和 `dist-electron/` 目录
+3. 检查 Node.js 版本(推荐 18+)
+
+### 图标问题
+
+确保以下图标文件存在:
+- Windows: `public/icons/win/icon.ico`
+- macOS: `public/icons/mac/icon.icns`
+- Linux: `public/icons/png/` (包含各尺寸 PNG)
+
+### 签名问题
+
+- **Windows**: 需要代码签名证书(可选)
+- **macOS**: 需要 Apple Developer 证书进行公证(发布到 App Store 必需)

+ 294 - 0
ApqInstaller/scripts/build.js

@@ -0,0 +1,294 @@
+#!/usr/bin/env node
+
+/**
+ * 多平台构建脚本
+ * Multi-platform build script for Claude AI Installer
+ *
+ * 用法 / Usage:
+ *   node scripts/build.js [options]
+ *
+ * 选项 / Options:
+ *   --platform, -p    目标平台: win, mac, linux, all (默认: 当前平台)
+ *   --arch, -a        架构: x64, arm64, all (默认: 当前架构)
+ *   --publish, -P     发布模式: always, onTag, never (默认: never)
+ *   --skip-build      跳过前端构建,仅打包
+ *   --help, -h        显示帮助信息
+ */
+
+const { execSync, spawn } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+// 颜色输出
+const colors = {
+  reset: '\x1b[0m',
+  bright: '\x1b[1m',
+  red: '\x1b[31m',
+  green: '\x1b[32m',
+  yellow: '\x1b[33m',
+  blue: '\x1b[34m',
+  cyan: '\x1b[36m',
+};
+
+const log = {
+  info: (msg) => console.log(`${colors.blue}ℹ${colors.reset} ${msg}`),
+  success: (msg) => console.log(`${colors.green}✔${colors.reset} ${msg}`),
+  warn: (msg) => console.log(`${colors.yellow}⚠${colors.reset} ${msg}`),
+  error: (msg) => console.log(`${colors.red}✖${colors.reset} ${msg}`),
+  step: (msg) => console.log(`\n${colors.cyan}${colors.bright}▶ ${msg}${colors.reset}`),
+};
+
+// 解析命令行参数
+function parseArgs() {
+  const args = process.argv.slice(2);
+  const options = {
+    platform: process.platform === 'win32' ? 'win' : process.platform === 'darwin' ? 'mac' : 'linux',
+    arch: process.arch,
+    publish: 'never',
+    skipBuild: false,
+    help: false,
+  };
+
+  for (let i = 0; i < args.length; i++) {
+    const arg = args[i];
+    switch (arg) {
+      case '--platform':
+      case '-p':
+        options.platform = args[++i];
+        break;
+      case '--arch':
+      case '-a':
+        options.arch = args[++i];
+        break;
+      case '--publish':
+      case '-P':
+        options.publish = args[++i];
+        break;
+      case '--skip-build':
+        options.skipBuild = true;
+        break;
+      case '--help':
+      case '-h':
+        options.help = true;
+        break;
+    }
+  }
+
+  return options;
+}
+
+// 显示帮助信息
+function showHelp() {
+  console.log(`
+${colors.bright}Claude AI Installer 构建脚本${colors.reset}
+
+${colors.cyan}用法:${colors.reset}
+  node scripts/build.js [options]
+
+${colors.cyan}选项:${colors.reset}
+  --platform, -p <platform>   目标平台
+                              win    - Windows (NSIS 安装包)
+                              mac    - macOS (DMG)
+                              linux  - Linux (AppImage)
+                              all    - 所有平台
+                              默认: 当前平台
+
+  --arch, -a <arch>           目标架构
+                              x64    - 64位 Intel/AMD
+                              arm64  - ARM64 (Apple Silicon, etc.)
+                              all    - 所有架构
+                              默认: 当前架构
+
+  --publish, -P <mode>        发布模式
+                              always - 总是发布
+                              onTag  - 仅在 Git tag 时发布
+                              never  - 不发布 (默认)
+
+  --skip-build                跳过前端构建,仅执行打包
+
+  --help, -h                  显示此帮助信息
+
+${colors.cyan}示例:${colors.reset}
+  node scripts/build.js                          # 构建当前平台
+  node scripts/build.js -p win                   # 构建 Windows 版本
+  node scripts/build.js -p mac -a arm64          # 构建 macOS ARM64 版本
+  node scripts/build.js -p all                   # 构建所有平台
+  node scripts/build.js -p win -P always         # 构建并发布 Windows 版本
+`);
+}
+
+// 执行命令
+function exec(command, options = {}) {
+  log.info(`执行: ${command}`);
+  try {
+    execSync(command, {
+      stdio: 'inherit',
+      cwd: path.resolve(__dirname, '..'),
+      ...options,
+    });
+    return true;
+  } catch (error) {
+    log.error(`命令执行失败: ${command}`);
+    return false;
+  }
+}
+
+// 获取 electron-builder 平台参数
+function getPlatformArgs(platform, arch) {
+  const platformMap = {
+    win: '--win',
+    mac: '--mac',
+    linux: '--linux',
+  };
+
+  const archMap = {
+    x64: '--x64',
+    arm64: '--arm64',
+    all: '--x64 --arm64',
+  };
+
+  let args = [];
+
+  if (platform === 'all') {
+    args.push('--win', '--mac', '--linux');
+  } else {
+    args.push(platformMap[platform] || platformMap.win);
+  }
+
+  if (arch && arch !== 'all') {
+    args.push(archMap[arch] || '');
+  } else if (arch === 'all') {
+    args.push('--x64', '--arm64');
+  }
+
+  return args.join(' ');
+}
+
+// 清理旧的构建文件
+function cleanBuild() {
+  log.step('清理旧的构建文件...');
+
+  const dirsToClean = ['dist', 'dist-electron'];
+  const projectRoot = path.resolve(__dirname, '..');
+
+  for (const dir of dirsToClean) {
+    const fullPath = path.join(projectRoot, dir);
+    if (fs.existsSync(fullPath)) {
+      fs.rmSync(fullPath, { recursive: true, force: true });
+      log.info(`已删除: ${dir}`);
+    }
+  }
+
+  log.success('清理完成');
+}
+
+// 类型检查
+function typeCheck() {
+  log.step('执行类型检查...');
+  if (!exec('npx vue-tsc --noEmit')) {
+    throw new Error('类型检查失败');
+  }
+  log.success('类型检查通过');
+}
+
+// 构建前端
+function buildFrontend() {
+  log.step('构建前端资源...');
+  if (!exec('npx vite build')) {
+    throw new Error('前端构建失败');
+  }
+  log.success('前端构建完成');
+}
+
+// 打包 Electron 应用
+function packageApp(options) {
+  log.step(`打包应用 (平台: ${options.platform}, 架构: ${options.arch})...`);
+
+  const platformArgs = getPlatformArgs(options.platform, options.arch);
+  const publishArg = options.publish !== 'never' ? `--publish ${options.publish}` : '';
+
+  const command = `npx electron-builder ${platformArgs} ${publishArg}`.trim();
+
+  if (!exec(command)) {
+    throw new Error('应用打包失败');
+  }
+
+  log.success('应用打包完成');
+}
+
+// 显示构建结果
+function showResults() {
+  log.step('构建结果:');
+
+  const releaseDir = path.resolve(__dirname, '..', 'release');
+
+  if (!fs.existsSync(releaseDir)) {
+    log.warn('release 目录不存在');
+    return;
+  }
+
+  const files = fs.readdirSync(releaseDir);
+  const packages = files.filter(f => {
+    const ext = path.extname(f).toLowerCase();
+    return ['.exe', '.dmg', '.appimage', '.deb', '.rpm', '.zip'].includes(ext);
+  });
+
+  if (packages.length === 0) {
+    log.warn('未找到打包文件');
+    return;
+  }
+
+  console.log('');
+  for (const pkg of packages) {
+    const filePath = path.join(releaseDir, pkg);
+    const stats = fs.statSync(filePath);
+    const sizeMB = (stats.size / (1024 * 1024)).toFixed(2);
+    console.log(`  ${colors.green}•${colors.reset} ${pkg} (${sizeMB} MB)`);
+  }
+  console.log('');
+  log.info(`输出目录: ${releaseDir}`);
+}
+
+// 主函数
+async function main() {
+  const options = parseArgs();
+
+  if (options.help) {
+    showHelp();
+    process.exit(0);
+  }
+
+  console.log(`
+${colors.bright}╔════════════════════════════════════════════╗
+║     Claude AI Installer 构建脚本           ║
+╚════════════════════════════════════════════╝${colors.reset}
+`);
+
+  log.info(`目标平台: ${options.platform}`);
+  log.info(`目标架构: ${options.arch}`);
+  log.info(`发布模式: ${options.publish}`);
+
+  const startTime = Date.now();
+
+  try {
+    if (!options.skipBuild) {
+      cleanBuild();
+      typeCheck();
+      buildFrontend();
+    } else {
+      log.warn('跳过前端构建');
+    }
+
+    packageApp(options);
+    showResults();
+
+    const duration = ((Date.now() - startTime) / 1000).toFixed(1);
+    log.success(`构建完成! 耗时: ${duration}s`);
+
+  } catch (error) {
+    log.error(error.message);
+    process.exit(1);
+  }
+}
+
+main();

+ 457 - 0
ApqInstaller/scripts/release.js

@@ -0,0 +1,457 @@
+#!/usr/bin/env node
+
+/**
+ * 发布脚本
+ * Release script for Claude AI Installer
+ *
+ * 功能:
+ * - 自动更新版本号
+ * - 构建所有平台的安装包
+ * - 生成发布说明
+ * - 可选: 创建 Git tag 并推送
+ *
+ * 用法 / Usage:
+ *   node scripts/release.js [version] [options]
+ *
+ * 示例:
+ *   node scripts/release.js patch          # 0.0.1 -> 0.0.2
+ *   node scripts/release.js minor          # 0.0.1 -> 0.1.0
+ *   node scripts/release.js major          # 0.0.1 -> 1.0.0
+ *   node scripts/release.js 1.2.3          # 设置为指定版本
+ *   node scripts/release.js patch --tag    # 更新版本并创建 Git tag
+ */
+
+const { execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+// 颜色输出
+const colors = {
+  reset: '\x1b[0m',
+  bright: '\x1b[1m',
+  red: '\x1b[31m',
+  green: '\x1b[32m',
+  yellow: '\x1b[33m',
+  blue: '\x1b[34m',
+  cyan: '\x1b[36m',
+  magenta: '\x1b[35m',
+};
+
+const log = {
+  info: (msg) => console.log(`${colors.blue}ℹ${colors.reset} ${msg}`),
+  success: (msg) => console.log(`${colors.green}✔${colors.reset} ${msg}`),
+  warn: (msg) => console.log(`${colors.yellow}⚠${colors.reset} ${msg}`),
+  error: (msg) => console.log(`${colors.red}✖${colors.reset} ${msg}`),
+  step: (msg) => console.log(`\n${colors.cyan}${colors.bright}▶ ${msg}${colors.reset}`),
+};
+
+const projectRoot = path.resolve(__dirname, '..');
+const packageJsonPath = path.join(projectRoot, 'package.json');
+
+// 解析命令行参数
+function parseArgs() {
+  const args = process.argv.slice(2);
+  const options = {
+    version: null,
+    tag: false,
+    push: false,
+    platforms: ['win', 'mac', 'linux'],
+    dryRun: false,
+    help: false,
+  };
+
+  for (let i = 0; i < args.length; i++) {
+    const arg = args[i];
+    switch (arg) {
+      case '--tag':
+      case '-t':
+        options.tag = true;
+        break;
+      case '--push':
+        options.push = true;
+        break;
+      case '--platform':
+      case '-p':
+        options.platforms = args[++i].split(',');
+        break;
+      case '--dry-run':
+        options.dryRun = true;
+        break;
+      case '--help':
+      case '-h':
+        options.help = true;
+        break;
+      default:
+        if (!arg.startsWith('-') && !options.version) {
+          options.version = arg;
+        }
+    }
+  }
+
+  return options;
+}
+
+// 显示帮助信息
+function showHelp() {
+  console.log(`
+${colors.bright}Claude AI Installer 发布脚本${colors.reset}
+
+${colors.cyan}用法:${colors.reset}
+  node scripts/release.js [version] [options]
+
+${colors.cyan}版本参数:${colors.reset}
+  patch              补丁版本 (0.0.1 -> 0.0.2)
+  minor              次版本 (0.0.1 -> 0.1.0)
+  major              主版本 (0.0.1 -> 1.0.0)
+  x.y.z              指定版本号
+
+${colors.cyan}选项:${colors.reset}
+  --tag, -t          创建 Git tag
+  --push             推送 tag 到远程仓库
+  --platform, -p     指定平台 (逗号分隔): win,mac,linux
+  --dry-run          仅显示将要执行的操作,不实际执行
+  --help, -h         显示此帮助信息
+
+${colors.cyan}示例:${colors.reset}
+  node scripts/release.js patch                    # 更新补丁版本并构建
+  node scripts/release.js 1.0.0 --tag              # 设置版本为 1.0.0 并创建 tag
+  node scripts/release.js minor -p win,mac         # 更新次版本,仅构建 Win 和 Mac
+  node scripts/release.js patch --tag --push       # 更新版本、创建 tag 并推送
+`);
+}
+
+// 读取 package.json
+function readPackageJson() {
+  return JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
+}
+
+// 写入 package.json
+function writePackageJson(pkg) {
+  fs.writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + '\n');
+}
+
+// 计算新版本号
+function calculateNewVersion(currentVersion, versionArg) {
+  if (!versionArg) {
+    return currentVersion;
+  }
+
+  // 如果是具体版本号
+  if (/^\d+\.\d+\.\d+/.test(versionArg)) {
+    return versionArg;
+  }
+
+  const parts = currentVersion.split('.').map(Number);
+
+  switch (versionArg) {
+    case 'major':
+      return `${parts[0] + 1}.0.0`;
+    case 'minor':
+      return `${parts[0]}.${parts[1] + 1}.0`;
+    case 'patch':
+      return `${parts[0]}.${parts[1]}.${parts[2] + 1}`;
+    default:
+      throw new Error(`无效的版本参数: ${versionArg}`);
+  }
+}
+
+// 执行命令
+function exec(command, options = {}) {
+  log.info(`执行: ${command}`);
+  try {
+    return execSync(command, {
+      stdio: options.silent ? 'pipe' : 'inherit',
+      cwd: projectRoot,
+      encoding: 'utf-8',
+      ...options,
+    });
+  } catch (error) {
+    if (!options.ignoreError) {
+      throw error;
+    }
+    return null;
+  }
+}
+
+// 检查 Git 状态
+function checkGitStatus() {
+  log.step('检查 Git 状态...');
+
+  try {
+    const status = execSync('git status --porcelain', {
+      cwd: projectRoot,
+      encoding: 'utf-8',
+    });
+
+    if (status.trim()) {
+      log.warn('工作目录有未提交的更改:');
+      console.log(status);
+      return false;
+    }
+
+    log.success('Git 工作目录干净');
+    return true;
+  } catch (error) {
+    log.warn('无法检查 Git 状态');
+    return true;
+  }
+}
+
+// 更新版本号
+function updateVersion(newVersion, dryRun) {
+  log.step(`更新版本号到 ${newVersion}...`);
+
+  if (dryRun) {
+    log.info('[DRY RUN] 将更新 package.json 版本号');
+    return;
+  }
+
+  const pkg = readPackageJson();
+  pkg.version = newVersion;
+  writePackageJson(pkg);
+
+  log.success(`版本号已更新: ${newVersion}`);
+}
+
+// 构建所有平台
+function buildAllPlatforms(platforms, dryRun) {
+  log.step('构建应用...');
+
+  for (const platform of platforms) {
+    log.info(`构建 ${platform} 平台...`);
+
+    if (dryRun) {
+      log.info(`[DRY RUN] 将构建 ${platform} 平台`);
+      continue;
+    }
+
+    exec(`node scripts/build.js -p ${platform}`);
+  }
+
+  log.success('所有平台构建完成');
+}
+
+// 创建 Git tag
+function createGitTag(version, dryRun) {
+  log.step(`创建 Git tag v${version}...`);
+
+  if (dryRun) {
+    log.info(`[DRY RUN] 将创建 tag: v${version}`);
+    return;
+  }
+
+  // 提交版本更新
+  exec('git add package.json');
+  exec(`git commit -m "chore: release v${version}"`);
+
+  // 创建 tag
+  exec(`git tag -a v${version} -m "Release v${version}"`);
+
+  log.success(`Git tag v${version} 已创建`);
+}
+
+// 推送到远程
+function pushToRemote(version, dryRun) {
+  log.step('推送到远程仓库...');
+
+  if (dryRun) {
+    log.info('[DRY RUN] 将推送 commits 和 tags');
+    return;
+  }
+
+  exec('git push');
+  exec('git push --tags');
+
+  log.success('已推送到远程仓库');
+}
+
+// 生成发布说明
+function generateReleaseNotes(version) {
+  log.step('生成发布说明...');
+
+  const releaseDir = path.join(projectRoot, 'release');
+  const notesPath = path.join(releaseDir, `RELEASE_NOTES_v${version}.md`);
+
+  // 获取最近的 commits
+  let commits = '';
+  try {
+    commits = execSync('git log --oneline -20', {
+      cwd: projectRoot,
+      encoding: 'utf-8',
+    });
+  } catch (e) {
+    commits = '无法获取提交历史';
+  }
+
+  // 获取构建产物列表
+  let artifacts = [];
+  if (fs.existsSync(releaseDir)) {
+    artifacts = fs.readdirSync(releaseDir).filter(f => {
+      const ext = path.extname(f).toLowerCase();
+      return ['.exe', '.dmg', '.appimage', '.deb', '.rpm', '.zip'].includes(ext);
+    });
+  }
+
+  const notes = `# Claude AI Installer v${version}
+
+## 发布日期
+${new Date().toISOString().split('T')[0]}
+
+## 下载
+
+${artifacts.map(a => `- ${a}`).join('\n') || '暂无构建产物'}
+
+## 平台支持
+
+| 平台 | 文件格式 | 架构 |
+|------|----------|------|
+| Windows | NSIS 安装包 (.exe) | x64 |
+| macOS | DMG 镜像 (.dmg) | x64, arm64 |
+| Linux | AppImage (.AppImage) | x64 |
+
+## 更新内容
+
+请查看提交历史了解详细更新内容。
+
+## 最近提交
+
+\`\`\`
+${commits}
+\`\`\`
+
+## 安装说明
+
+### Windows
+1. 下载 \`.exe\` 安装包
+2. 双击运行安装程序
+3. 按照向导完成安装
+
+### macOS
+1. 下载 \`.dmg\` 文件
+2. 双击打开 DMG 镜像
+3. 将应用拖拽到 Applications 文件夹
+
+### Linux
+1. 下载 \`.AppImage\` 文件
+2. 添加执行权限: \`chmod +x *.AppImage\`
+3. 双击运行或在终端执行
+
+---
+🤖 Generated with Claude AI Installer Build System
+`;
+
+  fs.writeFileSync(notesPath, notes);
+  log.success(`发布说明已生成: ${notesPath}`);
+}
+
+// 显示发布摘要
+function showSummary(version, platforms) {
+  const releaseDir = path.join(projectRoot, 'release');
+
+  console.log(`
+${colors.bright}╔════════════════════════════════════════════╗
+║           发布摘要 - v${version.padEnd(20)}║
+╚════════════════════════════════════════════╝${colors.reset}
+`);
+
+  if (fs.existsSync(releaseDir)) {
+    const files = fs.readdirSync(releaseDir).filter(f => {
+      const ext = path.extname(f).toLowerCase();
+      return ['.exe', '.dmg', '.appimage', '.deb', '.rpm', '.zip'].includes(ext);
+    });
+
+    if (files.length > 0) {
+      console.log(`${colors.cyan}构建产物:${colors.reset}`);
+      for (const file of files) {
+        const filePath = path.join(releaseDir, file);
+        const stats = fs.statSync(filePath);
+        const sizeMB = (stats.size / (1024 * 1024)).toFixed(2);
+        console.log(`  ${colors.green}•${colors.reset} ${file} (${sizeMB} MB)`);
+      }
+    }
+  }
+
+  console.log(`
+${colors.cyan}输出目录:${colors.reset} ${releaseDir}
+${colors.cyan}版本号:${colors.reset} v${version}
+${colors.cyan}构建平台:${colors.reset} ${platforms.join(', ')}
+`);
+}
+
+// 主函数
+async function main() {
+  const options = parseArgs();
+
+  if (options.help) {
+    showHelp();
+    process.exit(0);
+  }
+
+  console.log(`
+${colors.bright}${colors.magenta}╔════════════════════════════════════════════╗
+║     Claude AI Installer 发布脚本           ║
+╚════════════════════════════════════════════╝${colors.reset}
+`);
+
+  if (options.dryRun) {
+    log.warn('DRY RUN 模式 - 不会执行实际操作');
+  }
+
+  const startTime = Date.now();
+
+  try {
+    // 读取当前版本
+    const pkg = readPackageJson();
+    const currentVersion = pkg.version;
+    log.info(`当前版本: ${currentVersion}`);
+
+    // 计算新版本
+    const newVersion = calculateNewVersion(currentVersion, options.version);
+    log.info(`目标版本: ${newVersion}`);
+
+    // 检查 Git 状态
+    if (options.tag && !options.dryRun) {
+      const isClean = checkGitStatus();
+      if (!isClean) {
+        log.warn('建议先提交或暂存更改');
+      }
+    }
+
+    // 更新版本号
+    if (options.version) {
+      updateVersion(newVersion, options.dryRun);
+    }
+
+    // 构建所有平台
+    buildAllPlatforms(options.platforms, options.dryRun);
+
+    // 生成发布说明
+    if (!options.dryRun) {
+      generateReleaseNotes(newVersion);
+    }
+
+    // 创建 Git tag
+    if (options.tag) {
+      createGitTag(newVersion, options.dryRun);
+    }
+
+    // 推送到远程
+    if (options.push) {
+      pushToRemote(newVersion, options.dryRun);
+    }
+
+    // 显示摘要
+    if (!options.dryRun) {
+      showSummary(newVersion, options.platforms);
+    }
+
+    const duration = ((Date.now() - startTime) / 1000).toFixed(1);
+    log.success(`发布完成! 耗时: ${duration}s`);
+
+  } catch (error) {
+    log.error(error.message);
+    process.exit(1);
+  }
+}
+
+main();