1
0

feat: 扩展发布打包支持多组件多架构多格式产物

- 新增 web 组件独立发布为 nex-web_<version>.tar.gz
- server 新增 arm64 架构、macOS universal、Windows arm64 产物
- desktop 新增 arm64 架构支持(Linux/Windows)
- Linux desktop 新增 AppImage、deb、rpm 安装包格式
- macOS desktop 新增 unsigned DMG 安装包
- 统一发布资产命名为 {component}_{version}_{platform}_{arch}.{ext}
- 新增 SHA256SUMS 校验和清单覆盖全部发布资产
- versionctl 新增 asset-name CLI 支持按参数生成资产文件名
- Makefile release target 重构为组件/平台/架构参数化
- GitHub Actions release workflow 扩展多组件多架构构建矩阵
- 同步更新 openspec 主规范(desktop-app/release-pipeline/workspace-command-flows)
This commit is contained in:
2026-05-05 12:36:33 +08:00
parent 6de7a2d2e1
commit c9c3a84b33
13 changed files with 806 additions and 208 deletions

View File

@@ -83,20 +83,72 @@ func TestVerifyTag(t *testing.T) {
}
func TestAssetNames(t *testing.T) {
linuxServer, err := ServerAssetName("1.2.3", "linux", "amd64")
require.NoError(t, err)
assert.Equal(t, "nex-server_1.2.3_linux_amd64.tar.gz", linuxServer)
testCases := []struct {
name string
component string
platform string
arch string
format string
want string
}{
{"server linux amd64", "server", "linux", "amd64", "tar.gz", "nex-server_1.2.3_linux_amd64.tar.gz"},
{"server linux arm64", "server", "linux", "arm64", "tar.gz", "nex-server_1.2.3_linux_arm64.tar.gz"},
{"server macos amd64", "server", "macos", "amd64", "tar.gz", "nex-server_1.2.3_macos_amd64.tar.gz"},
{"server macos arm64", "server", "macos", "arm64", "tar.gz", "nex-server_1.2.3_macos_arm64.tar.gz"},
{"server macos universal", "server", "macos", "universal", "tar.gz", "nex-server_1.2.3_macos_universal.tar.gz"},
{"server windows amd64", "server", "windows", "amd64", "zip", "nex-server_1.2.3_windows_amd64.zip"},
{"server windows arm64", "server", "windows", "arm64", "zip", "nex-server_1.2.3_windows_arm64.zip"},
{"web", "web", "", "", "tar.gz", "nex-web_1.2.3.tar.gz"},
{"desktop linux amd64 tar", "desktop", "linux", "amd64", "tar.gz", "nex-desktop_1.2.3_linux_amd64.tar.gz"},
{"desktop linux amd64 appimage", "desktop", "linux", "amd64", "AppImage", "nex-desktop_1.2.3_linux_amd64.AppImage"},
{"desktop linux amd64 deb", "desktop", "linux", "amd64", "deb", "nex-desktop_1.2.3_linux_amd64.deb"},
{"desktop linux amd64 rpm", "desktop", "linux", "amd64", "rpm", "nex-desktop_1.2.3_linux_amd64.rpm"},
{"desktop linux arm64 tar", "desktop", "linux", "arm64", "tar.gz", "nex-desktop_1.2.3_linux_arm64.tar.gz"},
{"desktop linux arm64 appimage", "desktop", "linux", "arm64", "AppImage", "nex-desktop_1.2.3_linux_arm64.AppImage"},
{"desktop linux arm64 deb", "desktop", "linux", "arm64", "deb", "nex-desktop_1.2.3_linux_arm64.deb"},
{"desktop linux arm64 rpm", "desktop", "linux", "arm64", "rpm", "nex-desktop_1.2.3_linux_arm64.rpm"},
{"desktop macos zip", "desktop", "macos", "universal", "zip", "nex-desktop_1.2.3_macos_universal.zip"},
{"desktop macos dmg", "desktop", "macos", "universal", "dmg", "nex-desktop_1.2.3_macos_universal.dmg"},
{"desktop windows amd64", "desktop", "windows", "amd64", "zip", "nex-desktop_1.2.3_windows_amd64.zip"},
{"desktop windows arm64", "desktop", "windows", "arm64", "zip", "nex-desktop_1.2.3_windows_arm64.zip"},
}
macServer, err := ServerAssetName("1.2.3", "darwin", "arm64")
require.NoError(t, err)
assert.Equal(t, "nex-server_1.2.3_darwin_arm64.tar.gz", macServer)
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
got, err := ReleaseAssetName("1.2.3", tc.component, tc.platform, tc.arch, tc.format)
require.NoError(t, err)
assert.Equal(t, tc.want, got)
})
}
macDesktop, err := DesktopAssetName("1.2.3", "macos")
require.NoError(t, err)
assert.Equal(t, "Nex_1.2.3_macOS_universal.zip", macDesktop)
invalidCases := []struct {
name string
component string
platform string
arch string
format string
}{
{"invalid version", "server", "linux", "amd64", "tar.gz"},
{"invalid component", "mobile", "linux", "amd64", "tar.gz"},
{"darwin platform", "server", "darwin", "arm64", "tar.gz"},
{"server unsupported format", "server", "linux", "amd64", "zip"},
{"server unsupported arch", "server", "windows", "universal", "zip"},
{"web with platform", "web", "linux", "amd64", "tar.gz"},
{"web unsupported format", "web", "", "", "zip"},
{"desktop unsupported platform", "desktop", "ios", "arm64", "zip"},
{"desktop unsupported format", "desktop", "macos", "universal", "tar.gz"},
}
_, err = DesktopAssetName("1.2.3", "ios")
assert.Error(t, err)
for _, tc := range invalidCases {
t.Run(tc.name, func(t *testing.T) {
version := "1.2.3"
if tc.name == "invalid version" {
version = "1.2"
}
_, err := ReleaseAssetName(version, tc.component, tc.platform, tc.arch, tc.format)
assert.Error(t, err)
})
}
}
func TestDesktopInfoPlist(t *testing.T) {