@lobehub/lobehub 2.0.0-next.291 → 2.0.0-next.293
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.conductor/setup.sh +107 -0
- package/.cursor/rules/linear.mdc +53 -0
- package/.github/actions/desktop-build-setup/action.yml +29 -0
- package/.github/actions/desktop-upload-artifacts/action.yml +46 -0
- package/.github/workflows/release-desktop-beta.yml +76 -115
- package/.github/workflows/release-desktop-stable.yml +472 -0
- package/CHANGELOG.md +58 -0
- package/CLAUDE.md +2 -48
- package/apps/desktop/dev-app-update.yml +10 -0
- package/apps/desktop/electron-builder.mjs +40 -10
- package/apps/desktop/electron.vite.config.ts +3 -2
- package/apps/desktop/package.json +2 -1
- package/apps/desktop/scripts/update-test/README.md +222 -0
- package/apps/desktop/scripts/update-test/dev-app-update.local.yml +18 -0
- package/apps/desktop/scripts/update-test/generate-manifest.sh +277 -0
- package/apps/desktop/scripts/update-test/run-test.sh +105 -0
- package/apps/desktop/scripts/update-test/setup.sh +111 -0
- package/apps/desktop/scripts/update-test/start-server.sh +70 -0
- package/apps/desktop/scripts/update-test/stop-server.sh +33 -0
- package/apps/desktop/src/main/core/infrastructure/UpdaterManager.ts +120 -9
- package/apps/desktop/src/main/core/infrastructure/__tests__/UpdaterManager.test.ts +17 -1
- package/apps/desktop/src/main/env.ts +19 -11
- package/apps/desktop/src/main/modules/updater/configs.ts +14 -1
- package/changelog/v1.json +14 -0
- package/conductor.json +5 -0
- package/locales/en-US/subscription.json +2 -2
- package/locales/zh-CN/subscription.json +2 -2
- package/package.json +1 -1
- package/packages/builtin-tool-notebook/src/client/Render/CreateDocument/DocumentCard.tsx +16 -14
- package/packages/const/src/cacheControl.ts +1 -0
- package/packages/electron-client-ipc/src/useWatchBroadcast.ts +10 -4
- package/packages/model-bank/src/aiModels/qiniu.ts +6 -6
- package/packages/observability-otel/src/node.ts +39 -37
- package/scripts/electronWorkflow/mergeMacReleaseFiles.js +22 -8
- package/src/app/(backend)/api/desktop/latest/route.ts +115 -0
- package/src/app/(backend)/api/version/route.ts +13 -0
- package/src/app/(backend)/middleware/validate/createValidator.test.ts +61 -0
- package/src/app/(backend)/middleware/validate/createValidator.ts +79 -0
- package/src/app/(backend)/middleware/validate/index.ts +3 -0
- package/src/app/[variants]/(desktop)/desktop-onboarding/_layout/index.tsx +2 -1
- package/src/app/[variants]/(main)/_layout/index.tsx +2 -1
- package/src/app/[variants]/(main)/agent/cron/[cronId]/features/CronJobScheduleConfig.tsx +0 -1
- package/src/app/[variants]/(main)/agent/cron/[cronId]/index.tsx +5 -5
- package/src/app/[variants]/(main)/agent/features/Conversation/ThreadHydration.tsx +3 -1
- package/src/app/[variants]/(main)/group/features/Conversation/ThreadHydration.tsx +3 -1
- package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/Checker.tsx +3 -3
- package/src/app/[variants]/(mobile)/router/mobileRouter.config.tsx +1 -4
- package/src/app/[variants]/router/desktopRouter.config.tsx +1 -4
- package/src/components/HtmlPreview/PreviewDrawer.tsx +1 -1
- package/src/features/Conversation/Messages/AssistantGroup/components/GroupItem.tsx +12 -2
- package/src/features/Conversation/Messages/Tool/Tool/index.tsx +10 -1
- package/src/features/{ElectronTitlebar/hooks → Electron/navigation}/useNavigationHistory.ts +1 -1
- package/src/features/{ElectronTitlebar/NavigationBar/index.tsx → Electron/titlebar/NavigationBar.tsx} +1 -1
- package/src/features/{ElectronTitlebar/NavigationBar → Electron/titlebar}/RecentlyViewed.tsx +1 -1
- package/src/features/{ElectronTitlebar/index.tsx → Electron/titlebar/TitleBar.tsx} +19 -9
- package/src/features/Electron/titlebar/WinControl.tsx +5 -0
- package/src/features/Electron/updater/UpdateModal.tsx +299 -0
- package/src/features/LibraryModal/AddFilesToKnowledgeBase/index.test.tsx +24 -0
- package/src/features/LibraryModal/AddFilesToKnowledgeBase/index.tsx +21 -24
- package/src/features/LibraryModal/CreateNew/index.tsx +18 -22
- package/src/features/PluginDevModal/index.tsx +1 -1
- package/src/layout/GlobalProvider/AppTheme.tsx +1 -1
- package/src/libs/swr/index.ts +26 -30
- package/src/server/services/desktopRelease/index.test.ts +65 -0
- package/src/server/services/desktopRelease/index.ts +208 -0
- package/src/store/aiInfra/slices/aiProvider/action.ts +16 -17
- package/src/store/chat/slices/portal/action.test.ts +0 -2
- package/src/store/chat/slices/portal/action.ts +17 -44
- package/src/store/chat/slices/thread/action.test.ts +4 -1
- package/src/store/chat/slices/thread/action.ts +6 -1
- package/src/components/FunctionModal/createModalHooks.ts +0 -48
- package/src/components/FunctionModal/index.ts +0 -1
- package/src/components/FunctionModal/style.tsx +0 -44
- package/src/features/ElectronTitlebar/UpdateModal.tsx +0 -274
- package/src/features/ElectronTitlebar/WinControl/index.tsx +0 -90
- /package/src/features/{ElectronTitlebar/Connection/index.tsx → Electron/connection/Connection.tsx} +0 -0
- /package/src/features/{ElectronTitlebar/Connection → Electron/connection}/ConnectionMode.tsx +0 -0
- /package/src/features/{ElectronTitlebar/Connection → Electron/connection}/Option.tsx +0 -0
- /package/src/features/{ElectronTitlebar/Connection → Electron/connection}/RemoteStatus.tsx +0 -0
- /package/src/features/{ElectronTitlebar/Connection → Electron/connection}/Waiting.tsx +0 -0
- /package/src/features/{ElectronTitlebar/Connection → Electron/connection}/WaitingAnim.tsx +0 -0
- /package/src/features/{ElectronTitlebar/helpers → Electron/navigation}/routeMetadata.ts +0 -0
- /package/src/features/{ElectronTitlebar/hooks → Electron/system}/useWatchThemeUpdate.ts +0 -0
- /package/src/features/{ElectronTitlebar → Electron/titlebar}/SimpleTitleBar.tsx +0 -0
- /package/src/features/{ElectronTitlebar → Electron/updater}/UpdateNotification.tsx +0 -0
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
name: Release Desktop Stable
|
|
2
|
+
|
|
3
|
+
# ============================================
|
|
4
|
+
# Stable 频道发版工作流
|
|
5
|
+
# ============================================
|
|
6
|
+
# 触发条件: 发布不含 pre-release 标识的 release (如 v2.0.0)
|
|
7
|
+
#
|
|
8
|
+
# 与 Beta 的区别:
|
|
9
|
+
# 1. 仅响应 stable 版本 tag (不含 beta/alpha/rc/nightly)
|
|
10
|
+
# 2. 使用 STABLE 专用的 Umami 配置
|
|
11
|
+
# 3. 额外上传到 S3 更新服务器
|
|
12
|
+
# 4. 构建时注入 UPDATE_SERVER_URL 让客户端从 S3 检查更新
|
|
13
|
+
#
|
|
14
|
+
# 需要配置的 Secrets (S3 相关, 统一 UPDATE_ 前缀):
|
|
15
|
+
# - UPDATE_AWS_ACCESS_KEY_ID
|
|
16
|
+
# - UPDATE_AWS_SECRET_ACCESS_KEY
|
|
17
|
+
# - UPDATE_S3_BUCKET (S3 存储桶名称)
|
|
18
|
+
# - UPDATE_S3_REGION (可选, 默认 us-east-1)
|
|
19
|
+
# - UPDATE_S3_ENDPOINT (可选, 用于 R2/MinIO 等 S3 兼容服务)
|
|
20
|
+
# - UPDATE_SERVER_URL (客户端检查更新的 URL)
|
|
21
|
+
# ============================================
|
|
22
|
+
|
|
23
|
+
on:
|
|
24
|
+
release:
|
|
25
|
+
types: [published]
|
|
26
|
+
workflow_dispatch:
|
|
27
|
+
inputs:
|
|
28
|
+
version:
|
|
29
|
+
description: 'Version to build (e.g., 2.0.0)'
|
|
30
|
+
required: true
|
|
31
|
+
type: string
|
|
32
|
+
build_mac:
|
|
33
|
+
description: 'Build macOS (ARM64)'
|
|
34
|
+
required: false
|
|
35
|
+
type: boolean
|
|
36
|
+
default: true
|
|
37
|
+
build_mac_intel:
|
|
38
|
+
description: 'Build macOS (Intel x64)'
|
|
39
|
+
required: false
|
|
40
|
+
type: boolean
|
|
41
|
+
default: true
|
|
42
|
+
build_windows:
|
|
43
|
+
description: 'Build Windows'
|
|
44
|
+
required: false
|
|
45
|
+
type: boolean
|
|
46
|
+
default: true
|
|
47
|
+
build_linux:
|
|
48
|
+
description: 'Build Linux'
|
|
49
|
+
required: false
|
|
50
|
+
type: boolean
|
|
51
|
+
default: true
|
|
52
|
+
skip_s3_upload:
|
|
53
|
+
description: 'Skip S3 upload (for testing)'
|
|
54
|
+
required: false
|
|
55
|
+
type: boolean
|
|
56
|
+
default: true
|
|
57
|
+
skip_github_release:
|
|
58
|
+
description: 'Skip GitHub release upload (for testing)'
|
|
59
|
+
required: false
|
|
60
|
+
type: boolean
|
|
61
|
+
default: true
|
|
62
|
+
|
|
63
|
+
concurrency:
|
|
64
|
+
group: ${{ github.ref }}-${{ github.workflow }}
|
|
65
|
+
cancel-in-progress: true
|
|
66
|
+
|
|
67
|
+
permissions: read-all
|
|
68
|
+
|
|
69
|
+
env:
|
|
70
|
+
NODE_VERSION: '24.11.1'
|
|
71
|
+
|
|
72
|
+
jobs:
|
|
73
|
+
# ============================================
|
|
74
|
+
# 检查版本信息
|
|
75
|
+
# ============================================
|
|
76
|
+
check-stable:
|
|
77
|
+
name: Check Release Version
|
|
78
|
+
runs-on: ubuntu-latest
|
|
79
|
+
outputs:
|
|
80
|
+
is_stable: ${{ steps.check.outputs.is_stable }}
|
|
81
|
+
version: ${{ steps.check.outputs.version }}
|
|
82
|
+
is_manual: ${{ steps.check.outputs.is_manual }}
|
|
83
|
+
release_notes: ${{ steps.check.outputs.release_notes }}
|
|
84
|
+
steps:
|
|
85
|
+
- name: Check release info
|
|
86
|
+
id: check
|
|
87
|
+
run: |
|
|
88
|
+
# 判断触发方式
|
|
89
|
+
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
|
|
90
|
+
# 手动触发: 使用输入的版本号
|
|
91
|
+
version="${{ inputs.version }}"
|
|
92
|
+
echo "is_manual=true" >> $GITHUB_OUTPUT
|
|
93
|
+
echo "is_stable=true" >> $GITHUB_OUTPUT
|
|
94
|
+
echo "version=${version}" >> $GITHUB_OUTPUT
|
|
95
|
+
echo "release_notes=" >> $GITHUB_OUTPUT
|
|
96
|
+
echo "🔧 Manual trigger: version=${version}"
|
|
97
|
+
else
|
|
98
|
+
# Release 触发: 从 tag 提取版本号
|
|
99
|
+
version="${{ github.event.release.tag_name }}"
|
|
100
|
+
version="${version#v}"
|
|
101
|
+
echo "is_manual=false" >> $GITHUB_OUTPUT
|
|
102
|
+
echo "version=${version}" >> $GITHUB_OUTPUT
|
|
103
|
+
release_body="${{ github.event.release.body }}"
|
|
104
|
+
{
|
|
105
|
+
echo "release_notes<<EOF"
|
|
106
|
+
printf '%s\n' "$release_body"
|
|
107
|
+
echo "EOF"
|
|
108
|
+
} >> $GITHUB_OUTPUT
|
|
109
|
+
|
|
110
|
+
# 检查是否为 stable 版本 (不含 beta/alpha/rc/nightly)
|
|
111
|
+
if [[ "$version" == *"beta"* ]] || [[ "$version" == *"alpha"* ]] || [[ "$version" == *"rc"* ]] || [[ "$version" == *"nightly"* ]]; then
|
|
112
|
+
echo "is_stable=false" >> $GITHUB_OUTPUT
|
|
113
|
+
echo "⏭️ Skipping: $version is not a stable release"
|
|
114
|
+
else
|
|
115
|
+
echo "is_stable=true" >> $GITHUB_OUTPUT
|
|
116
|
+
echo "✅ Stable release detected: $version"
|
|
117
|
+
fi
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
# ============================================
|
|
121
|
+
# 配置构建矩阵 (检查自托管 Runner)
|
|
122
|
+
# ============================================
|
|
123
|
+
configure-build:
|
|
124
|
+
needs: [check-stable]
|
|
125
|
+
if: needs.check-stable.outputs.is_stable == 'true'
|
|
126
|
+
name: Configure Build Matrix
|
|
127
|
+
runs-on: ubuntu-latest
|
|
128
|
+
outputs:
|
|
129
|
+
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
|
130
|
+
steps:
|
|
131
|
+
- name: Generate Matrix
|
|
132
|
+
id: set-matrix
|
|
133
|
+
run: |
|
|
134
|
+
# 基础矩阵
|
|
135
|
+
static_matrix='[]'
|
|
136
|
+
|
|
137
|
+
# Windows
|
|
138
|
+
if [[ "${{ github.event_name }}" != "workflow_dispatch" ]] || [[ "${{ inputs.build_windows }}" == "true" ]]; then
|
|
139
|
+
static_matrix=$(echo "$static_matrix" | jq -c '. + [{"os": "windows-2025", "name": "windows-2025"}]')
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
# Linux
|
|
143
|
+
if [[ "${{ github.event_name }}" != "workflow_dispatch" ]] || [[ "${{ inputs.build_linux }}" == "true" ]]; then
|
|
144
|
+
static_matrix=$(echo "$static_matrix" | jq -c '. + [{"os": "ubuntu-latest", "name": "ubuntu-latest"}]')
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
# macOS (ARM64)
|
|
148
|
+
# 使用 GitHub Hosted Runner
|
|
149
|
+
if [[ "${{ github.event_name }}" != "workflow_dispatch" ]] || [[ "${{ inputs.build_mac }}" == "true" ]]; then
|
|
150
|
+
echo "Using GitHub-Hosted Runner for macOS ARM64"
|
|
151
|
+
arm_entry='{"os": "macos-14", "name": "macos-arm64"}'
|
|
152
|
+
static_matrix=$(echo "$static_matrix" | jq -c --argjson entry "$arm_entry" '. + [$entry]')
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
if [[ "${{ github.event_name }}" != "workflow_dispatch" ]] || [[ "${{ inputs.build_mac_intel }}" == "true" ]]; then
|
|
156
|
+
echo "Using GitHub-Hosted Runner for macOS Intel x64"
|
|
157
|
+
intel_entry='{"os": "macos-15-intel", "name": "macos-intel"}'
|
|
158
|
+
static_matrix=$(echo "$static_matrix" | jq -c --argjson entry "$intel_entry" '. + [$entry]')
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
# 输出
|
|
162
|
+
echo "matrix={\"include\":$static_matrix}" >> $GITHUB_OUTPUT
|
|
163
|
+
|
|
164
|
+
# ============================================
|
|
165
|
+
# 多平台构建
|
|
166
|
+
# ============================================
|
|
167
|
+
build:
|
|
168
|
+
needs: [check-stable, configure-build]
|
|
169
|
+
if: needs.check-stable.outputs.is_stable == 'true'
|
|
170
|
+
name: Build Desktop App
|
|
171
|
+
runs-on: ${{ matrix.os }}
|
|
172
|
+
strategy:
|
|
173
|
+
fail-fast: false
|
|
174
|
+
matrix: ${{ fromJson(needs.configure-build.outputs.matrix) }}
|
|
175
|
+
steps:
|
|
176
|
+
- uses: actions/checkout@v6
|
|
177
|
+
with:
|
|
178
|
+
fetch-depth: 0
|
|
179
|
+
|
|
180
|
+
- name: Setup build environment
|
|
181
|
+
uses: ./.github/actions/desktop-build-setup
|
|
182
|
+
with:
|
|
183
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
184
|
+
|
|
185
|
+
- name: Set package version
|
|
186
|
+
run: npm run workflow:set-desktop-version ${{ needs.check-stable.outputs.version }} stable
|
|
187
|
+
|
|
188
|
+
# macOS 构建
|
|
189
|
+
- name: Build artifact on macOS
|
|
190
|
+
if: runner.os == 'macOS'
|
|
191
|
+
run: npm run desktop:build
|
|
192
|
+
env:
|
|
193
|
+
UPDATE_CHANNEL: stable
|
|
194
|
+
UPDATE_SERVER_URL: ${{ secrets.UPDATE_SERVER_URL }}
|
|
195
|
+
RELEASE_NOTES: ${{ needs.check-stable.outputs.release_notes }}
|
|
196
|
+
APP_URL: http://localhost:3015
|
|
197
|
+
DATABASE_URL: 'postgresql://postgres@localhost:5432/postgres'
|
|
198
|
+
KEY_VAULTS_SECRET: 'oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE='
|
|
199
|
+
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
|
|
200
|
+
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
|
201
|
+
CSC_FOR_PULL_REQUEST: true
|
|
202
|
+
APPLE_ID: ${{ secrets.APPLE_ID }}
|
|
203
|
+
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
|
|
204
|
+
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
205
|
+
NEXT_PUBLIC_DESKTOP_PROJECT_ID: ${{ secrets.UMAMI_STABLE_DESKTOP_PROJECT_ID }}
|
|
206
|
+
NEXT_PUBLIC_DESKTOP_UMAMI_BASE_URL: ${{ secrets.UMAMI_STABLE_DESKTOP_BASE_URL }}
|
|
207
|
+
|
|
208
|
+
# Windows 构建
|
|
209
|
+
- name: Build artifact on Windows
|
|
210
|
+
if: runner.os == 'Windows'
|
|
211
|
+
run: npm run desktop:build
|
|
212
|
+
env:
|
|
213
|
+
UPDATE_CHANNEL: stable
|
|
214
|
+
UPDATE_SERVER_URL: ${{ secrets.UPDATE_SERVER_URL }}
|
|
215
|
+
RELEASE_NOTES: ${{ needs.check-stable.outputs.release_notes }}
|
|
216
|
+
APP_URL: http://localhost:3015
|
|
217
|
+
DATABASE_URL: 'postgresql://postgres@localhost:5432/postgres'
|
|
218
|
+
KEY_VAULTS_SECRET: 'oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE='
|
|
219
|
+
NEXT_PUBLIC_DESKTOP_PROJECT_ID: ${{ secrets.UMAMI_STABLE_DESKTOP_PROJECT_ID }}
|
|
220
|
+
NEXT_PUBLIC_DESKTOP_UMAMI_BASE_URL: ${{ secrets.UMAMI_STABLE_DESKTOP_BASE_URL }}
|
|
221
|
+
TEMP: C:\temp
|
|
222
|
+
TMP: C:\temp
|
|
223
|
+
|
|
224
|
+
# Linux 构建
|
|
225
|
+
- name: Build artifact on Linux
|
|
226
|
+
if: runner.os == 'Linux'
|
|
227
|
+
run: |
|
|
228
|
+
npm run desktop:build
|
|
229
|
+
tar -czf apps/desktop/release/lobehub-renderer.tar.gz -C out .
|
|
230
|
+
env:
|
|
231
|
+
UPDATE_CHANNEL: stable
|
|
232
|
+
UPDATE_SERVER_URL: ${{ secrets.UPDATE_SERVER_URL }}
|
|
233
|
+
RELEASE_NOTES: ${{ needs.check-stable.outputs.release_notes }}
|
|
234
|
+
APP_URL: http://localhost:3015
|
|
235
|
+
DATABASE_URL: 'postgresql://postgres@localhost:5432/postgres'
|
|
236
|
+
KEY_VAULTS_SECRET: 'oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE='
|
|
237
|
+
NEXT_PUBLIC_DESKTOP_PROJECT_ID: ${{ secrets.UMAMI_STABLE_DESKTOP_PROJECT_ID }}
|
|
238
|
+
NEXT_PUBLIC_DESKTOP_UMAMI_BASE_URL: ${{ secrets.UMAMI_STABLE_DESKTOP_BASE_URL }}
|
|
239
|
+
|
|
240
|
+
- name: Upload artifacts
|
|
241
|
+
uses: ./.github/actions/desktop-upload-artifacts
|
|
242
|
+
with:
|
|
243
|
+
artifact-name: release-${{ matrix.name }}
|
|
244
|
+
|
|
245
|
+
# ============================================
|
|
246
|
+
# 合并 macOS 多架构文件
|
|
247
|
+
# ============================================
|
|
248
|
+
merge-mac-files:
|
|
249
|
+
needs: [build, check-stable]
|
|
250
|
+
name: Merge macOS Release Files
|
|
251
|
+
runs-on: ubuntu-latest
|
|
252
|
+
permissions:
|
|
253
|
+
contents: write
|
|
254
|
+
steps:
|
|
255
|
+
- name: Checkout repository
|
|
256
|
+
uses: actions/checkout@v6
|
|
257
|
+
|
|
258
|
+
- name: Setup Node.js
|
|
259
|
+
uses: actions/setup-node@v6
|
|
260
|
+
with:
|
|
261
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
262
|
+
package-manager-cache: false
|
|
263
|
+
|
|
264
|
+
- name: Install bun
|
|
265
|
+
uses: oven-sh/setup-bun@v2
|
|
266
|
+
with:
|
|
267
|
+
bun-version: latest
|
|
268
|
+
|
|
269
|
+
- name: Download artifacts
|
|
270
|
+
uses: actions/download-artifact@v7
|
|
271
|
+
with:
|
|
272
|
+
path: release
|
|
273
|
+
pattern: release-*
|
|
274
|
+
merge-multiple: true
|
|
275
|
+
|
|
276
|
+
- name: List downloaded artifacts
|
|
277
|
+
run: ls -R release
|
|
278
|
+
|
|
279
|
+
- name: Install yaml only for merge step
|
|
280
|
+
run: |
|
|
281
|
+
cd scripts/electronWorkflow
|
|
282
|
+
if [ ! -f package.json ]; then
|
|
283
|
+
echo '{"name":"merge-mac-release","private":true}' > package.json
|
|
284
|
+
fi
|
|
285
|
+
bun add --no-save yaml@2.8.1
|
|
286
|
+
|
|
287
|
+
- name: Merge latest-mac.yml files
|
|
288
|
+
run: bun run scripts/electronWorkflow/mergeMacReleaseFiles.js
|
|
289
|
+
|
|
290
|
+
- name: Upload artifacts with merged macOS files
|
|
291
|
+
uses: actions/upload-artifact@v6
|
|
292
|
+
with:
|
|
293
|
+
name: merged-release
|
|
294
|
+
path: release/
|
|
295
|
+
retention-days: 1
|
|
296
|
+
|
|
297
|
+
# ============================================
|
|
298
|
+
# 发布到 GitHub Releases
|
|
299
|
+
# ============================================
|
|
300
|
+
publish-github:
|
|
301
|
+
needs: [merge-mac-files, check-stable]
|
|
302
|
+
name: Publish to GitHub Release
|
|
303
|
+
runs-on: ubuntu-latest
|
|
304
|
+
# 手动触发时可选择跳过
|
|
305
|
+
if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.skip_github_release) }}
|
|
306
|
+
permissions:
|
|
307
|
+
contents: write
|
|
308
|
+
steps:
|
|
309
|
+
- name: Download merged artifacts
|
|
310
|
+
uses: actions/download-artifact@v7
|
|
311
|
+
with:
|
|
312
|
+
name: merged-release
|
|
313
|
+
path: release
|
|
314
|
+
|
|
315
|
+
- name: List final artifacts
|
|
316
|
+
run: ls -R release
|
|
317
|
+
|
|
318
|
+
- name: Upload to Release
|
|
319
|
+
uses: softprops/action-gh-release@v1
|
|
320
|
+
with:
|
|
321
|
+
# 手动触发时使用输入的版本号创建 tag
|
|
322
|
+
tag_name: ${{ github.event_name == 'workflow_dispatch' && format('v{0}', needs.check-stable.outputs.version) || github.event.release.tag_name }}
|
|
323
|
+
# 手动触发时创建为 draft
|
|
324
|
+
draft: ${{ github.event_name == 'workflow_dispatch' }}
|
|
325
|
+
files: |
|
|
326
|
+
release/stable*
|
|
327
|
+
release/latest*
|
|
328
|
+
release/*.dmg*
|
|
329
|
+
release/*.zip*
|
|
330
|
+
release/*.exe*
|
|
331
|
+
release/*.AppImage
|
|
332
|
+
release/*.deb*
|
|
333
|
+
release/*.snap*
|
|
334
|
+
release/*.rpm*
|
|
335
|
+
release/*.tar.gz*
|
|
336
|
+
env:
|
|
337
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
338
|
+
|
|
339
|
+
# ============================================
|
|
340
|
+
# 发布到 S3 更新服务器
|
|
341
|
+
# ============================================
|
|
342
|
+
# S3 目录结构:
|
|
343
|
+
# s3://bucket/
|
|
344
|
+
# stable/
|
|
345
|
+
# stable-mac.yml ← electron-updater 检查更新 (stable channel)
|
|
346
|
+
# stable.yml ← Windows (stable channel)
|
|
347
|
+
# stable-linux.yml ← Linux (stable channel)
|
|
348
|
+
# latest-mac.yml ← fallback for GitHub provider
|
|
349
|
+
# {version}/ ← 版本目录
|
|
350
|
+
# *.dmg, *.zip, *.exe, ...
|
|
351
|
+
# ============================================
|
|
352
|
+
publish-s3:
|
|
353
|
+
needs: [merge-mac-files, check-stable]
|
|
354
|
+
name: Publish to S3
|
|
355
|
+
runs-on: ubuntu-latest
|
|
356
|
+
# 手动触发时可选择跳过
|
|
357
|
+
if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.skip_s3_upload) }}
|
|
358
|
+
steps:
|
|
359
|
+
- name: Download merged artifacts
|
|
360
|
+
uses: actions/download-artifact@v7
|
|
361
|
+
with:
|
|
362
|
+
name: merged-release
|
|
363
|
+
path: release
|
|
364
|
+
|
|
365
|
+
- name: List artifacts to upload
|
|
366
|
+
run: |
|
|
367
|
+
echo "📦 Artifacts to upload to S3:"
|
|
368
|
+
ls -lah release/
|
|
369
|
+
echo ""
|
|
370
|
+
echo "📋 Version: ${{ needs.check-stable.outputs.version }}"
|
|
371
|
+
|
|
372
|
+
- name: Upload to S3
|
|
373
|
+
env:
|
|
374
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.UPDATE_AWS_ACCESS_KEY_ID }}
|
|
375
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.UPDATE_AWS_SECRET_ACCESS_KEY }}
|
|
376
|
+
AWS_REGION: ${{ secrets.UPDATE_S3_REGION || 'us-east-1' }}
|
|
377
|
+
S3_BUCKET: ${{ secrets.UPDATE_S3_BUCKET }}
|
|
378
|
+
S3_ENDPOINT: ${{ secrets.UPDATE_S3_ENDPOINT }}
|
|
379
|
+
VERSION: ${{ needs.check-stable.outputs.version }}
|
|
380
|
+
run: |
|
|
381
|
+
if [ -z "$S3_BUCKET" ]; then
|
|
382
|
+
echo "⚠️ UPDATE_S3_BUCKET is not configured, skipping S3 upload"
|
|
383
|
+
echo ""
|
|
384
|
+
echo "To enable S3 upload, configure the following secrets:"
|
|
385
|
+
echo " - UPDATE_AWS_ACCESS_KEY_ID"
|
|
386
|
+
echo " - UPDATE_AWS_SECRET_ACCESS_KEY"
|
|
387
|
+
echo " - UPDATE_S3_BUCKET"
|
|
388
|
+
echo " - UPDATE_S3_REGION (optional, defaults to us-east-1)"
|
|
389
|
+
echo " - UPDATE_S3_ENDPOINT (optional, for S3-compatible services)"
|
|
390
|
+
exit 0
|
|
391
|
+
fi
|
|
392
|
+
|
|
393
|
+
# 构建端点参数
|
|
394
|
+
ENDPOINT_ARG=""
|
|
395
|
+
if [ -n "$S3_ENDPOINT" ]; then
|
|
396
|
+
ENDPOINT_ARG="--endpoint-url $S3_ENDPOINT"
|
|
397
|
+
echo "📡 Using custom S3 endpoint: $S3_ENDPOINT"
|
|
398
|
+
fi
|
|
399
|
+
|
|
400
|
+
echo "🚀 Uploading to S3 bucket: $S3_BUCKET"
|
|
401
|
+
echo "📁 Target path: s3://$S3_BUCKET/stable/"
|
|
402
|
+
echo ""
|
|
403
|
+
|
|
404
|
+
# 1. 上传安装包到版本目录
|
|
405
|
+
echo "📦 Uploading release files to s3://$S3_BUCKET/stable/$VERSION/"
|
|
406
|
+
for file in release/*.dmg release/*.zip release/*.exe release/*.AppImage release/*.deb release/*.rpm release/*.snap release/*.tar.gz; do
|
|
407
|
+
if [ -f "$file" ]; then
|
|
408
|
+
filename=$(basename "$file")
|
|
409
|
+
echo " ↗️ $filename"
|
|
410
|
+
aws s3 cp "$file" "s3://$S3_BUCKET/stable/$VERSION/$filename" $ENDPOINT_ARG
|
|
411
|
+
fi
|
|
412
|
+
done
|
|
413
|
+
|
|
414
|
+
# 2. 创建 stable*.yml (从 latest*.yml 复制,并修改 URL 加上版本目录前缀)
|
|
415
|
+
# electron-updater 在 channel=stable 时会找 stable-mac.yml
|
|
416
|
+
# S3 目录结构: stable/{version}/xxx.dmg,所以 URL 需要加上 {version}/ 前缀
|
|
417
|
+
echo ""
|
|
418
|
+
echo "📋 Creating stable*.yml files from latest*.yml..."
|
|
419
|
+
for yml in release/latest*.yml; do
|
|
420
|
+
if [ -f "$yml" ]; then
|
|
421
|
+
stable_name=$(basename "$yml" | sed 's/latest/stable/')
|
|
422
|
+
# 复制并修改 URL: 给所有 url 字段加上版本目录前缀
|
|
423
|
+
# url: xxx.dmg -> url: {VERSION}/xxx.dmg
|
|
424
|
+
sed "s|url: |url: $VERSION/|g" "$yml" > "release/$stable_name"
|
|
425
|
+
echo " 📄 Created $stable_name from $(basename $yml) with URL prefix: $VERSION/"
|
|
426
|
+
fi
|
|
427
|
+
done
|
|
428
|
+
|
|
429
|
+
# 3. 创建 renderer manifest (用于验证 renderer tar 完整性)
|
|
430
|
+
echo ""
|
|
431
|
+
echo "📋 Creating renderer manifest..."
|
|
432
|
+
RENDERER_TAR="release/lobehub-renderer.tar.gz"
|
|
433
|
+
if [ -f "$RENDERER_TAR" ]; then
|
|
434
|
+
RENDERER_SHA512=$(shasum -a 512 "$RENDERER_TAR" | awk '{print $1}' | xxd -r -p | base64)
|
|
435
|
+
RENDERER_SIZE=$(stat -f%z "$RENDERER_TAR" 2>/dev/null || stat -c%s "$RENDERER_TAR")
|
|
436
|
+
RELEASE_DATE=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")
|
|
437
|
+
echo "version: $VERSION" > "release/stable-renderer.yml"
|
|
438
|
+
echo "files:" >> "release/stable-renderer.yml"
|
|
439
|
+
echo " - url: $VERSION/lobehub-renderer.tar.gz" >> "release/stable-renderer.yml"
|
|
440
|
+
echo " sha512: $RENDERER_SHA512" >> "release/stable-renderer.yml"
|
|
441
|
+
echo " size: $RENDERER_SIZE" >> "release/stable-renderer.yml"
|
|
442
|
+
echo "path: $VERSION/lobehub-renderer.tar.gz" >> "release/stable-renderer.yml"
|
|
443
|
+
echo "sha512: $RENDERER_SHA512" >> "release/stable-renderer.yml"
|
|
444
|
+
echo "releaseDate: '$RELEASE_DATE'" >> "release/stable-renderer.yml"
|
|
445
|
+
echo " 📄 Created stable-renderer.yml with SHA512 checksum"
|
|
446
|
+
else
|
|
447
|
+
echo " ⚠️ Renderer tar not found, skipping manifest creation"
|
|
448
|
+
fi
|
|
449
|
+
|
|
450
|
+
# 4. 上传 manifest 到根目录和版本目录
|
|
451
|
+
# 根目录: electron-updater 需要,会被每次发版覆盖
|
|
452
|
+
# 版本目录: 作为存档保留
|
|
453
|
+
echo ""
|
|
454
|
+
echo "📋 Uploading manifest files..."
|
|
455
|
+
for yml in release/stable*.yml release/latest*.yml; do
|
|
456
|
+
if [ -f "$yml" ]; then
|
|
457
|
+
filename=$(basename "$yml")
|
|
458
|
+
echo " ↗️ $filename -> s3://$S3_BUCKET/stable/$filename"
|
|
459
|
+
aws s3 cp "$yml" "s3://$S3_BUCKET/stable/$filename" $ENDPOINT_ARG
|
|
460
|
+
echo " ↗️ $filename -> s3://$S3_BUCKET/stable/$VERSION/$filename (archive)"
|
|
461
|
+
aws s3 cp "$yml" "s3://$S3_BUCKET/stable/$VERSION/$filename" $ENDPOINT_ARG
|
|
462
|
+
fi
|
|
463
|
+
done
|
|
464
|
+
|
|
465
|
+
echo ""
|
|
466
|
+
echo "✅ S3 upload completed!"
|
|
467
|
+
echo ""
|
|
468
|
+
echo "📋 Files in s3://$S3_BUCKET/stable/:"
|
|
469
|
+
aws s3 ls "s3://$S3_BUCKET/stable/" $ENDPOINT_ARG || true
|
|
470
|
+
echo ""
|
|
471
|
+
echo "📋 Files in s3://$S3_BUCKET/stable/$VERSION/:"
|
|
472
|
+
aws s3 ls "s3://$S3_BUCKET/stable/$VERSION/" $ENDPOINT_ARG || true
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,64 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 2.0.0-next.293](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.292...v2.0.0-next.293)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2026-01-15**</sup>
|
|
8
|
+
|
|
9
|
+
#### ✨ Features
|
|
10
|
+
|
|
11
|
+
- **desktop**: Add desktop release service and API endpoint.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's improved
|
|
19
|
+
|
|
20
|
+
- **desktop**: Add desktop release service and API endpoint, closes [#11520](https://github.com/lobehub/lobe-chat/issues/11520) ([e3dc5be](https://github.com/lobehub/lobe-chat/commit/e3dc5be))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
## [Version 2.0.0-next.292](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.291...v2.0.0-next.292)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2026-01-15**</sup>
|
|
33
|
+
|
|
34
|
+
#### ♻ Code Refactoring
|
|
35
|
+
|
|
36
|
+
- **misc**: Use fallbackData to prevent useActionSWR auto-fetch.
|
|
37
|
+
|
|
38
|
+
#### ✨ Features
|
|
39
|
+
|
|
40
|
+
- **desktop**: Add local update testing scripts and stable channel API version check.
|
|
41
|
+
|
|
42
|
+
<br/>
|
|
43
|
+
|
|
44
|
+
<details>
|
|
45
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
46
|
+
|
|
47
|
+
#### Code refactoring
|
|
48
|
+
|
|
49
|
+
- **misc**: Use fallbackData to prevent useActionSWR auto-fetch, closes [#11514](https://github.com/lobehub/lobe-chat/issues/11514) ([d446163](https://github.com/lobehub/lobe-chat/commit/d446163))
|
|
50
|
+
|
|
51
|
+
#### What's improved
|
|
52
|
+
|
|
53
|
+
- **desktop**: Add local update testing scripts and stable channel API version check, closes [#11474](https://github.com/lobehub/lobe-chat/issues/11474) [#11513](https://github.com/lobehub/lobe-chat/issues/11513) ([959c210](https://github.com/lobehub/lobe-chat/commit/959c210))
|
|
54
|
+
|
|
55
|
+
</details>
|
|
56
|
+
|
|
57
|
+
<div align="right">
|
|
58
|
+
|
|
59
|
+
[](#readme-top)
|
|
60
|
+
|
|
61
|
+
</div>
|
|
62
|
+
|
|
5
63
|
## [Version 2.0.0-next.291](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.290...v2.0.0-next.291)
|
|
6
64
|
|
|
7
65
|
<sup>Released on **2026-01-15**</sup>
|
package/CLAUDE.md
CHANGED
|
@@ -57,55 +57,9 @@ see @.cursor/rules/typescript.mdc
|
|
|
57
57
|
- **Dev**: Translate `locales/zh-CN/namespace.json` and `locales/en-US/namespace.json` locales file only for dev preview
|
|
58
58
|
- DON'T run `pnpm i18n`, let CI auto handle it
|
|
59
59
|
|
|
60
|
-
## Linear Issue Management
|
|
60
|
+
## Linear Issue Management(ignore if not installed linear mcp)
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
1. **Retrieve issue details** before starting work using `mcp__linear-server__get_issue`
|
|
65
|
-
2. **Check for sub-issues**: If the issue has sub-issues, retrieve and review ALL sub-issues using `mcp__linear-server__list_issues` with `parentId` filter before starting work
|
|
66
|
-
3. **Update issue status** when completing tasks using `mcp__linear-server__update_issue`
|
|
67
|
-
4. **MUST add completion comment** using `mcp__linear-server__create_comment`
|
|
68
|
-
|
|
69
|
-
### Creating Issues
|
|
70
|
-
|
|
71
|
-
When creating new Linear issues using `mcp__linear-server__create_issue`, **MUST add the `claude code` label** to indicate the issue was created by Claude Code.
|
|
72
|
-
|
|
73
|
-
### Completion Comment (REQUIRED)
|
|
74
|
-
|
|
75
|
-
**Every time you complete an issue, you MUST add a comment summarizing the work done.** This is critical for:
|
|
76
|
-
|
|
77
|
-
- Team visibility and knowledge sharing
|
|
78
|
-
- Code review context
|
|
79
|
-
- Future reference and debugging
|
|
80
|
-
|
|
81
|
-
### PR Linear Issue Association (REQUIRED)
|
|
82
|
-
|
|
83
|
-
**When creating PRs for Linear issues, MUST include magic keywords in PR body:** `Fixes LOBE-123`, `Closes LOBE-123`, or `Resolves LOBE-123`, and summarize the work done in the linear issue comment and update the issue status to "In Review".
|
|
84
|
-
|
|
85
|
-
### IMPORTANT: Per-Issue Completion Rule
|
|
86
|
-
|
|
87
|
-
**When working on multiple issues (e.g., parent issue with sub-issues), you MUST update status and add comment for EACH issue IMMEDIATELY after completing it.** Do NOT wait until all issues are done to update them in batch.
|
|
88
|
-
|
|
89
|
-
**Workflow for EACH individual issue:**
|
|
90
|
-
|
|
91
|
-
1. Complete the implementation for this specific issue
|
|
92
|
-
2. Run type check: `bun run type-check`
|
|
93
|
-
3. Run related tests if applicable
|
|
94
|
-
4. Create PR if needed
|
|
95
|
-
5. **IMMEDIATELY** update issue status to **"In Review"** (NOT "Done"): `mcp__linear-server__update_issue`
|
|
96
|
-
6. **IMMEDIATELY** add completion comment: `mcp__linear-server__create_comment`
|
|
97
|
-
7. Only then move on to the next issue
|
|
98
|
-
|
|
99
|
-
**Note:** Issue status should be set to **"In Review"** when PR is created. The status will be updated to **"Done"** only after the PR is merged (usually handled by Linear-GitHub integration or manually).
|
|
100
|
-
|
|
101
|
-
**❌ Wrong approach:**
|
|
102
|
-
|
|
103
|
-
- Complete Issue A → Complete Issue B → Complete Issue C → Update all statuses → Add all comments
|
|
104
|
-
- Mark issue as "Done" immediately after creating PR
|
|
105
|
-
|
|
106
|
-
**✅ Correct approach:**
|
|
107
|
-
|
|
108
|
-
- Complete Issue A → Create PR → Update A status to "In Review" → Add A comment → Complete Issue B → ...
|
|
62
|
+
Read @.cursor/rules/linear.mdc when working with Linear issues.
|
|
109
63
|
|
|
110
64
|
## Rules Index
|
|
111
65
|
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
+
# 开发环境更新配置
|
|
2
|
+
# 可选择 GitHub 或 Generic provider 进行测试
|
|
3
|
+
|
|
4
|
+
# 方式1: GitHub Provider (默认)
|
|
1
5
|
provider: github
|
|
2
6
|
owner: lobehub
|
|
3
7
|
repo: lobe-chat
|
|
4
8
|
updaterCacheDirName: electron-app-updater
|
|
5
9
|
allowPrerelease: true
|
|
6
10
|
channel: nightly
|
|
11
|
+
|
|
12
|
+
# 方式2: Generic Provider (测试自定义服务器)
|
|
13
|
+
# 取消下面的注释,注释掉上面的 GitHub 配置
|
|
14
|
+
# provider: generic
|
|
15
|
+
# url: http://localhost:8080
|
|
16
|
+
# updaterCacheDirName: electron-app-updater
|
|
@@ -10,19 +10,47 @@ dotenv.config();
|
|
|
10
10
|
|
|
11
11
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
12
12
|
|
|
13
|
-
const packageJSON = JSON.parse(
|
|
14
|
-
await fs.readFile(path.join(__dirname, 'package.json'), 'utf8')
|
|
15
|
-
);
|
|
13
|
+
const packageJSON = JSON.parse(await fs.readFile(path.join(__dirname, 'package.json'), 'utf8'));
|
|
16
14
|
|
|
17
15
|
const channel = process.env.UPDATE_CHANNEL;
|
|
18
16
|
const arch = os.arch();
|
|
19
17
|
const hasAppleCertificate = Boolean(process.env.CSC_LINK);
|
|
20
18
|
|
|
19
|
+
// 自定义更新服务器 URL (用于 stable 频道)
|
|
20
|
+
const updateServerUrl = process.env.UPDATE_SERVER_URL;
|
|
21
|
+
|
|
21
22
|
console.log(`🚄 Build Version ${packageJSON.version}, Channel: ${channel}`);
|
|
22
23
|
console.log(`🏗️ Building for architecture: ${arch}`);
|
|
23
24
|
|
|
24
25
|
const isNightly = channel === 'nightly';
|
|
25
26
|
const isBeta = packageJSON.name.includes('beta');
|
|
27
|
+
const isStable = !isNightly && !isBeta;
|
|
28
|
+
|
|
29
|
+
// 根据 channel 配置不同的 publish provider
|
|
30
|
+
// - Stable + UPDATE_SERVER_URL: 使用 generic (自定义 HTTP 服务器)
|
|
31
|
+
// - Beta/Nightly: 仅使用 GitHub
|
|
32
|
+
const getPublishConfig = () => {
|
|
33
|
+
const githubProvider = {
|
|
34
|
+
owner: 'lobehub',
|
|
35
|
+
provider: 'github',
|
|
36
|
+
repo: 'lobe-chat',
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// Stable channel: 使用自定义服务器 (generic provider)
|
|
40
|
+
if (isStable && updateServerUrl) {
|
|
41
|
+
console.log(`📦 Stable channel: Using generic provider (${updateServerUrl})`);
|
|
42
|
+
const genericProvider = {
|
|
43
|
+
provider: 'generic',
|
|
44
|
+
url: updateServerUrl,
|
|
45
|
+
};
|
|
46
|
+
// 同时发布到自定义服务器和 GitHub (GitHub 作为备用/镜像)
|
|
47
|
+
return [genericProvider, githubProvider];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Beta/Nightly channel: 仅使用 GitHub
|
|
51
|
+
console.log(`📦 ${channel || 'default'} channel: Using GitHub provider`);
|
|
52
|
+
return [githubProvider];
|
|
53
|
+
};
|
|
26
54
|
|
|
27
55
|
// Keep only these Electron Framework localization folders (*.lproj)
|
|
28
56
|
// (aligned with previous Electron Forge build config)
|
|
@@ -221,13 +249,15 @@ const config = {
|
|
|
221
249
|
schemes: [protocolScheme],
|
|
222
250
|
},
|
|
223
251
|
],
|
|
224
|
-
publish:
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
252
|
+
publish: getPublishConfig(),
|
|
253
|
+
|
|
254
|
+
// Release notes 配置
|
|
255
|
+
// 可以通过环境变量 RELEASE_NOTES 传入,或从文件读取
|
|
256
|
+
// 这会被写入 latest-mac.yml / latest.yml 中,供 generic provider 使用
|
|
257
|
+
releaseInfo: {
|
|
258
|
+
releaseNotes: process.env.RELEASE_NOTES || undefined,
|
|
259
|
+
},
|
|
260
|
+
|
|
231
261
|
win: {
|
|
232
262
|
executableName: 'LobeHub',
|
|
233
263
|
},
|