Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 49b47a1ae0 | |||
| bcf82d42bc | |||
| 394025c8ea | |||
| 34bd749741 | |||
| 290f299e22 | |||
| 859dec8ada |
26
.github/workflows/release.yml
vendored
26
.github/workflows/release.yml
vendored
@@ -136,7 +136,7 @@ jobs:
|
|||||||
make release-assets-check
|
make release-assets-check
|
||||||
|
|
||||||
- name: Build Linux release assets
|
- name: Build Linux release assets
|
||||||
run: make release-assets-linux TARGET_ARCH=${{ matrix.arch }}
|
run: make release-assets-linux
|
||||||
|
|
||||||
- name: Upload Linux release assets
|
- name: Upload Linux release assets
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
@@ -148,18 +148,24 @@ jobs:
|
|||||||
build-windows:
|
build-windows:
|
||||||
name: Build Windows ${{ matrix.arch }} Assets
|
name: Build Windows ${{ matrix.arch }} Assets
|
||||||
needs: prepare
|
needs: prepare
|
||||||
runs-on: windows-latest
|
runs-on: ${{ matrix.runner }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- arch: amd64
|
- arch: amd64
|
||||||
|
runner: windows-latest
|
||||||
msystem: MINGW64
|
msystem: MINGW64
|
||||||
|
cc: gcc
|
||||||
|
cxx: g++
|
||||||
packages: >-
|
packages: >-
|
||||||
make
|
make
|
||||||
mingw-w64-x86_64-gcc
|
mingw-w64-x86_64-gcc
|
||||||
- arch: arm64
|
- arch: arm64
|
||||||
|
runner: windows-11-arm
|
||||||
msystem: CLANGARM64
|
msystem: CLANGARM64
|
||||||
|
cc: clang
|
||||||
|
cxx: clang++
|
||||||
packages: >-
|
packages: >-
|
||||||
make
|
make
|
||||||
mingw-w64-clang-aarch64-clang
|
mingw-w64-clang-aarch64-clang
|
||||||
@@ -193,6 +199,9 @@ jobs:
|
|||||||
|
|
||||||
- name: Preflight Windows release toolchain
|
- name: Preflight Windows release toolchain
|
||||||
shell: msys2 {0}
|
shell: msys2 {0}
|
||||||
|
env:
|
||||||
|
CC: ${{ matrix.cc }}
|
||||||
|
CXX: ${{ matrix.cxx }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
command -v go
|
command -v go
|
||||||
@@ -201,9 +210,11 @@ jobs:
|
|||||||
bun --version
|
bun --version
|
||||||
command -v make
|
command -v make
|
||||||
make --version
|
make --version
|
||||||
|
command -v "$CC"
|
||||||
|
"$CC" --version
|
||||||
|
command -v "$CXX"
|
||||||
|
"$CXX" --version
|
||||||
if [ "${{ matrix.arch }}" = "arm64" ]; then
|
if [ "${{ matrix.arch }}" = "arm64" ]; then
|
||||||
command -v clang
|
|
||||||
clang --version
|
|
||||||
if command -v llvm-windres >/dev/null 2>&1; then
|
if command -v llvm-windres >/dev/null 2>&1; then
|
||||||
llvm-windres --version
|
llvm-windres --version
|
||||||
else
|
else
|
||||||
@@ -211,8 +222,6 @@ jobs:
|
|||||||
windres --version
|
windres --version
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
command -v gcc
|
|
||||||
gcc --version
|
|
||||||
command -v windres
|
command -v windres
|
||||||
windres --version
|
windres --version
|
||||||
fi
|
fi
|
||||||
@@ -226,7 +235,10 @@ jobs:
|
|||||||
|
|
||||||
- name: Build Windows release assets
|
- name: Build Windows release assets
|
||||||
shell: msys2 {0}
|
shell: msys2 {0}
|
||||||
run: make release-assets-windows TARGET_ARCH=${{ matrix.arch }}
|
env:
|
||||||
|
CC: ${{ matrix.cc }}
|
||||||
|
CXX: ${{ matrix.cxx }}
|
||||||
|
run: make release-assets-windows
|
||||||
|
|
||||||
- name: Upload Windows release assets
|
- name: Upload Windows release assets
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|||||||
23
Makefile
23
Makefile
@@ -35,13 +35,15 @@ ifeq ($(TARGET_ARCH),arm64)
|
|||||||
APPIMAGE_ARCH := aarch64
|
APPIMAGE_ARCH := aarch64
|
||||||
DEB_ARCH := arm64
|
DEB_ARCH := arm64
|
||||||
RPM_ARCH := aarch64
|
RPM_ARCH := aarch64
|
||||||
WINDOWS_WINDRES_FORMAT := pe-aarch64
|
WINDOWS_WINDRES_FORMAT_BFD := pe-aarch64
|
||||||
|
WINDOWS_WINDRES_FORMAT_LLVM := aarch64-w64-mingw32
|
||||||
WINDOWS_RESOURCE := rsrc_windows_arm64.syso
|
WINDOWS_RESOURCE := rsrc_windows_arm64.syso
|
||||||
else
|
else
|
||||||
APPIMAGE_ARCH := x86_64
|
APPIMAGE_ARCH := x86_64
|
||||||
DEB_ARCH := amd64
|
DEB_ARCH := amd64
|
||||||
RPM_ARCH := x86_64
|
RPM_ARCH := x86_64
|
||||||
WINDOWS_WINDRES_FORMAT := pe-x86-64
|
WINDOWS_WINDRES_FORMAT_BFD := pe-x86-64
|
||||||
|
WINDOWS_WINDRES_FORMAT_LLVM := x86_64-w64-mingw32
|
||||||
WINDOWS_RESOURCE := rsrc_windows_amd64.syso
|
WINDOWS_RESOURCE := rsrc_windows_amd64.syso
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -116,6 +118,7 @@ desktop-build-mac: version-check _desktop-prepare-frontend _desktop-prepare-embe
|
|||||||
cd backend && CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -ldflags "$(GO_LDFLAGS)" -o ../build/nex-mac-amd64 ./cmd/desktop
|
cd backend && CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -ldflags "$(GO_LDFLAGS)" -o ../build/nex-mac-amd64 ./cmd/desktop
|
||||||
lipo -create build/nex-mac-arm64 build/nex-mac-amd64 -output build/nex-mac-universal
|
lipo -create build/nex-mac-arm64 build/nex-mac-amd64 -output build/nex-mac-universal
|
||||||
lipo -info build/nex-mac-universal | grep -q 'x86_64 arm64'
|
lipo -info build/nex-mac-universal | grep -q 'x86_64 arm64'
|
||||||
|
rm -f build/nex-mac-arm64 build/nex-mac-amd64
|
||||||
@printf 'Packaging macOS app bundle...\n'
|
@printf 'Packaging macOS app bundle...\n'
|
||||||
rm -rf build/Nex.app
|
rm -rf build/Nex.app
|
||||||
mkdir -p build/Nex.app/Contents/MacOS build/Nex.app/Contents/Resources
|
mkdir -p build/Nex.app/Contents/MacOS build/Nex.app/Contents/Resources
|
||||||
@@ -176,13 +179,16 @@ _desktop-prepare-embedfs:
|
|||||||
|
|
||||||
_desktop-prepare-windows-resource: _check-windows-target-arch
|
_desktop-prepare-windows-resource: _check-windows-target-arch
|
||||||
@printf 'Preparing Windows $(TARGET_ARCH) executable icon...\n'
|
@printf 'Preparing Windows $(TARGET_ARCH) executable icon...\n'
|
||||||
@if [ "$(TARGET_ARCH)" = "arm64" ] && [ "$(WINDRES)" = "windres" ] && command -v llvm-windres >/dev/null 2>&1; then \
|
@WINDRES_CMD="$(WINDRES)"; \
|
||||||
|
WINDRES_FMT="$(WINDOWS_WINDRES_FORMAT_BFD)"; \
|
||||||
|
if command -v llvm-windres >/dev/null 2>&1; then \
|
||||||
WINDRES_CMD=llvm-windres; \
|
WINDRES_CMD=llvm-windres; \
|
||||||
else \
|
WINDRES_FMT="$(WINDOWS_WINDRES_FORMAT_LLVM)"; \
|
||||||
WINDRES_CMD="$(WINDRES)"; \
|
elif "$$WINDRES_CMD" --version 2>&1 | grep -qi LLVM; then \
|
||||||
|
WINDRES_FMT="$(WINDOWS_WINDRES_FORMAT_LLVM)"; \
|
||||||
fi; \
|
fi; \
|
||||||
command -v "$$WINDRES_CMD" >/dev/null 2>&1 || { printf 'Missing windres tool: %s\n' "$$WINDRES_CMD"; exit 1; }; \
|
command -v "$$WINDRES_CMD" >/dev/null 2>&1 || { printf 'Missing windres tool: %s\n' "$$WINDRES_CMD"; exit 1; }; \
|
||||||
cd backend/cmd/desktop && "$$WINDRES_CMD" -O coff -F $(WINDOWS_WINDRES_FORMAT) -i icon_windows.rc -o $(WINDOWS_RESOURCE)
|
cd backend/cmd/desktop && "$$WINDRES_CMD" -O coff -F "$$WINDRES_FMT" -i icon_windows.rc -o $(WINDOWS_RESOURCE)
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
# 发布资产
|
# 发布资产
|
||||||
@@ -241,6 +247,7 @@ release-assets-server-macos: version-check
|
|||||||
tar -C build -czf "$(RELEASE_DIR)/$$asset" nex-server-macos-arm64
|
tar -C build -czf "$(RELEASE_DIR)/$$asset" nex-server-macos-arm64
|
||||||
asset=$$(go run ./versionctl asset-name server macos universal tar.gz); \
|
asset=$$(go run ./versionctl asset-name server macos universal tar.gz); \
|
||||||
tar -C build -czf "$(RELEASE_DIR)/$$asset" nex-server-macos-universal
|
tar -C build -czf "$(RELEASE_DIR)/$$asset" nex-server-macos-universal
|
||||||
|
rm -f build/nex-server-macos-amd64 build/nex-server-macos-arm64 build/nex-server-macos-universal
|
||||||
|
|
||||||
release-assets-desktop-linux: version-check release-assets-check desktop-build-linux _package-linux-tar _package-linux-appimage _package-linux-deb _package-linux-rpm
|
release-assets-desktop-linux: version-check release-assets-check desktop-build-linux _package-linux-tar _package-linux-appimage _package-linux-deb _package-linux-rpm
|
||||||
|
|
||||||
@@ -251,6 +258,7 @@ release-assets-desktop-windows: version-check release-assets-check desktop-build
|
|||||||
"$$POWERSHELL" -NoProfile -Command "Compress-Archive -LiteralPath '$(WINDOWS_DESKTOP_BINARY)' -DestinationPath '$(RELEASE_DIR)/$$asset' -Force"
|
"$$POWERSHELL" -NoProfile -Command "Compress-Archive -LiteralPath '$(WINDOWS_DESKTOP_BINARY)' -DestinationPath '$(RELEASE_DIR)/$$asset' -Force"
|
||||||
|
|
||||||
release-assets-desktop-macos: version-check release-assets-check desktop-build-mac _package-macos-zip _package-macos-dmg
|
release-assets-desktop-macos: version-check release-assets-check desktop-build-mac _package-macos-zip _package-macos-dmg
|
||||||
|
rm -rf build/Nex.app build/dmg
|
||||||
|
|
||||||
release-assets-checksums:
|
release-assets-checksums:
|
||||||
@cd "$(RELEASE_DIR)" && \
|
@cd "$(RELEASE_DIR)" && \
|
||||||
@@ -366,7 +374,8 @@ _package-macos-dmg:
|
|||||||
ln -s /Applications "$$dmgdir/Applications"; \
|
ln -s /Applications "$$dmgdir/Applications"; \
|
||||||
asset=$$(go run ./versionctl asset-name desktop macos universal dmg); \
|
asset=$$(go run ./versionctl asset-name desktop macos universal dmg); \
|
||||||
hdiutil create -volname Nex -srcfolder "$$dmgdir" -ov -format UDZO "$(RELEASE_DIR)/$$asset"; \
|
hdiutil create -volname Nex -srcfolder "$$dmgdir" -ov -format UDZO "$(RELEASE_DIR)/$$asset"; \
|
||||||
hdiutil verify "$(RELEASE_DIR)/$$asset" >/dev/null
|
hdiutil verify "$(RELEASE_DIR)/$$asset" >/dev/null && \
|
||||||
|
rm -rf "$$dmgdir"
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
# 共享 helper targets
|
# 共享 helper targets
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
VITE_API_BASE=
|
VITE_API_BASE=
|
||||||
VITE_APP_VERSION=0.1.3
|
VITE_APP_VERSION=0.1.6
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
VITE_API_BASE=
|
VITE_API_BASE=
|
||||||
VITE_APP_VERSION=0.1.3
|
VITE_APP_VERSION=0.1.6
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
VITE_API_BASE=/api
|
VITE_API_BASE=/api
|
||||||
VITE_APP_VERSION=0.1.3
|
VITE_APP_VERSION=0.1.6
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "frontend",
|
"name": "frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.1.3",
|
"version": "0.1.6",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -57,22 +57,35 @@
|
|||||||
- **WHEN** 发布流水线执行 Linux desktop 发布构建
|
- **WHEN** 发布流水线执行 Linux desktop 发布构建
|
||||||
- **THEN** 系统 SHALL 在可访问 Go、Bun、CGO、GTK3、Ayatana AppIndicator 和 Linux 打包工具链的环境中构建
|
- **THEN** 系统 SHALL 在可访问 Go、Bun、CGO、GTK3、Ayatana AppIndicator 和 Linux 打包工具链的环境中构建
|
||||||
- **AND** 系统 SHALL 为 `amd64` 和 `arm64` 分别生成 tar.gz、AppImage、deb 和 rpm desktop 发布资产
|
- **AND** 系统 SHALL 为 `amd64` 和 `arm64` 分别生成 tar.gz、AppImage、deb 和 rpm desktop 发布资产
|
||||||
- **AND** Linux arm64 desktop 发布构建 SHALL 使用原生 arm64 runner 或等价的 arm64 Linux 构建环境
|
- **AND** Linux amd64 desktop 发布构建 SHALL 在 `ubuntu-latest` runner 上执行
|
||||||
|
- **AND** Linux arm64 desktop 发布构建 SHALL 在 `ubuntu-24.04-arm` runner 上执行
|
||||||
|
- **AND** 系统 SHALL NOT 在构建步骤中显式传递 TARGET_ARCH 参数
|
||||||
|
|
||||||
#### Scenario: Windows desktop 发布构建
|
#### Scenario: Windows desktop 发布构建
|
||||||
|
|
||||||
- **WHEN** 发布流水线执行 Windows desktop 发布构建
|
- **WHEN** 发布流水线执行 Windows desktop 发布构建
|
||||||
- **THEN** 系统 SHALL 在包含对应架构 MSYS2/MinGW 或等价 CGO 工具链的环境中构建
|
- **THEN** 系统 SHALL 在包含对应架构 MSYS2/MinGW 或等价 CGO 工具链的环境中构建
|
||||||
|
- **AND** Windows amd64 desktop 发布构建 SHALL 在 `windows-latest` runner 上的 MSYS2 MINGW64 环境中执行
|
||||||
|
- **AND** Windows arm64 desktop 发布构建 SHALL 在 `windows-11-arm` runner 上的 MSYS2 CLANGARM64 环境中执行
|
||||||
- **AND** 系统 SHALL 生成 `nex-desktop_<version>_windows_amd64.zip`
|
- **AND** 系统 SHALL 生成 `nex-desktop_<version>_windows_amd64.zip`
|
||||||
- **AND** 系统 SHALL 生成 `nex-desktop_<version>_windows_arm64.zip`
|
- **AND** 系统 SHALL 生成 `nex-desktop_<version>_windows_arm64.zip`
|
||||||
|
- **AND** 系统 SHALL NOT 在构建步骤中显式传递 TARGET_ARCH 参数
|
||||||
|
|
||||||
#### Scenario: macOS desktop 发布构建
|
#### Scenario: macOS desktop 发布构建
|
||||||
|
|
||||||
- **WHEN** 发布流水线执行 macOS desktop 发布构建
|
- **WHEN** 发布流水线执行 macOS desktop 发布构建
|
||||||
- **THEN** 系统 SHALL 在可访问 Go、Bun、Xcode 命令行工具、`lipo`、`hdiutil` 和 zip 打包工具的 macOS 环境中构建
|
- **THEN** 系统 SHALL 在可访问 Go、Bun、Xcode 命令行工具、`lipo`、`hdiutil` 和 zip 打包工具的 macOS 环境中构建
|
||||||
|
- **AND** 系统 SHALL 在 ARM64 macOS runner 上编译 amd64 和 arm64 双架构二进制并使用 `lipo` 合并为 universal binary
|
||||||
- **AND** 系统 SHALL 生成 `nex-desktop_<version>_macos_universal.zip`
|
- **AND** 系统 SHALL 生成 `nex-desktop_<version>_macos_universal.zip`
|
||||||
- **AND** 系统 SHALL 生成 `nex-desktop_<version>_macos_universal.dmg`
|
- **AND** 系统 SHALL 生成 `nex-desktop_<version>_macos_universal.dmg`
|
||||||
|
|
||||||
|
#### Scenario: 原生架构构建
|
||||||
|
|
||||||
|
- **WHEN** 发布流水线执行 Linux 或 Windows 的 server/desktop 构建步骤
|
||||||
|
- **THEN** 系统 SHALL NOT 显式传递 TARGET_ARCH 参数
|
||||||
|
- **AND** Makefile SHALL 通过 `go env GOARCH` 自动检测目标架构
|
||||||
|
- **AND** 原生 runner 的实际架构 SHALL 与 `go env GOARCH` 返回值一致
|
||||||
|
|
||||||
### Requirement: 三平台发布构建预检
|
### Requirement: 三平台发布构建预检
|
||||||
|
|
||||||
系统 SHALL 在正式执行各平台 release 构建前验证对应 job 的关键工具链可用性,并在环境不完整时快速失败且输出明确诊断。
|
系统 SHALL 在正式执行各平台 release 构建前验证对应 job 的关键工具链可用性,并在环境不完整时快速失败且输出明确诊断。
|
||||||
@@ -107,6 +120,22 @@
|
|||||||
- **THEN** 发布流水线 SHALL 在正式构建前失败
|
- **THEN** 发布流水线 SHALL 在正式构建前失败
|
||||||
- **AND** 系统 SHALL 在日志中标识缺失的工具链名称
|
- **AND** 系统 SHALL 在日志中标识缺失的工具链名称
|
||||||
|
|
||||||
|
### Requirement: Windows arm64 CGO 编译器指定
|
||||||
|
|
||||||
|
系统 SHALL 在 Windows arm64 发布构建中显式指定 `CC=clang` 和 `CXX=clang++` 环境变量,确保 Go cgo 在 MSYS2 CLANGARM64 环境下使用正确的 C 编译器进行 `windows/arm64` 交叉编译。
|
||||||
|
|
||||||
|
#### Scenario: Windows arm64 构建使用 clang
|
||||||
|
|
||||||
|
- **WHEN** 发布流水线在 `windows-11-arm` runner 上执行 Windows arm64 构建步骤
|
||||||
|
- **THEN** 构建步骤 SHALL 将 `CC=clang` 和 `CXX=clang++` 注入 go build 环境
|
||||||
|
- **AND** Go cgo SHALL 使用 `clang` 编译 `runtime/cgo` 等 CGO 组件
|
||||||
|
|
||||||
|
#### Scenario: Windows amd64 构建保持 gcc
|
||||||
|
|
||||||
|
- **WHEN** 发布流水线在 `windows-latest` runner 上执行 Windows amd64 构建步骤
|
||||||
|
- **THEN** 构建步骤 MAY 显式指定 `CC=gcc` 和 `CXX=g++` 或依赖 Go 默认编译器探测
|
||||||
|
- **AND** 显式指定的 `gcc` SHALL 等价于 MSYS2 MINGW64 默认 C 编译器(`x86_64-w64-mingw32-gcc`)
|
||||||
|
|
||||||
### Requirement: 发布流水线 LFS 资产拉取
|
### Requirement: 发布流水线 LFS 资产拉取
|
||||||
|
|
||||||
发布流水线 SHALL 在所有会 checkout 仓库并参与版本校验、web 构建、server 构建或 desktop 构建的 job 中拉取 Git LFS 真实文件,确保发布构建读取到真实二进制资产而非 LFS pointer 文本。
|
发布流水线 SHALL 在所有会 checkout 仓库并参与版本校验、web 构建、server 构建或 desktop 构建的 job 中拉取 Git LFS 真实文件,确保发布构建读取到真实二进制资产而非 LFS pointer 文本。
|
||||||
|
|||||||
Reference in New Issue
Block a user