Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
222 changes: 222 additions & 0 deletions .github/workflows/macos-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
name: macOS Build · app/ClaudeCodeHistory

# 构建 macOS 桌面应用 · 输出 .app 包 + .dmg
#
# 触发:
# - push 到 main 且动了 app/ 目录 → 构建 + 上传 artifact(不打 Release)
# - 打 tag v*.*.* → 构建 + 自动创建 GitHub Release 附 .dmg
# - workflow_dispatch → 手动触发
#
# 签名 / 公证逻辑:
# - 无 AC_* secret → 跳过签名,产出 unsigned .dmg(用户首次打开要右键绕 Gatekeeper)
# - 有 AC_* secret → 用 codesign + notarytool 签名 + 公证
# - 签名相关 secret:
# - AC_TEAM_ID · Apple Developer Team ID
# - AC_SIGNING_CERT · base64 编码的 .p12 证书
# - AC_SIGNING_CERT_PASSWORD · .p12 密码
# - AC_APPLE_ID · Apple ID 邮箱
# - AC_APPLE_ID_PASSWORD · App-specific password
#
# 说明:目前 secret 未配置,workflow 会走无签名分支;未来配好后自动切签名版。

on:
push:
branches: [main]
paths:
- 'app/**'
- '.github/workflows/macos-build.yml'
workflow_dispatch:
inputs:
create-release:
description: 是否创建 GitHub Release(非 tag 触发时用)
required: false
default: 'false'
push:
tags:
- 'v*.*.*'

permissions:
contents: write # 创建 Release 要写权限

jobs:
build:
name: Build macOS .app + .dmg
runs-on: macos-14 # Apple Silicon runner
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Select Xcode
run: sudo xcode-select -s /Applications/Xcode.app

- name: Show Xcode version
run: xcodebuild -version

- name: 检测签名 Secret 是否配置
id: check-signing
run: |
if [ -n "${{ secrets.AC_TEAM_ID }}" ] && [ -n "${{ secrets.AC_SIGNING_CERT }}" ]; then
echo "signing=true" >> $GITHUB_OUTPUT
echo "🔐 将使用 Apple Developer 证书签名 + 公证"
else
echo "signing=false" >> $GITHUB_OUTPUT
echo "⚠️ 无 AC_TEAM_ID / AC_SIGNING_CERT secret,产出未签名 .dmg"
echo " 用户首次打开需右键点'打开'绕过 Gatekeeper"
fi

# ============ 签名分支(有 Secret 时)============
- name: 导入签名证书(有 secret)
if: steps.check-signing.outputs.signing == 'true'
env:
SIGNING_CERT: ${{ secrets.AC_SIGNING_CERT }}
SIGNING_CERT_PASSWORD: ${{ secrets.AC_SIGNING_CERT_PASSWORD }}
run: |
# 解码 base64 证书
echo "$SIGNING_CERT" | base64 -d > /tmp/cert.p12

# 创建临时 keychain 避免污染 runner
KEYCHAIN="build.keychain"
security create-keychain -p "tempPass" "$KEYCHAIN"
security default-keychain -s "$KEYCHAIN"
security unlock-keychain -p "tempPass" "$KEYCHAIN"
security set-keychain-settings -t 3600 -l "$KEYCHAIN"

# 导入证书
security import /tmp/cert.p12 -k "$KEYCHAIN" \
-P "$SIGNING_CERT_PASSWORD" \
-T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "tempPass" "$KEYCHAIN"

# 清理 p12
rm -f /tmp/cert.p12

# ============ 构建 ============
- name: Build (xcodebuild archive)
working-directory: app
run: |
SIGNING=${{ steps.check-signing.outputs.signing }}

if [ "$SIGNING" = "true" ]; then
CODE_SIGN_ARGS="-allowProvisioningUpdates DEVELOPMENT_TEAM=${{ secrets.AC_TEAM_ID }} CODE_SIGN_STYLE=Automatic"
else
CODE_SIGN_ARGS="CODE_SIGN_IDENTITY=- CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO"
fi

xcodebuild \
-project ClaudeCodeHistory.xcodeproj \
-scheme ClaudeCodeHistory \
-configuration Release \
-destination 'generic/platform=macOS' \
-archivePath /tmp/build/ClaudeCodeHistory.xcarchive \
$CODE_SIGN_ARGS \
archive

- name: 导出 .app(有签名,正式)
if: steps.check-signing.outputs.signing == 'true'
working-directory: app
run: |
cat > /tmp/exportOptions.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>method</key><string>developer-id</string>
<key>teamID</key><string>${{ secrets.AC_TEAM_ID }}</string>
</dict>
</plist>
EOF
xcodebuild -exportArchive \
-archivePath /tmp/build/ClaudeCodeHistory.xcarchive \
-exportPath /tmp/build/export \
-exportOptionsPlist /tmp/exportOptions.plist

