cicy-desktop 2.1.129 → 2.1.131
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/.github/workflows/windows-exe-release.yml +51 -8
- package/bin/cicy-desktop +47 -8
- package/package.json +1 -1
- package/cicy-dektop.command +0 -51
|
@@ -95,15 +95,18 @@ jobs:
|
|
|
95
95
|
path: dist/*.exe
|
|
96
96
|
if-no-files-found: error
|
|
97
97
|
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
#
|
|
101
|
-
|
|
98
|
+
# 推 exe 到 OSS。三件事(不再是"永远一个版本"):
|
|
99
|
+
# 1) 带版本号的永久副本 releases/cicy-desktop-<version>.exe — 历史 / 指定版本 / 回滚
|
|
100
|
+
# 2) latest 指针 releases/cicy-desktop-latest.exe — 只前进:本次版本 < 已发布版本(更旧的
|
|
101
|
+
# 构建后完成)则不覆盖,避免并发构建竞态把 latest 退回旧版
|
|
102
|
+
# 3) releases/latest-version.txt — 记录 latest 当前是哪个版本,curl 一下即可核对,无需猜 exe
|
|
103
|
+
- name: Upload EXE to OSS (versioned + forward-only latest pointer)
|
|
102
104
|
shell: pwsh
|
|
103
105
|
env:
|
|
104
106
|
OSS_AK: ${{ secrets.OSS_ACCESS_KEY_ID }}
|
|
105
107
|
OSS_SK: ${{ secrets.OSS_ACCESS_KEY_SECRET }}
|
|
106
108
|
run: |
|
|
109
|
+
$version = "${{ steps.meta.outputs.version }}"
|
|
107
110
|
Invoke-WebRequest -Uri "https://gosspublic.alicdn.com/ossutil/1.7.18/ossutil-v1.7.18-windows-amd64.zip" -OutFile ossutil.zip
|
|
108
111
|
Expand-Archive -LiteralPath ossutil.zip -DestinationPath ossutil-dir -Force
|
|
109
112
|
$oss = "ossutil-dir\ossutil-v1.7.18-windows-amd64\ossutil.exe"
|
|
@@ -111,10 +114,50 @@ jobs:
|
|
|
111
114
|
$exe = Get-ChildItem dist\*.exe | Where-Object { $_.Name -match 'Setup' } | Select-Object -First 1
|
|
112
115
|
if (-not $exe) { $exe = Get-ChildItem dist\*.exe | Select-Object -First 1 }
|
|
113
116
|
if (-not $exe) { Write-Error "no exe found in dist"; exit 1 }
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
117
|
+
$base = "oss://cicy-1372193042-cn/releases"
|
|
118
|
+
|
|
119
|
+
# 1) 永久版本化副本(unique key — 不会被后续发版覆盖)
|
|
120
|
+
$verKey = "$base/cicy-desktop-$version.exe"
|
|
121
|
+
Write-Host "Uploading versioned -> $verKey"
|
|
122
|
+
& $oss cp "$($exe.FullName)" "$verKey" -f --acl public-read
|
|
123
|
+
if ($LASTEXITCODE -ne 0) { Write-Error "versioned upload failed"; exit 1 }
|
|
124
|
+
|
|
125
|
+
# 2) latest 指针 — 只在本次版本 >= 已发布版本时前进
|
|
126
|
+
& $oss cp "$base/latest-version.txt" "current-latest.txt" -f 2>$null
|
|
127
|
+
$cur = if (Test-Path "current-latest.txt") { (Get-Content "current-latest.txt" -Raw).Trim() } else { "0.0.0" }
|
|
128
|
+
$advance = $true
|
|
129
|
+
try { $advance = ([version]$version -ge [version]$cur) } catch { $advance = $true }
|
|
130
|
+
if ($advance) {
|
|
131
|
+
Write-Host "Advancing latest: $cur -> $version"
|
|
132
|
+
& $oss cp "$($exe.FullName)" "$base/cicy-desktop-latest.exe" -f --acl public-read
|
|
133
|
+
if ($LASTEXITCODE -ne 0) { Write-Error "latest upload failed"; exit 1 }
|
|
134
|
+
Set-Content -NoNewline -Path "current-latest.txt" -Value $version
|
|
135
|
+
& $oss cp "current-latest.txt" "$base/latest-version.txt" -f --acl public-read
|
|
136
|
+
if ($LASTEXITCODE -ne 0) { Write-Error "latest-version.txt upload failed"; exit 1 }
|
|
137
|
+
} else {
|
|
138
|
+
Write-Host "Skip latest: building $version < published $cur (older build — not clobbering newer latest)"
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
# 3) 保留策略 — 只留最近 $KEEP 个版本化 exe(~130MB/个),旧的删掉,避免 OSS 无限膨胀。
|
|
142
|
+
# latest.exe / latest-version.txt 不在此列(名字不匹配 X.Y.Z),永远保留。
|
|
143
|
+
$KEEP = 2
|
|
144
|
+
$versions = @()
|
|
145
|
+
foreach ($l in (& $oss ls "$base/" 2>$null)) {
|
|
146
|
+
if ($l -match 'releases/cicy-desktop-(\d+\.\d+\.\d+)\.exe\s*$') { $versions += $matches[1] }
|
|
147
|
+
}
|
|
148
|
+
$sorted = @($versions | Sort-Object { [version]$_ } -Descending)
|
|
149
|
+
if ($sorted.Count -gt $KEEP) {
|
|
150
|
+
foreach ($v in ($sorted | Select-Object -Skip $KEEP)) {
|
|
151
|
+
Write-Host "Pruning old versioned exe: cicy-desktop-$v.exe"
|
|
152
|
+
& $oss rm "$base/cicy-desktop-$v.exe" -f 2>$null
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
Write-Host "Retention: $($sorted.Count) versioned exe(s) <= keep $KEEP, nothing to prune"
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
Write-Host "Versioned : https://cicy-1372193042-cn.oss-cn-shanghai.aliyuncs.com/releases/cicy-desktop-$version.exe"
|
|
159
|
+
Write-Host "Latest : https://cicy-1372193042-cn.oss-cn-shanghai.aliyuncs.com/releases/cicy-desktop-latest.exe"
|
|
160
|
+
Write-Host "Version-of: https://cicy-1372193042-cn.oss-cn-shanghai.aliyuncs.com/releases/latest-version.txt"
|
|
118
161
|
|
|
119
162
|
- name: Publish release (drop draft, mark latest)
|
|
120
163
|
# Only promote AFTER all assets uploaded successfully. autoUpdater on
|
package/bin/cicy-desktop
CHANGED
|
@@ -7,6 +7,14 @@ const isWindows = process.platform === "win32";
|
|
|
7
7
|
const { MasterTokenManager } = require("../src/master/master-main");
|
|
8
8
|
const { version: CLI_VERSION } = require("../package.json");
|
|
9
9
|
|
|
10
|
+
// Windows consoles default to a legacy OEM codepage (936/GBK on zh-CN), which
|
|
11
|
+
// renders our UTF-8 output (emoji + 中文) as 乱码. Flip the active console to
|
|
12
|
+
// UTF-8 (65001) before anything prints. Best-effort: harmless if redirected,
|
|
13
|
+
// unsupported, or already UTF-8.
|
|
14
|
+
if (isWindows) {
|
|
15
|
+
try { execSync("chcp 65001", { stdio: "ignore" }); } catch {}
|
|
16
|
+
}
|
|
17
|
+
|
|
10
18
|
const HOME = os.homedir();
|
|
11
19
|
const DESKTOP_DIR = path.join(HOME, "Desktop");
|
|
12
20
|
const GLOBAL_CONFIG_FILE = path.join(HOME, "global.json");
|
|
@@ -170,19 +178,42 @@ function provisionElectronFromMirror(bundledDir) {
|
|
|
170
178
|
// into the bundled npx copy straight from the R2 mirror — NO `npm i -g`, NO
|
|
171
179
|
// GitHub, NO @electron/get. This is what lets a single `npx cicy-desktop`
|
|
172
180
|
// self-provision electron and start first-try. Runs once per process.
|
|
181
|
+
// The electron dir we provision into: the real electron npm package if it's
|
|
182
|
+
// installed, otherwise a self-managed dir under our own node_modules. `npx
|
|
183
|
+
// cicy-desktop` does NOT pull electron (it's not a runtime dep), so on a fresh
|
|
184
|
+
// machine require.resolve('electron') fails — we must NOT give up there.
|
|
185
|
+
function bundledElectronDir() {
|
|
186
|
+
try { return path.dirname(require.resolve("electron/package.json", { paths: [PACKAGE_ROOT] })); } catch {}
|
|
187
|
+
return path.join(PACKAGE_ROOT, "node_modules", "electron");
|
|
188
|
+
}
|
|
189
|
+
// Make `dir` a resolvable electron package (package.json + index.js that reads
|
|
190
|
+
// path.txt) so provisionElectronFromMirror's layout + a spawned require('electron')
|
|
191
|
+
// both work — WITHOUT ever running electron's own installer. Only fills in missing
|
|
192
|
+
// files, so a real electron package is left untouched.
|
|
193
|
+
function ensureMinimalElectronPkg(dir) {
|
|
194
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
195
|
+
const pj = path.join(dir, "package.json");
|
|
196
|
+
if (!fs.existsSync(pj)) fs.writeFileSync(pj, JSON.stringify({ name: "electron", version: ELECTRON_VERSION, main: "index.js" }));
|
|
197
|
+
const ij = path.join(dir, "index.js");
|
|
198
|
+
if (!fs.existsSync(ij)) fs.writeFileSync(ij,
|
|
199
|
+
"const fs=require('fs'),path=require('path');const p=path.join(__dirname,'path.txt');" +
|
|
200
|
+
"module.exports=fs.existsSync(p)?path.join(__dirname,'dist',fs.readFileSync(p,'utf8').trim()):null;\n");
|
|
201
|
+
}
|
|
202
|
+
|
|
173
203
|
let _electronEnsured = false;
|
|
174
204
|
function ensureElectron() {
|
|
175
205
|
if (_electronEnsured) return;
|
|
176
206
|
_electronEnsured = true;
|
|
177
|
-
// Already usable (a shared global, or
|
|
207
|
+
// Already usable (a shared global, or an already-provisioned bundled copy)? done.
|
|
178
208
|
if (electronBinaryHealthy(globalElectronDir())) return;
|
|
179
|
-
|
|
180
|
-
try { bundledDir = path.dirname(require.resolve("electron/package.json", { paths: [PACKAGE_ROOT] })); } catch {}
|
|
209
|
+
const bundledDir = bundledElectronDir();
|
|
181
210
|
if (electronBinaryHealthy(bundledDir)) return;
|
|
182
|
-
if
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
211
|
+
// Set up the dir (create minimal pkg if electron isn't installed) then download
|
|
212
|
+
// the binary straight from the mirror — bypassing electron's own installer,
|
|
213
|
+
// which is broken on win32 + node 24 (@electron-internal extract-zip native
|
|
214
|
+
// binding "intentionally not published" → "Cannot find native binding").
|
|
215
|
+
try { ensureMinimalElectronPkg(bundledDir); }
|
|
216
|
+
catch (e) { console.warn(`⚠️ could not set up electron dir ${bundledDir}: ${e.message}`); return; }
|
|
186
217
|
console.log(`⚙️ Fetching Electron ${ELECTRON_VERSION} from mirror (one-time)…`);
|
|
187
218
|
try {
|
|
188
219
|
provisionElectronFromMirror(bundledDir);
|
|
@@ -200,9 +231,17 @@ function resolveElectronSpawn() {
|
|
|
200
231
|
ensureElectron();
|
|
201
232
|
const g = globalElectronBin();
|
|
202
233
|
if (g) return { cmd: g, prefixArgs: [] };
|
|
203
|
-
|
|
234
|
+
// Spawn the self-provisioned binary DIRECTLY (mirror download → <dir>/dist/<exe>).
|
|
235
|
+
// Critically: prefer this over `npx electron` — electron's own installer is
|
|
236
|
+
// broken on win32 + node 24, so the npx fallback below just crashes there.
|
|
237
|
+
try {
|
|
238
|
+
const { exe } = electronArtifact();
|
|
239
|
+
const bin = path.join(bundledElectronDir(), "dist", exe);
|
|
240
|
+
if (fs.existsSync(bin)) return { cmd: bin, prefixArgs: [] };
|
|
241
|
+
} catch {}
|
|
204
242
|
const local = path.join(PACKAGE_ROOT, "node_modules", ".bin", "electron");
|
|
205
243
|
if (fs.existsSync(local)) return { cmd: local, prefixArgs: [] };
|
|
244
|
+
if (isWindows) return { cmd: "npx.cmd", prefixArgs: ["electron"] };
|
|
206
245
|
return { cmd: "npx", prefixArgs: ["electron"] };
|
|
207
246
|
}
|
|
208
247
|
const PROJECT_COMMAND_FILE = path.join(PACKAGE_ROOT, "cicy-dektop.command");
|
package/package.json
CHANGED
package/cicy-dektop.command
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
#!/bin/zsh
|
|
2
|
-
set -e
|
|
3
|
-
|
|
4
|
-
PROJECT_DIR="/Users/ton/projects/cicy-desktop"
|
|
5
|
-
|
|
6
|
-
exec 2>&1
|
|
7
|
-
|
|
8
|
-
echo "========================================="
|
|
9
|
-
echo " 🚀 CiCy Desktop Master + Worker"
|
|
10
|
-
echo " 📅 $(date '+%Y-%m-%d %H:%M:%S')"
|
|
11
|
-
echo "========================================="
|
|
12
|
-
|
|
13
|
-
if [ ! -d "$PROJECT_DIR" ]; then
|
|
14
|
-
echo "❌ Project directory not found: $PROJECT_DIR"
|
|
15
|
-
echo "按回车键退出..."
|
|
16
|
-
read
|
|
17
|
-
exit 1
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
cd "$PROJECT_DIR" || {
|
|
21
|
-
echo "❌ Failed to cd into project directory"
|
|
22
|
-
echo "按回车键退出..."
|
|
23
|
-
read
|
|
24
|
-
exit 1
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
echo "📁 Project: $PROJECT_DIR"
|
|
28
|
-
|
|
29
|
-
# Dev override: if .env.dev exists in the project root, source it before
|
|
30
|
-
# npm start. Useful for CICY_HOMEPAGE_URL=http://localhost:8173 to load
|
|
31
|
-
# the workers/render vite dev server (HMR) into the BrowserWindow instead
|
|
32
|
-
# of the production CF Worker / bundled file://.
|
|
33
|
-
if [ -f "$PROJECT_DIR/.env.dev" ]; then
|
|
34
|
-
echo "🧪 .env.dev detected — loading dev overrides"
|
|
35
|
-
set -a
|
|
36
|
-
. "$PROJECT_DIR/.env.dev"
|
|
37
|
-
set +a
|
|
38
|
-
fi
|
|
39
|
-
|
|
40
|
-
echo "🚀 Running: npm start"
|
|
41
|
-
echo "⚠️ 关闭此窗口将停止 Master 和 Worker"
|
|
42
|
-
echo "========================================="
|
|
43
|
-
echo ""
|
|
44
|
-
|
|
45
|
-
npm start
|
|
46
|
-
|
|
47
|
-
echo ""
|
|
48
|
-
echo "========================================="
|
|
49
|
-
echo "Master + Worker 已停止"
|
|
50
|
-
echo "按回车键关闭窗口..."
|
|
51
|
-
read
|