Repository navigation
fix(ci): lint-test 与 app-rust 改用 windows-latest(项目含 Windows 专用模块) #47
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release Tauri App | |
| # 由 semantic-release 创建的 v* tag 触发:构建 Tauri 安装包并附加到对应 Release | |
| # 适配说明(2026-08-21):原 Electron 发布链适配为 Tauri—— | |
| # electron-builder → cargo tauri build(nsis);更新源 latest.yml → Tauri 安装包直链 | |
| # (updater 端点未启用,TODO:启用 tauri.conf updater 后补 latest.json 同步) | |
| on: | |
| push: | |
| tags: ['v*'] | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: release-tauri-${{ github.ref_name }} | |
| cancel-in-progress: false | |
| jobs: | |
| lint-test: | |
| # 项目含 Windows 专用模块(audio_route_probe/device_probe/gdi_capture 等未做 Linux cfg 隔离), | |
| # 测试必须在 Windows runner 执行;Linux 编译会因 E0433 失败 | |
| runs-on: windows-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: x86_64-pc-windows-msvc | |
| - name: Cache cargo registry | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: app/src-tauri | |
| # models/ 不入库(AGENTS.md 铁律),build.rs 的 bundle.resources glob 需要空目录占位 | |
| - name: Prepare models placeholder | |
| shell: bash | |
| run: mkdir -p app/src-tauri/models | |
| - name: Test | |
| # 覆盖 .cargo/config.toml 的本地 Windows 预编译库路径:CI runner 无 D:/ 本机目录, | |
| # 清空后 sherpa-onnx-sys/ort-sys 回退在线下载(CI 网络可达) | |
| env: | |
| SHERPA_ONNX_ARCHIVE_DIR: "" | |
| ORT_LIB_LOCATION: "" | |
| ORT_SKIP_DOWNLOAD: "0" | |
| ORT_PREFER_DYNAMIC_LINK: "1" | |
| run: cd app/src-tauri && cargo test | |
| build: | |
| needs: lint-test | |
| runs-on: windows-latest | |
| # Tauri 打包 + 上传 + 服务器同步:上限 90 分钟 | |
| timeout-minutes: 90 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: 'npm' | |
| cache-dependency-path: app/package-lock.json | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: x86_64-pc-windows-msvc | |
| - name: Cache cargo registry | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: app/src-tauri | |
| # 模型资源占位:models/ 不入库(AGENTS.md 铁律),CI 构建时创建空目录 | |
| # 避免 tauri bundle 资源 glob 报错;运行时缺失模型有下载/降级路径兜底 | |
| - name: Prepare models placeholder | |
| shell: bash | |
| run: mkdir -p app/src-tauri/models | |
| - name: Install frontend deps | |
| run: cd app && npm ci | |
| - name: Build Tauri app (NSIS) | |
| shell: bash | |
| # 覆盖 .cargo/config.toml 的本地 Windows 预编译库路径([target.x86_64-pc-windows-msvc.env]): | |
| # CI runner 无 D:/ 本机目录,清空后 sherpa-onnx-sys/ort-sys 回退在线下载(CI 网络可达) | |
| env: | |
| SHERPA_ONNX_ARCHIVE_DIR: "" | |
| ORT_LIB_LOCATION: "" | |
| ORT_SKIP_DOWNLOAD: "0" | |
| ORT_PREFER_DYNAMIC_LINK: "1" | |
| run: cd app && npx tauri build --bundles nsis | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-windows-latest | |
| path: | | |
| app/src-tauri/target/release/bundle/nsis/*.exe | |
| release: | |
| needs: build | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| env: | |
| HAS_ALIYUN_AK: ${{ secrets.ALIYUN_ACCESS_KEY_ID != '' }} | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: release-* | |
| - uses: softprops/action-gh-release@v2 | |
| with: | |
| files: release-*/* | |
| # --------------------------------------------------------------- | |
| # 同步安装包至自建服务器(国内主下载源;服务器连接继承自原项目) | |
| # --------------------------------------------------------------- | |
| - name: Generate latest.json for download page | |
| id: meta | |
| run: | | |
| FILE=$(ls release-windows-latest/*.exe | head -1 | xargs basename) | |
| SIZE=$(stat -c%s "release-windows-latest/$FILE") | |
| SHA256=$(sha256sum "release-windows-latest/$FILE" | awk '{print $1}') | |
| DATE=$(date -u +%F) | |
| printf '{"version":"%s","fileName":"%s","size":%s,"sha256":"%s","releaseDate":"%s"}\n' \ | |
| "${{ github.ref_name }}" "$FILE" "$SIZE" "$SHA256" "$DATE" > release-windows-latest/latest.json | |
| cat release-windows-latest/latest.json | |
| echo "file=$FILE" >> "$GITHUB_OUTPUT" | |
| - name: Ensure downloads directory on server | |
| uses: appleboy/ssh-action@v1 | |
| with: | |
| host: ${{ secrets.SERVER_HOST }} | |
| username: ${{ secrets.SERVER_USER }} | |
| key: ${{ secrets.SSH_PRIVATE_KEY }} | |
| script: mkdir -p /opt/Entropydecrease/downloads | |
| - name: Upload installer to server | |
| uses: appleboy/scp-action@v0.1.7 | |
| with: | |
| host: ${{ secrets.SERVER_HOST }} | |
| username: ${{ secrets.SERVER_USER }} | |
| key: ${{ secrets.SSH_PRIVATE_KEY }} | |
| source: release-windows-latest/*.exe | |
| target: /opt/Entropydecrease/downloads | |
| strip_components: 1 | |
| - name: Publish metadata (last, avoids 404 window) | |
| uses: appleboy/scp-action@v0.1.7 | |
| with: | |
| host: ${{ secrets.SERVER_HOST }} | |
| username: ${{ secrets.SERVER_USER }} | |
| key: ${{ secrets.SSH_PRIVATE_KEY }} | |
| source: release-windows-latest/latest.json | |
| target: /opt/Entropydecrease/downloads | |
| strip_components: 1 | |
| # --------------------------------------------------------------- | |
| # 同步至 OSS(CDN 源站;可选——未配置阿里云凭据时跳过) | |
| # --------------------------------------------------------------- | |
| - name: Upload to OSS (CDN origin) | |
| if: env.HAS_ALIYUN_AK == 'true' | |
| env: | |
| AK_ID: ${{ secrets.ALIYUN_ACCESS_KEY_ID }} | |
| AK_SECRET: ${{ secrets.ALIYUN_ACCESS_KEY_SECRET }} | |
| OSS_ENDPOINT_IN: ${{ secrets.OSS_ENDPOINT }} | |
| FILE_NAME: ${{ steps.meta.outputs.file }} | |
| run: | | |
| set -eo pipefail | |
| OSS_ENDPOINT="${OSS_ENDPOINT_IN:-oss-cn-hangzhou.aliyuncs.com}" | |
| curl -sL https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz -o /tmp/aliyun.tgz | |
| tar -xzf /tmp/aliyun.tgz -C /tmp | |
| /tmp/aliyun configure set --profile ossci --mode AK --region cn-hangzhou \ | |
| --access-key-id "$AK_ID" --access-key-secret "$AK_SECRET" | |
| /tmp/aliyun oss cp "release-windows-latest/$FILE_NAME" \ | |
| "oss://${{ secrets.OSS_BUCKET }}/downloads/$FILE_NAME" \ | |
| --force -e "$OSS_ENDPOINT" --profile ossci | |
| /tmp/aliyun oss cp release-windows-latest/latest.json \ | |
| "oss://${{ secrets.OSS_BUCKET }}/downloads/latest.json" \ | |
| --force -e "$OSS_ENDPOINT" --profile ossci | |
| echo "OSS sync done" | |
| # --------------------------------------------------------------- | |
| # 保留策略:仅保留最近 3 个版本的安装包,防止磁盘增长 | |
| # --------------------------------------------------------------- | |
| - name: Prune old versions (keep last 3) | |
| uses: appleboy/ssh-action@v1 | |
| with: | |
| host: ${{ secrets.SERVER_HOST }} | |
| username: ${{ secrets.SERVER_USER }} | |
| key: ${{ secrets.SSH_PRIVATE_KEY }} | |
| script: | | |
| cd /opt/Entropydecrease/downloads | |
| ls -t -- *.exe 2>/dev/null | tail -n +4 | while read -r f; do | |
| rm -f -- "$f" | |
| done | |
| # --------------------------------------------------------------- | |
| # 发布结果校验:防止"空 Release"(历史事故 v0.27.0/v0.28.7) | |
| # --------------------------------------------------------------- | |
| - name: Verify release assets | |
| if: startsWith(github.ref, 'refs/tags/') | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| GH_REPO: ${{ github.repository }} | |
| TAG: ${{ github.ref_name }} | |
| run: | | |
| set -eo pipefail | |
| names=$(gh release view "$TAG" --json assets --jq '.assets[].name') | |
| echo "Assets of $TAG:" | |
| echo "$names" | |
| if ! echo "$names" | grep -qE '\.exe$'; then | |
| echo "::error::Release $TAG 缺少 .exe 安装包资产" | |
| exit 1 | |
| fi | |
| echo "发布资产完整校验通过" | |
| - name: Check installer size | |
| run: | | |
| set -eo pipefail | |
| for exe in release-windows-latest/*.exe; do | |
| [ -f "$exe" ] || continue | |
| SIZE=$(stat -c%s "$exe") | |
| SIZE_MB=$(awk "BEGIN {printf \"%.2f\", $SIZE / 1048576}") | |
| echo "📦 $exe: ${SIZE_MB} MB" | |
| if [ "$SIZE" -gt 419430400 ]; then | |
| echo "::warning::${exe} 超过 400MB,请检查是否误打包大文件(模型不入库)" | |
| fi | |
| done |