- name: 导出 .app(无签名,直接从 archive 拷贝)
if: steps.check-signing.outputs.signing == 'false'
run: |
mkdir -p /tmp/build/export
cp -r /tmp/build/ClaudeCodeHistory.xcarchive/Products/Applications/*.app /tmp/build/export/

# ============ 打包 .dmg ============
- name: 装 create-dmg 工具
run: brew install create-dmg

- name: 打包 .dmg
id: dmg
run: |
VERSION=${GITHUB_REF#refs/tags/v}
[ "$GITHUB_REF" = "$VERSION" ] && VERSION="0.0.0-dev"
DMG_NAME="EP-Code-AI-macOS-${VERSION}.dmg"
APP_PATH=$(ls -d /tmp/build/export/*.app | head -1)

create-dmg \
--volname "EP Code AI" \
--window-size 600 400 \
--icon-size 100 \
--icon "$(basename $APP_PATH)" 150 200 \
--app-drop-link 450 200 \
--hdiutil-quiet \
"/tmp/build/${DMG_NAME}" \
"$APP_PATH" || true # create-dmg 有时返回非零但文件已生成

ls -la /tmp/build/*.dmg
echo "dmg_path=/tmp/build/${DMG_NAME}" >> $GITHUB_OUTPUT
echo "dmg_name=${DMG_NAME}" >> $GITHUB_OUTPUT

# ============ 公证(有 secret 时)============
- name: Notarize(公证 · 有 secret)
if: steps.check-signing.outputs.signing == 'true'
env:
APPLE_ID: ${{ secrets.AC_APPLE_ID }}
APPLE_PW: ${{ secrets.AC_APPLE_ID_PASSWORD }}
TEAM_ID: ${{ secrets.AC_TEAM_ID }}
run: |
# 提交公证
xcrun notarytool submit "${{ steps.dmg.outputs.dmg_path }}" \
--apple-id "$APPLE_ID" \
--password "$APPLE_PW" \
--team-id "$TEAM_ID" \
--wait

# 把公证 staple 到 dmg
xcrun stapler staple "${{ steps.dmg.outputs.dmg_path }}"

# ============ 上传 artifact ============
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: macos-dmg
path: ${{ steps.dmg.outputs.dmg_path }}
retention-days: 30

# ============ 创建 Release(tag 触发)============
- name: Create Release(tag 推送时)
if: startsWith(github.ref, 'refs/tags/v')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION=${GITHUB_REF#refs/tags/}
SIGNING=${{ steps.check-signing.outputs.signing }}
NOTE=""
if [ "$SIGNING" = "false" ]; then
NOTE=$'\n\n⚠️ **本版本未签名**。首次打开请右键点"打开"绕过 Gatekeeper。签名版本在 Apple Developer 账号配置好后自动启用。'
fi

# 如果 Release 不存在就建,存在就追加
if gh release view "$VERSION" > /dev/null 2>&1; then
gh release upload "$VERSION" "${{ steps.dmg.outputs.dmg_path }}" --clobber
else
gh release create "$VERSION" \
"${{ steps.dmg.outputs.dmg_path }}" \
--title "$VERSION" \
--notes "macOS Beta 构建${NOTE}"
fi

- name: 运行结束摘要
run: |
echo "## 构建完成" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| 项 | 值 |" >> $GITHUB_STEP_SUMMARY
echo "|----|-----|" >> $GITHUB_STEP_SUMMARY
echo "| 签名 | ${{ steps.check-signing.outputs.signing == 'true' && '✅ 已签名+公证' || '⚠️ 无签名' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 产物 | ${{ steps.dmg.outputs.dmg_name }} |" >> $GITHUB_STEP_SUMMARY
echo "| artifact | [下载](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) |" >> $GITHUB_STEP_SUMMARY
45 changes: 42 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,50 @@

---

## [Unreleased] · Sprint 7 进行中
## [Unreleased] · Sprint 7 规划完成 · 实施 S7.1-7.4 滚动推进

S7 按"规划 + 框架"范围完成:跨平台栈决策 + Swift 改造清单 + 打包 workflow。
实际 Swift 代码修改分 4 轮 PR(S7.1-7.4)滚动推进,每轮发布一个 Beta milestone。

### [0.7.0-draft] · Sprint 7 规划完成(2026-04-20)

**主题**: ADR 决策 · macOS 打包框架 · Swift 改造路线图

#### 新增 · 3 个 ADR
- **ADR-0001** 采用 4 种接入模式作为框架一等公民(回溯 Sprint 1 的决策)· Accepted
- **ADR-0002** 跨平台桌面应用技术栈 · **混合方案**:macOS 保留 Swift(资产保护)+ Linux/Windows 用 Tauri+Svelte(快速多平台)· Proposed
- 对比 Tauri / Electron / 保持原生 / 混合 4 方案,基于"团队规模 1 人 + 已有 Swift 骨架 2500 行 + 维护成本敏感"选混合
- **ADR-0003** 自动更新策略 · 统一用 GitHub Release API 作为更新源(零付费 + 三平台一致)· Proposed
- severity frontmatter 区分 critical / recommended / optional 强制级别

#### 新增 · 实施规划
- **Swift 改造清单** `docs/design/ui/swift-refactor-plan.md` · 列出 22 个 Swift 文件的具体改动:
- P0 · 8 项 · Beta 前必做(主视图/侧栏/聊天/向导/设置/供应商/命令面板/状态栏)
- P1 · 5 项 · 重要但可稍晚(登录/项目列表/新建向导/工作流/Prompt 注册表)
- P2 · 6 项 · Beta 后补(搜索/Artifact 增强/自动更新/收藏调整)
- 拆成 S7.1 - S7.4 四轮 PR 推进

#### 新增 · 构建基础设施
- **`.github/workflows/macos-build.yml`** · macOS Beta 自动构建:
- **无签名分支**(当前默认):用户需右键打开绕 Gatekeeper
- **签名+公证分支**(预留):secrets 配好 AC_TEAM_ID 等 5 个后自动启用
- push tag v*.*.* 自动创建 GitHub Release 附 .dmg
- **ADR 索引** `docs/adr/README.md` 由 `generate-adr-index.js` 生成

#### Sprint 7.x 推进路线
| 轮次 | 目标 | 文件数 |
|------|------|--------|
| S7.1 | 基础三栏 + 向导 + 设置 | P0 #1-5(5) |
| S7.2 | 命令面板 + 状态栏 + 供应商 | P0 #6-8(3) |
| S7.3 | 登录 + 项目列表 + 新建向导 | P1 #9-11(3) |
| S7.4 | 场景工作流 + Prompt 注册表 | P1 #12-13(2) |

Sprint 7 结束时:S7.1 + S7.2 macOS Beta 可下载(无签名)。

---

Phase 2 第一 Sprint (S6) 完成。S7 启动: macOS Beta 打包 + 跨平台栈决策。

### [0.7.0-draft] · Sprint 6 完成(2026-04-20)
### [Sprint 6] · 2026-04-20 · 完成

**主题**: 架构盘点 + UI/UX 设计稿 + 信息共享文档化 + 用户手册起步

Expand Down
2 changes: 1 addition & 1 deletion PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
> | S4 | 场景联动 + 度量闭环 | ✅ 完成(2026-04-18) |
> | S5 | 统一 CLI + 对外发布 + 试点复盘 | ✅ 完成(2026-04-18) 🎉 |
> | S6 | 架构盘点 + UI/UX 设计稿 + 手册起步 + 信息流文档化 | ✅ 完成(2026-04-20) |
> | **S7** | **macOS Beta 打包 + 跨平台栈决策** | **📋 Phase 2 计划中** |
> | **S7** | **跨平台栈决策(ADR-0002)+ macOS 改造清单 + 打包 workflow** | **🟡 规划/框架完成 · 代码留 S7.1-7.4** |
> | S8 | 用户手册完整版 + v1.0 正式发布 | 📋 Phase 2 计划中 |
> | S9 | 服务端 RFC + OTA 协议设计(不实现) | 📋 Phase 2 计划中 |
> | S10 | 真实试点项目复盘 | 📋 Phase 2 计划中 |
Expand Down
10 changes: 9 additions & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
| S5 | Week 5 | 统一 CLI + 对外发布 + 试点复盘 | ✅ 完成 |
| **Phase 2 · 落地与产品化** | | | |
| S6 | Week 6 | 架构图 + UI/UX 设计稿 + 信息流 + 手册起步 | ✅ 完成 |
| S7 | Week 7 | macOS Beta(对齐设计稿)+ 跨平台栈决策 | 📋 计划中 |
| S7 | Week 7 | 跨平台栈决策(ADR-0002)+ macOS 改造清单 + 打包 workflow | 🟡 规划完成 · 代码实施 S7.1-7.4 |
| S8 | Week 8 | 用户手册完整版 + Linux/Win Beta + v1.0 GA | 📋 计划中 |
| S9 | Week 9 | 服务端同步 RFC + OTA 协议设计(不实现) | 📋 计划中 |
| S10 | Week 10 | 真实试点项目复盘 | 📋 计划中 |
Expand All @@ -28,6 +28,14 @@

## 近期变更

### 2026-04-20(Sprint 7 规划完成 · 代码留 S7.1-7.4)
- **ADR-0001** 采用 4 种接入模式作为框架一等公民(回溯 Sprint 1)· Accepted
- **ADR-0002** 跨平台桌面应用技术栈 · **混合方案**(macOS 保留 Swift + Linux/Win 用 Tauri+Svelte)· Proposed
- **ADR-0003** 自动更新策略 · GitHub Release 为统一更新源(三平台共享)· Proposed
- **Swift 改造清单** `docs/design/ui/swift-refactor-plan.md` · 19 项改动 + 4 轮 PR 推进计划
- **macOS 打包 workflow** `.github/workflows/macos-build.yml` · 支持签名/无签名双路径(secret 未配时走无签名)
- **ADR 索引** `docs/adr/README.md` 自动生成

### 2026-04-20(Sprint 6 完成 · Phase 2 第一 Sprint)
- **⑥ UI/UX 设计稿**: 17 张 HTML 原型 + 13 wireframes 文档(覆盖 17 个主题)+ 5 Mermaid flows + 映射表
- 核心: 主视图 / 向导 / 设置 / 命令面板 / Artifact / 供应商切换 / 搜索 / 右键菜单 / 空态 / 状态栏
Expand Down
Loading
Loading