diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 75cb6f9..9b72015 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -25,6 +25,24 @@ jobs: name: linux-web path: dist/ + build-macos: + runs-on: mac + env: + PUB_HOSTED_URL: https://pub.flutter-io.cn + FLUTTER_STORAGE_BASE_URL: https://storage.flutter-io.cn + + steps: + - uses: actions/checkout@v4 + + - name: Compile (Flutter macOS) + run: sh scripts/ci/compile-macos.sh "${{ gitea.ref_name }}" + + - name: Upload macos artifacts + uses: actions/upload-artifact@v3 + with: + name: macos + path: dist/ + build-windows: runs-on: windows env: @@ -46,7 +64,7 @@ jobs: path: dist/ release-deploy: - needs: [build-linux-web, build-windows] + needs: [build-linux-web, build-macos, build-windows] runs-on: mac env: GOPROXY: https://goproxy.cn,direct @@ -62,6 +80,12 @@ jobs: name: linux-web path: dist/ + - name: Download macos artifacts + uses: actions/download-artifact@v3 + with: + name: macos + path: dist/ + - name: Download windows artifacts uses: actions/download-artifact@v3 with: diff --git a/.gitignore b/.gitignore index 2a8dc06..997d73e 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,9 @@ client/devtools_options.yaml # Flutter 构建产物 client/build/ +# CI 构建产物 +dist/ + # 营销站构建产物 web/dist/ web/node_modules/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e88daa..5ad97c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.0.4] - 2026-05-30 + +### 新功能 +- 支持 macOS 桌面客户端下载,下载页 macOS 卡片已激活,下载 zip 解压即用 + ## [1.0.3] - 2026-05-28 ### 新功能 diff --git a/scripts/ci/compile-macos.sh b/scripts/ci/compile-macos.sh new file mode 100755 index 0000000..b7cc1bf --- /dev/null +++ b/scripts/ci/compile-macos.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# compile-macos.sh — build Flutter macOS desktop, package into dist/ +set -euo pipefail + +export GOPROXY="${GOPROXY:-https://goproxy.cn,direct}" +export PUB_HOSTED_URL="${PUB_HOSTED_URL:-https://pub.flutter-io.cn}" +export FLUTTER_STORAGE_BASE_URL="${FLUTTER_STORAGE_BASE_URL:-https://storage.flutter-io.cn}" + +TAG="$1" +VER="${TAG#v}" + +echo "==> compile-macos: version=${VER}" + +# Sync Flutter pubspec version (BSD sed on macOS) +sed -i '' "s/^version:.*/version: ${VER}+1/" client/pubspec.yaml + +# Build Flutter macOS +cd client +flutter build macos --release \ + "--dart-define=BASE_URL=https://jiu.51yanmei.com" \ + "--dart-define=PUBLIC_URL=https://jiu.51yanmei.com" \ + "--dart-define=APP_VERSION=${TAG}" +cd .. + +# Package .app bundle into zip +mkdir -p dist +python3 - <<'PYEOF' +import zipfile, os + +src = os.path.join('client', 'build', 'macos', 'Build', 'Products', 'Release', 'jiu.app') +dst = os.path.join('dist', 'jiu-macos-x64.zip') + +with zipfile.ZipFile(dst, 'w', zipfile.ZIP_DEFLATED) as zf: + for root, dirs, files in os.walk(src): + for fname in files: + fp = os.path.join(root, fname) + zf.write(fp, os.path.join('jiu.app', os.path.relpath(fp, src))) + +size = os.path.getsize(dst) +print(f'Packaged {dst} ({size // 1024 // 1024} MB)') +PYEOF + +echo "==> compile-macos: done — dist/ contents:" +ls -lh dist/ diff --git a/scripts/ci/release.sh b/scripts/ci/release.sh index 85396a3..6a593cb 100755 --- a/scripts/ci/release.sh +++ b/scripts/ci/release.sh @@ -36,7 +36,7 @@ PYEOF echo "==> release: release_notes=${RELEASE_NOTES}" -# Update backend/config/version.yaml (version, build_number, release_notes, windows URL) +# Update backend/config/version.yaml (version, build_number, release_notes, macos/windows URL) python3 - "${VER}" "${RELEASE_NOTES}" "${TAG}" "${FORGEJO_URL}" "${GITEA_REPOSITORY}" <<'PYEOF' import sys ver = sys.argv[1] @@ -44,7 +44,9 @@ notes = sys.argv[2] tag = sys.argv[3] furl = sys.argv[4].rstrip('/') repo = sys.argv[5] -win_url = f"{furl}/{repo}/releases/download/{tag}/jiu-windows-x64.zip" +base = f"{furl}/{repo}/releases/download/{tag}" +mac_url = f"{base}/jiu-macos-x64.zip" +win_url = f"{base}/jiu-windows-x64.zip" lines = [] with open('backend/config/version.yaml') as f: @@ -59,13 +61,15 @@ with open('backend/config/version.yaml') as f: lines.append('build_number: ' + str(build) + '\n') elif line.startswith('release_notes:'): lines.append('release_notes: "' + notes.replace('\\', '\\\\').replace('"', '\\"') + '"\n') + elif line.startswith(' macos:'): + lines.append(' macos: "' + mac_url + '"\n') elif line.startswith(' windows:'): lines.append(' windows: "' + win_url + '"\n') else: lines.append(line) with open('backend/config/version.yaml', 'w') as f: f.writelines(lines) -print('version.yaml updated to', ver, '| windows:', win_url) +print('version.yaml updated to', ver, '| macos:', mac_url, '| windows:', win_url) PYEOF # Package configs.tar.gz (includes updated version.yaml) @@ -123,6 +127,7 @@ upload_asset dist/jiu-server upload_asset dist/web.tar.gz upload_asset dist/marketing.tar.gz upload_asset dist/configs.tar.gz +upload_asset dist/jiu-macos-x64.zip upload_asset dist/jiu-windows-x64.zip echo "==> release: done — Release ${TAG} created" diff --git a/web/download.njk b/web/download.njk index e699203..06905d4 100644 --- a/web/download.njk +++ b/web/download.njk @@ -334,14 +334,14 @@ pageStyle: | -
+

