forked from daodao97/code-switch
-
Notifications
You must be signed in to change notification settings - Fork 46
530 lines (439 loc) · 20.1 KB
/
Copy pathrelease.yml
File metadata and controls
530 lines (439 loc) · 20.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
name: Release
on:
push:
tags:
- 'v*'
permissions:
contents: write
jobs:
build-macos:
name: Build macOS
runs-on: macos-latest
strategy:
matrix:
arch: [arm64, amd64]
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- name: Update version from tag
id: version
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
echo "Updating version to: $VERSION"
sed -i '' "s/const AppVersion = \"v[^\"]*\"/const AppVersion = \"v$VERSION\"/" version_service.go
echo "Updated version_service.go:"
grep "AppVersion" version_service.go
- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: '1.24'
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '22'
- name: Install Wails
run: go install github.com/wailsapp/wails/v3/cmd/wails3@v3.0.0-alpha.38
- name: Install frontend dependencies
run: cd frontend && npm ci
- name: Build frontend assets for embed
run: cd frontend && npm run build
- name: Run backend tests
run: go test -timeout 60s ./...
- name: Run backend vet
run: go vet ./...
- name: Run frontend typecheck
run: cd frontend && npx vue-tsc --noEmit
- name: Update build assets
run: wails3 task common:update:build-assets
# update build-assets 会用 config.yml(0.1.0) 重新生成 Info.plist,版本必须在其之后注入
- name: Inject version into Info.plist
run: |
VERSION=${{ steps.version.outputs.VERSION }}
export VERSION
perl -0pi -e 's|(<key>CFBundleVersion</key>\s*<string>)[^<]*(</string>)|$1$ENV{VERSION}$2|; s|(<key>CFBundleShortVersionString</key>\s*<string>)[^<]*(</string>)|$1$ENV{VERSION}$2|' build/darwin/Info.plist
echo "Updated build/darwin/Info.plist:"
grep -A1 -E 'CFBundleVersion|CFBundleShortVersionString' build/darwin/Info.plist
# 两个版本键都必须已写入真实版本,否则直接失败
test "$(grep -c "<string>${VERSION}</string>" build/darwin/Info.plist)" -eq 2
- name: Generate bindings
run: wails3 task common:generate:bindings
- name: Build macOS ${{ matrix.arch }}
run: env ARCH=${{ matrix.arch }} wails3 task package
- name: Find app bundle
id: find-app
run: |
if [ -d "bin/codeswitch.app" ]; then
echo "app_path=bin/codeswitch.app" >> $GITHUB_OUTPUT
elif [ -d "bin/CodeSwitch.app" ]; then
echo "app_path=bin/CodeSwitch.app" >> $GITHUB_OUTPUT
else
echo "App bundle not found" >&2
exit 1
fi
- name: Archive macOS app
run: |
cd bin
ditto -c -k --sequesterRsrc --keepParent "$(basename ${{ steps.find-app.outputs.app_path }})" CodeSwitch-v${{ steps.version.outputs.VERSION }}-macos-${{ matrix.arch }}.zip
- name: Generate SHA256 Checksum
run: |
VERSION=${{ steps.version.outputs.VERSION }}
cd bin
shasum -a 256 "CodeSwitch-v${VERSION}-macos-${{ matrix.arch }}.zip" > "CodeSwitch-v${VERSION}-macos-${{ matrix.arch }}.zip.sha256"
cat "CodeSwitch-v${VERSION}-macos-${{ matrix.arch }}.zip.sha256"
- name: Upload artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: macos-${{ matrix.arch }}
path: |
bin/CodeSwitch-v${{ steps.version.outputs.VERSION }}-macos-${{ matrix.arch }}.zip
bin/CodeSwitch-v${{ steps.version.outputs.VERSION }}-macos-${{ matrix.arch }}.zip.sha256
build-windows:
name: Build Windows
runs-on: windows-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- name: Update version from tag
id: version
shell: pwsh
run: |
$VERSION = "${{ github.ref_name }}".TrimStart('v')
"VERSION=$VERSION" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
Write-Host "Updating version to: $VERSION"
# Update version_service.go
$content = Get-Content version_service.go -Raw
$content = $content -replace 'const AppVersion = "v[^"]*"', "const AppVersion = `"v$VERSION`""
Set-Content version_service.go $content
Write-Host "Updated version_service.go:"
Select-String "AppVersion" version_service.go
- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: '1.24'
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '22'
- name: Install Wails
run: go install github.com/wailsapp/wails/v3/cmd/wails3@v3.0.0-alpha.38
- name: Install frontend dependencies
run: cd frontend && npm ci
- name: Build frontend assets for embed
run: cd frontend && npm run build
- name: Run backend tests
run: go test -timeout 60s ./...
- name: Run backend vet
run: go vet ./...
- name: Run frontend typecheck
run: cd frontend && npx vue-tsc --noEmit
- name: Install NSIS
run: choco install nsis -y
- name: Update build assets
run: wails3 task common:update:build-assets
# update build-assets 会用 config.yml(0.1.0) 重新生成 info.json,版本必须在其之后注入,
# 否则 generate:syso 读到的 exe 版本资源恒为 0.1.0
- name: Inject version into build assets
shell: pwsh
run: |
$VERSION = "${{ steps.version.outputs.VERSION }}"
$json = Get-Content build/windows/info.json -Raw | ConvertFrom-Json
$json.fixed.file_version = $VERSION
$json.info.'0000'.ProductVersion = $VERSION
$json | ConvertTo-Json -Depth 10 | Set-Content build/windows/info.json
Write-Host "Updated build/windows/info.json:"
Get-Content build/windows/info.json
- name: Generate bindings
run: wails3 task common:generate:bindings
- name: Build Windows Binary
run: |
$env:ARCH = "amd64"
wails3 task windows:build
env:
PRODUCTION: "true"
- name: Verify Binary
run: |
if (Test-Path "bin\CodeSwitch.exe") {
Write-Host "✓ Binary found: bin\CodeSwitch.exe"
Get-Item "bin\CodeSwitch.exe" | Format-List Name,Length,LastWriteTime
} else {
Write-Host "✗ Binary not found!"
Write-Host "Listing bin directory:"
Get-ChildItem bin -ErrorAction SilentlyContinue
exit 1
}
- name: Create NSIS Installer
run: |
$env:PATH += ";C:\Program Files (x86)\NSIS"
Push-Location build\windows\nsis
wails3 generate webview2bootstrapper
$binaryPath = (Resolve-Path "..\..\..\bin\CodeSwitch.exe").Path
Write-Host "Binary path: $binaryPath"
# wails_tools.nsh 里 INFO_PRODUCTVERSION 默认 0.1.0,必须显式传入真实版本,
# 否则安装器版本资源与卸载注册表 DisplayVersion 全部错误
$VERSION = "${{ steps.version.outputs.VERSION }}"
makensis -DARG_WAILS_AMD64_BINARY="$binaryPath" -DINFO_PRODUCTVERSION="$VERSION" project.nsi
Pop-Location
- name: Rename files with version
shell: pwsh
run: |
$VERSION = "${{ steps.version.outputs.VERSION }}"
Push-Location bin
Rename-Item "CodeSwitch.exe" "CodeSwitch-v$VERSION.exe"
Pop-Location
# Rename installer (generated by NSIS)
if (Test-Path "build/windows/nsis/CodeSwitch-amd64-installer.exe") {
Move-Item "build/windows/nsis/CodeSwitch-amd64-installer.exe" "bin/CodeSwitch-v$VERSION-amd64-installer.exe"
} elseif (Test-Path "bin/CodeSwitch-amd64-installer.exe") {
Rename-Item "bin/CodeSwitch-amd64-installer.exe" "CodeSwitch-v$VERSION-amd64-installer.exe"
}
Write-Host "Files renamed:"
Get-ChildItem bin
- name: Generate SHA256 Checksums
shell: pwsh
run: |
$VERSION = "${{ steps.version.outputs.VERSION }}"
Push-Location bin
Get-FileHash -Algorithm SHA256 "CodeSwitch-v$VERSION.exe" | ForEach-Object { "$($_.Hash.ToLower()) CodeSwitch-v$VERSION.exe" } | Out-File -Encoding ascii "CodeSwitch-v$VERSION.exe.sha256"
Get-FileHash -Algorithm SHA256 "CodeSwitch-v$VERSION-amd64-installer.exe" | ForEach-Object { "$($_.Hash.ToLower()) CodeSwitch-v$VERSION-amd64-installer.exe" } | Out-File -Encoding ascii "CodeSwitch-v$VERSION-amd64-installer.exe.sha256"
Write-Host "SHA256 checksums generated:"
Get-Content *.sha256
Pop-Location
- name: Upload artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: windows-amd64
path: |
bin/CodeSwitch-v${{ steps.version.outputs.VERSION }}-amd64-installer.exe
bin/CodeSwitch-v${{ steps.version.outputs.VERSION }}-amd64-installer.exe.sha256
bin/CodeSwitch-v${{ steps.version.outputs.VERSION }}.exe
bin/CodeSwitch-v${{ steps.version.outputs.VERSION }}.exe.sha256
build-linux:
name: Build Linux
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- name: Update version from tag
id: version
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
echo "Updating version to: $VERSION"
sed -i "s/const AppVersion = \"v[^\"]*\"/const AppVersion = \"v$VERSION\"/" version_service.go
echo "Updated version_service.go:"
grep "AppVersion" version_service.go
- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: '1.24'
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '22'
- name: Install Linux Build Dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
pkg-config \
libgtk-4-dev \
libwebkitgtk-6.0-dev \
libgtk-3-dev \
libwebkit2gtk-4.1-dev
- name: Install Wails
run: go install github.com/wailsapp/wails/v3/cmd/wails3@v3.0.0-alpha.38
- name: Install frontend dependencies
run: cd frontend && npm ci
- name: Build frontend assets for embed
run: cd frontend && npm run build
- name: Run backend tests
run: go test -timeout 60s ./...
- name: Run backend vet
run: go vet ./...
- name: Run frontend typecheck
run: cd frontend && npx vue-tsc --noEmit
- name: Update build assets
run: wails3 task common:update:build-assets
- name: Generate bindings
run: wails3 task common:generate:bindings
- name: Build Linux Binary
run: wails3 task linux:build
env:
PRODUCTION: "true"
- name: Generate Desktop File
run: wails3 task linux:generate:dotdesktop
- name: Create AppImage
run: wails3 task linux:create:appimage
- name: Rename AppImage
run: |
VERSION=${{ steps.version.outputs.VERSION }}
cd bin
echo "Files in bin/:"
ls -la
# linuxdeploy creates AppImage with lowercase name and arch suffix
for f in *-x86_64.AppImage *-aarch64.AppImage; do
if [ -f "$f" ]; then
mv "$f" "CodeSwitch-v${VERSION}.AppImage"
echo "Renamed $f -> CodeSwitch-v${VERSION}.AppImage"
break
fi
done
ls -la "CodeSwitch-v${VERSION}.AppImage"
- name: Set nfpm script permissions
run: |
chmod +x build/linux/nfpm/scripts/postinstall.sh
chmod +x build/linux/nfpm/scripts/postremove.sh
- name: Update nfpm version
run: |
VERSION=${GITHUB_REF#refs/tags/v}
sed -i "s/^version:.*/version: \"$VERSION\"/" build/linux/nfpm/nfpm.yaml
echo "Updated nfpm version to: $VERSION"
# update build-assets 可能用模板重置 nfpm.yaml(postremove 被注释),此处幂等地重新启用卸载脚本
sed -i 's|^ # postremove:.*| postremove: "./build/linux/nfpm/scripts/postremove.sh"|' build/linux/nfpm/nfpm.yaml
grep -n "postremove" build/linux/nfpm/nfpm.yaml
- name: Create DEB Package
run: wails3 task linux:create:deb
- name: Create RPM Package
run: wails3 task linux:create:rpm
# wails3 tool package 固定输出 CodeSwitch.deb / CodeSwitch.rpm,
# 重命名为发行版惯例文件名;找不到产物直接失败,避免发布时静默缺失
- name: Rename Linux Packages
run: |
VERSION=${{ steps.version.outputs.VERSION }}
cd bin
echo "Files in bin/:"
ls -la
if [ -f CodeSwitch.deb ]; then mv CodeSwitch.deb "codeswitch_${VERSION}_amd64.deb"; fi
if [ -f CodeSwitch.rpm ]; then mv CodeSwitch.rpm "codeswitch-${VERSION}-1.x86_64.rpm"; fi
test -f "codeswitch_${VERSION}_amd64.deb"
test -f "codeswitch-${VERSION}-1.x86_64.rpm"
- name: Generate SHA256 Checksums
run: |
VERSION=${{ steps.version.outputs.VERSION }}
cd bin
sha256sum "CodeSwitch-v${VERSION}.AppImage" > "CodeSwitch-v${VERSION}.AppImage.sha256"
sha256sum "codeswitch_${VERSION}_amd64.deb" > "codeswitch_${VERSION}_amd64.deb.sha256"
sha256sum "codeswitch-${VERSION}-1.x86_64.rpm" > "codeswitch-${VERSION}-1.x86_64.rpm.sha256"
echo "SHA256 checksums:"
cat *.sha256
- name: Upload artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: linux-amd64
path: |
bin/CodeSwitch-v${{ steps.version.outputs.VERSION }}.AppImage
bin/CodeSwitch-v${{ steps.version.outputs.VERSION }}.AppImage.sha256
bin/codeswitch_*.deb
bin/codeswitch_*.deb.sha256
bin/codeswitch-*.rpm
bin/codeswitch-*.rpm.sha256
create-release:
name: Create Release
needs: [build-macos, build-windows, build-linux]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- name: Download all artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
path: artifacts
- name: Display structure
run: ls -R artifacts
- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: '3.12'
- name: Prepare release assets
run: |
VERSION=${GITHUB_REF#refs/tags/v}
mkdir -p release-assets
# macOS
cp artifacts/macos-arm64/CodeSwitch-v${VERSION}-macos-arm64.zip release-assets/
cp artifacts/macos-arm64/CodeSwitch-v${VERSION}-macos-arm64.zip.sha256 release-assets/
cp artifacts/macos-amd64/CodeSwitch-v${VERSION}-macos-amd64.zip release-assets/
cp artifacts/macos-amd64/CodeSwitch-v${VERSION}-macos-amd64.zip.sha256 release-assets/
# Windows
cp artifacts/windows-amd64/CodeSwitch-v${VERSION}-amd64-installer.exe release-assets/
cp artifacts/windows-amd64/CodeSwitch-v${VERSION}-amd64-installer.exe.sha256 release-assets/
cp artifacts/windows-amd64/CodeSwitch-v${VERSION}.exe release-assets/
cp artifacts/windows-amd64/CodeSwitch-v${VERSION}.exe.sha256 release-assets/
# Linux(deb/rpm 已在构建 job 中强制校验存在,此处缺失应直接失败而非静默跳过)
cp artifacts/linux-amd64/CodeSwitch-v${VERSION}.AppImage release-assets/
cp artifacts/linux-amd64/CodeSwitch-v${VERSION}.AppImage.sha256 release-assets/
cp artifacts/linux-amd64/codeswitch_*.deb release-assets/
cp artifacts/linux-amd64/codeswitch_*.deb.sha256 release-assets/
cp artifacts/linux-amd64/codeswitch-*.rpm release-assets/
cp artifacts/linux-amd64/codeswitch-*.rpm.sha256 release-assets/
ls -lh release-assets/
- name: Generate latest.json
run: |
VERSION=${GITHUB_REF#refs/tags/v}
python3 scripts/generate-latest-json.py "v${VERSION}" release-assets release-assets/latest.json
echo "Generated latest.json:"
cat release-assets/latest.json
- name: Generate release body
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "Generating release body for v$VERSION"
# 提取当前版本的更新内容(从标题之后到下一个版本标题之前)
# 注意:先用 tr 去除 Windows CRLF 换行符,否则 awk 匹配失败;
# 不能用 awk 区间模式 /起/,/止/:标题行同时命中首尾模式时区间只含标题行本身
tr -d '\r' < RELEASE_NOTES.md | awk -v ver="$VERSION" '
$0 == "# Code Switch v" ver {found=1; next}
found && /^# Code Switch v[0-9]/ {exit}
found {lines[++n]=$0}
END {
# 去掉尾部的空行与 "---" 分隔线,后面拼接 release body 时会另加分隔
while (n > 0 && (lines[n] ~ /^[[:space:]]*$/ || lines[n] == "---")) n--
for (i=1; i<=n; i++) print lines[i]
}
' > /tmp/version_notes.md
# 如果没找到版本说明,使用默认内容
if [ ! -s /tmp/version_notes.md ]; then
echo "## 更新亮点" > /tmp/version_notes.md
echo "- 请查看提交历史了解详细更新" >> /tmp/version_notes.md
fi
# 组合完整的 release body
cat /tmp/version_notes.md > /tmp/release_body.md
cat >> /tmp/release_body.md << EOF
---
## 下载说明
| 平台 | 文件 | 说明 |
|------|------|------|
| **Windows (首次)** | \`CodeSwitch-v${VERSION}-amd64-installer.exe\` | NSIS 安装器 |
| **Windows (便携)** | \`CodeSwitch-v${VERSION}.exe\` | 直接运行 |
| **macOS (ARM)** | \`CodeSwitch-v${VERSION}-macos-arm64.zip\` | Apple Silicon |
| **macOS (Intel)** | \`CodeSwitch-v${VERSION}-macos-amd64.zip\` | Intel 芯片 |
| **Linux (通用)** | \`CodeSwitch-v${VERSION}.AppImage\` | 跨发行版便携 |
| **Linux (Debian/Ubuntu)** | \`codeswitch_*.deb\` | apt 安装 |
| **Linux (RHEL/Fedora)** | \`codeswitch-*.rpm\` | dnf/yum 安装 |
## Linux 安装
### AppImage (推荐)
\`\`\`bash
chmod +x CodeSwitch-v${VERSION}.AppImage
./CodeSwitch-v${VERSION}.AppImage
\`\`\`
如遇 FUSE 问题:\`./CodeSwitch-v${VERSION}.AppImage --appimage-extract-and-run\`
### Debian/Ubuntu
\`\`\`bash
sudo dpkg -i codeswitch_*.deb
sudo apt-get install -f # 安装依赖
\`\`\`
### RHEL/Fedora
\`\`\`bash
sudo rpm -i codeswitch-*.rpm
# 或
sudo dnf install codeswitch-*.rpm
\`\`\`
## 文件校验
所有平台均提供 SHA256 校验文件(\`.sha256\`),下载后可验证完整性:
\`\`\`bash
# Linux/macOS
sha256sum -c CodeSwitch-v${VERSION}.AppImage.sha256
# Windows PowerShell
Get-FileHash CodeSwitch-v${VERSION}.exe | Format-List
\`\`\`
EOF
echo "Generated release body:"
cat /tmp/release_body.md
- name: Create Release
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
with:
files: release-assets/*
body_path: /tmp/release_body.md
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}