macOS

-

支持 Apple Silicon 与 Intel 芯片,通用版本。

- 敬请期待 - - 即将推出 - +

支持 Apple Silicon 与 Intel,解压即用,首次运行右键→打开。

+ ✓ 已支持 + + 下载 macOS 版 +
@@ -432,7 +432,7 @@ pageStyle: | ios: { name: 'iOS', desc: 'iOS 客户端正在开发中,敬请期待。', icon: 'smartphone', btnText: '敬请期待', available: false }, android: { name: 'Android', desc: 'Android 客户端正在开发中,敬请期待。', icon: 'tablet-smartphone', btnText: '敬请期待', available: false }, windows: { name: 'Windows 桌面', desc: '原生桌面客户端,支持 Win 10/11(64 位),离线模式与本地打印。', icon: 'monitor', btnText: '下载 Windows 版', btnHref: '#', available: true }, - macos: { name: 'macOS 桌面', desc: 'macOS 客户端正在开发中,敬请期待。', icon: 'laptop', btnText: '敬请期待', available: false } + macos: { name: 'macOS 桌面', desc: '支持 Apple Silicon 与 Intel,解压即用,首次运行右键→打开。', icon: 'laptop', btnText: '下载 macOS 版', btnHref: '#', available: true } }; function detectPlatform() { @@ -501,11 +501,16 @@ pageStyle: | .then(function(r) { return r.json(); }) .then(function(data) { if (data && data.version) updateVersionBadges(data.version); + if (data && data.download_urls && data.download_urls.macos) { + platforms.macos.btnHref = data.download_urls.macos; + var macBtn = document.getElementById('macos-dl-btn'); + if (macBtn) macBtn.href = data.download_urls.macos; + if (detected === 'macos') updateDetectCard(detected); + } if (data && data.download_urls && data.download_urls.windows) { platforms.windows.btnHref = data.download_urls.windows; var btn = document.getElementById('windows-dl-btn'); if (btn) btn.href = data.download_urls.windows; - // 若用户在 Windows 上,同步更新自动识别卡片 if (detected === 'windows') updateDetectCard(detected); } })