Release Tauri (cross-platform) #31
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 (cross-platform) | |
| # 触发条件: | |
| # - 推 v*.*.*-tauri 形式的 tag(与老 Swift 版的 vX.Y.Z 区分开,不冲突) | |
| # - 手动 dispatch(用于测试构建,不发版) | |
| # | |
| # 输出: | |
| # macOS arm64/x64 .dmg + Windows x64 .msi/.exe + Linux x64 .deb/.rpm/.AppImage,自动作为 GitHub Release 资产上传。 | |
| # | |
| # macOS 分发: | |
| # - 配好 APPLE_CERTIFICATE / APPLE_CERTIFICATE_PASSWORD / APPLE_ID / | |
| # APPLE_PASSWORD / APPLE_TEAM_ID 后,Tauri 会做 Developer ID 签名和公证。 | |
| # 用户从浏览器下载后不需要手工 xattr。 | |
| # - 未配置 Apple secrets 时自动回退 ad-hoc 签名,GitHub Actions 会打印 warning。 | |
| # - Windows 没签名(无证书),Win 11 SmartScreen 会警告 "未识别的发布者",用户点"仍要运行"。 | |
| # - 任意一个 platform 失败不影响另一个继续构建(fail-fast: false)。 | |
| on: | |
| push: | |
| tags: | |
| - 'v*-tauri' | |
| workflow_dispatch: | |
| jobs: | |
| build: | |
| permissions: | |
| contents: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - platform: macos-latest | |
| rust-target: aarch64-apple-darwin | |
| updater-target: darwin | |
| updater-arch: aarch64 | |
| - platform: macos-13 | |
| rust-target: x86_64-apple-darwin | |
| updater-target: darwin | |
| updater-arch: x86_64 | |
| - platform: windows-latest | |
| rust-target: x86_64-pc-windows-msvc | |
| updater-target: windows | |
| updater-arch: x86_64 | |
| - platform: ubuntu-22.04 | |
| rust-target: x86_64-unknown-linux-gnu | |
| updater-target: linux | |
| updater-arch: x86_64 | |
| runs-on: ${{ matrix.platform }} | |
| env: | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| # vendor/qwen-asr 是 macOS 上 build.rs 必须的 git submodule(cc-rs 编译 | |
| # antirez/qwen-asr 的 C 源),不拉就会在 mac 端 cargo build 阶段挂掉。 | |
| submodules: recursive | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: npm | |
| cache-dependency-path: 'openless-all/app/package-lock.json' | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.rust-target }} | |
| - name: Cache Cargo | |
| uses: swatinem/rust-cache@v2 | |
| with: | |
| workspaces: 'openless-all/app/src-tauri -> target' | |
| - name: Install Linux bundle deps | |
| if: matrix.platform == 'ubuntu-22.04' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| build-essential \ | |
| curl \ | |
| file \ | |
| libasound2-dev \ | |
| libayatana-appindicator3-dev \ | |
| libfuse2 \ | |
| librsvg2-dev \ | |
| libssl-dev \ | |
| libwebkit2gtk-4.1-dev \ | |
| libxdo-dev \ | |
| patchelf \ | |
| rpm \ | |
| wget | |
| - name: Install npm deps | |
| working-directory: 'openless-all/app' | |
| run: npm ci | |
| - name: Check updater signing availability | |
| if: startsWith(github.ref, 'refs/tags/v') && endsWith(github.ref, '-tauri') | |
| shell: bash | |
| env: | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| run: | | |
| if [ -z "${TAURI_SIGNING_PRIVATE_KEY:-}" ]; then | |
| echo "::error::TAURI_SIGNING_PRIVATE_KEY is required for signed auto-update artifacts." | |
| exit 1 | |
| fi | |
| - name: Check Apple signing availability | |
| if: startsWith(matrix.platform, 'macos') && startsWith(github.ref, 'refs/tags/v') && endsWith(github.ref, '-tauri') | |
| shell: bash | |
| env: | |
| APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} | |
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| APPLE_ID: ${{ secrets.APPLE_ID }} | |
| APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} | |
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| run: | | |
| missing=() | |
| for name in APPLE_CERTIFICATE APPLE_CERTIFICATE_PASSWORD APPLE_ID APPLE_PASSWORD APPLE_TEAM_ID; do | |
| if [ -z "${!name:-}" ]; then | |
| missing+=("$name") | |
| fi | |
| done | |
| if [ "${#missing[@]}" -gt 0 ]; then | |
| echo "::warning::macOS release will use ad-hoc signing because Apple signing/notarization secrets are missing: ${missing[*]}" | |
| fi | |
| - name: Import Apple Developer ID certificate | |
| if: startsWith(matrix.platform, 'macos') | |
| shell: bash | |
| env: | |
| APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} | |
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} | |
| run: | | |
| if [ -z "${APPLE_CERTIFICATE:-}" ] || [ -z "${APPLE_CERTIFICATE_PASSWORD:-}" ]; then | |
| echo "No Apple certificate secrets configured; macOS build will use ad-hoc signing." | |
| exit 0 | |
| fi | |
| KEYCHAIN_PASSWORD="${KEYCHAIN_PASSWORD:-$(openssl rand -base64 32)}" | |
| CERT_PATH="$RUNNER_TEMP/openless-certificate.p12" | |
| KEYCHAIN_PATH="$RUNNER_TEMP/openless-build.keychain-db" | |
| echo "$APPLE_CERTIFICATE" | base64 --decode > "$CERT_PATH" | |
| security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security default-keychain -s "$KEYCHAIN_PATH" | |
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security set-keychain-settings -t 3600 -u "$KEYCHAIN_PATH" | |
| security import "$CERT_PATH" -k "$KEYCHAIN_PATH" -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| DEVELOPER_ID_INFO="$(security find-identity -v -p codesigning "$KEYCHAIN_PATH" | grep 'Developer ID Application' | head -n 1)" | |
| if [ -n "$DEVELOPER_ID_INFO" ]; then | |
| CERT_INFO="$DEVELOPER_ID_INFO" | |
| else | |
| CERT_INFO="$(security find-identity -v -p codesigning "$KEYCHAIN_PATH" | grep -E 'Apple Distribution|Apple Development' | head -n 1)" | |
| fi | |
| if [ -z "$CERT_INFO" ]; then | |
| echo "Apple certificate imported, but no usable code-signing identity was found." | |
| security find-identity -v -p codesigning "$KEYCHAIN_PATH" | |
| exit 1 | |
| fi | |
| CERT_ID="$(echo "$CERT_INFO" | awk -F'"' '{print $2}')" | |
| echo "APPLE_SIGNING_IDENTITY=$CERT_ID" >> "$GITHUB_ENV" | |
| echo "Imported Apple signing identity: $CERT_ID" | |
| - name: Configure Apple notarization | |
| if: startsWith(matrix.platform, 'macos') | |
| shell: bash | |
| env: | |
| APPLE_ID: ${{ secrets.APPLE_ID }} | |
| APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} | |
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| APPLE_PROVIDER_SHORT_NAME: ${{ secrets.APPLE_PROVIDER_SHORT_NAME }} | |
| run: | | |
| for name in APPLE_ID APPLE_PASSWORD APPLE_TEAM_ID APPLE_PROVIDER_SHORT_NAME; do | |
| value="${!name:-}" | |
| if [ -n "$value" ]; then | |
| echo "$name=$value" >> "$GITHUB_ENV" | |
| fi | |
| done | |
| # ── macOS:用我们自己的 build-mac.sh,统一处理签名、公证和 artifact 清理 ── | |
| - name: Build (macOS) | |
| if: startsWith(matrix.platform, 'macos') | |
| working-directory: 'openless-all/app' | |
| env: | |
| INSTALL: '0' # CI 不要装到 /Applications,也不要 reset TCC | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| run: bash scripts/build-mac.sh | |
| # ── Windows:先 build OpenLessIme.dll(x64+x86),再跑 tauri bundle。 | |
| # openless-ime.wxs 用 $(env.OPENLESS_IME_DLL_X64) / _X86 拿绝对路径, | |
| # 跨 candle/light cwd 都能 resolve(Tauri wix bundler cwd 不固定)。 | |
| - name: Build Windows IME native DLLs | |
| if: matrix.platform == 'windows-latest' | |
| shell: pwsh | |
| working-directory: 'openless-all/app' | |
| run: | | |
| $appRoot = (Resolve-Path .).Path | |
| foreach ($t in @( | |
| @{ Platform = 'x64'; Folder = 'x64'; EnvName = 'OPENLESS_IME_DLL_X64' }, | |
| @{ Platform = 'Win32'; Folder = 'x86'; EnvName = 'OPENLESS_IME_DLL_X86' } | |
| )) { | |
| $out = Join-Path $appRoot "src-tauri\target\windows-ime-msvc\$($t.Folder)\Release" | |
| $obj = Join-Path $appRoot "src-tauri\target\windows-ime-msvc\obj\$($t.Folder)\Release" | |
| ./scripts/windows-ime-build.ps1 -Configuration Release -Platform $t.Platform -OutputDirectory $out -IntermediateDirectory $obj | |
| if ($LASTEXITCODE -ne 0) { | |
| throw "OpenLessIme $($t.Platform) build failed with exit $LASTEXITCODE" | |
| } | |
| $dll = (Resolve-Path (Join-Path $out 'OpenLessIme.dll')).Path | |
| if (-not (Test-Path $dll)) { | |
| throw "OpenLessIme.dll not produced at $dll" | |
| } | |
| "$($t.EnvName)=$dll" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 | |
| Write-Host "[ok] built $dll (exported $($t.EnvName))" | |
| # bundle.resources 引用的是 src-tauri/openless-ime-payload/{x64,x86}/OpenLessIme.dll | |
| # (仓库里 commit 的是 0 字节占位让 mac 本地 build 也能 resolve)。 | |
| # 这里用真 dll 覆盖占位,让 NSIS / MSI 都装上真文件;NSIS hook 的 regsvr32 | |
| # 同时会把 64 / 32 位 COM 注册到 HKLM\Software\Classes\CLSID 的 | |
| # KEY_WOW64_64KEY / KEY_WOW64_32KEY 两侧(windows_ime_profile.rs 都会查)。 | |
| $payloadDir = Join-Path $appRoot "src-tauri\openless-ime-payload\$($t.Folder)" | |
| New-Item -ItemType Directory -Force -Path $payloadDir | Out-Null | |
| Copy-Item -Force -Path $dll -Destination (Join-Path $payloadDir 'OpenLessIme.dll') | |
| Write-Host "[ok] copied real $($t.Folder) dll into bundle.resources payload path" | |
| } | |
| # ── Windows tauri build:保持 bash shell,因为 PowerShell 调外部命令 | |
| # 会把 '{"bundle":...}' 的内部双引号吃掉、让 tauri 收到无效 JSON。 | |
| # 用 set +e + GITHUB_ENV 把 exit code 传到下一步给 Repair 判断。 | |
| - name: Build (Windows) | |
| if: matrix.platform == 'windows-latest' | |
| shell: bash | |
| working-directory: 'openless-all/app' | |
| env: | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| run: | | |
| set +e | |
| # 拆两轮跑:Tauri 的签名 / updater artifact 阶段是 post-bundle 钩子, | |
| # 任意 bundler 失败会让 *所有* bundle 的 .sig 跳过。MSI 必踩 ICE80, | |
| # 所以单一 `tauri build` 永远拿不到 NSIS 的 .exe.sig。 | |
| # Pass 1:NSIS 独立跑——必须成功,产出 *_x64-setup.exe(.sig) 给 updater。 | |
| # Pass 2:MSI 独立跑——允许失败,Repair 步骤兜底 light.exe 重链。 | |
| if [ -n "${TAURI_SIGNING_PRIVATE_KEY:-}" ]; then | |
| npm run tauri -- build --bundles nsis --config '{"bundle":{"createUpdaterArtifacts":true}}' | |
| nsis_exit=$? | |
| npm run tauri -- build --bundles msi --config '{"bundle":{"createUpdaterArtifacts":true}}' | |
| msi_exit=$? | |
| else | |
| npm run tauri -- build --bundles nsis | |
| nsis_exit=$? | |
| npm run tauri -- build --bundles msi | |
| msi_exit=$? | |
| fi | |
| echo "TAURI_BUILD_EXIT=$msi_exit" >> "$GITHUB_ENV" | |
| # NSIS 是 updater 的硬依赖,挂了就直接 fail step。 | |
| if [ "$nsis_exit" -ne 0 ]; then | |
| echo "::error::NSIS bundle failed (exit $nsis_exit) — updater artifact unavailable." | |
| exit 1 | |
| fi | |
| # MSI 失败不挡——下一步 Repair 用 light.exe 重链(带 -sice:ICE80)。 | |
| exit 0 | |
| # ── 如果 tauri 在 wix link 阶段失败(candle 出了 wixobj,但 light 因 cwd | |
| # 解析 wxs Source 找不到 IME DLL),从 appRoot 手动跑 light 兜底重链。 | |
| # 这是本地 windows-package-msvc.ps1::Repair-TauriMsiBundle 的同款手术。 | |
| - name: Repair Windows MSI if Tauri failed at WiX link | |
| if: matrix.platform == 'windows-latest' | |
| shell: pwsh | |
| working-directory: 'openless-all/app' | |
| run: | | |
| $exitCode = $env:TAURI_BUILD_EXIT | |
| $appRoot = (Resolve-Path .).Path | |
| $msi = Get-ChildItem "src-tauri\target\release\bundle\msi\*.msi" -ErrorAction SilentlyContinue | Select-Object -First 1 | |
| if ($msi) { | |
| Write-Host "[ok] MSI already produced by tauri: $($msi.FullName); no repair needed." | |
| return | |
| } | |
| if (-not $exitCode -or $exitCode -eq '0') { | |
| throw "Tauri exited 0 but no MSI found at src-tauri\target\release\bundle\msi\" | |
| } | |
| Write-Warning "Tauri MSI failed (exit $exitCode). Attempting manual light.exe relink from app root." | |
| $wixRoot = Join-Path $appRoot 'src-tauri\target\release\wix\x64' | |
| $mainObj = Join-Path $wixRoot 'main.wixobj' | |
| $imeObj = Join-Path $wixRoot 'openless-ime.wixobj' | |
| $locale = Join-Path $wixRoot 'locale.wxl' | |
| foreach ($p in @($mainObj, $imeObj, $locale)) { | |
| if (-not (Test-Path $p)) { | |
| throw "Required WiX object missing: $p — tauri build aborted before candle ran. Check the Build (Windows) step log." | |
| } | |
| } | |
| $light = (Get-ChildItem "$env:LOCALAPPDATA\tauri\WixTools314\light.exe" -ErrorAction SilentlyContinue | Select-Object -First 1).FullName | |
| if (-not $light) { throw "WiX light.exe not found in $env:LOCALAPPDATA\tauri\WixTools314" } | |
| $version = (Get-Content src-tauri\tauri.conf.json -Raw | ConvertFrom-Json).version | |
| $bundleDir = Join-Path $appRoot 'src-tauri\target\release\bundle\msi' | |
| New-Item -ItemType Directory -Force -Path $bundleDir | Out-Null | |
| $msiPath = Join-Path $bundleDir "OpenLess_${version}_x64_en-US.msi" | |
| Push-Location $appRoot | |
| try { | |
| # -sice:ICE80:x86 IME DLL 与 x64 一同打进 INSTALLDIR\windows-ime\, | |
| # 这是 32 位组件落在 64 位 Directory 下的合法场景(DLL 路径绝对指向, | |
| # 不依赖 SysWOW64 重定向)。Tauri 自身没有暴露 light 透传参数,所以 | |
| # 必须在这里抑制,否则 LGHT0204 必失败。 | |
| & $light -nologo -sice:ICE80 -ext WixUIExtension -ext WixUtilExtension -loc $locale -out $msiPath $mainObj $imeObj | |
| if ($LASTEXITCODE -ne 0) { throw "light.exe relink failed with exit $LASTEXITCODE" } | |
| } finally { | |
| Pop-Location | |
| } | |
| Write-Host "[ok] MSI rebuilt at $msiPath" | |
| - name: Verify Windows installers register TSF IME | |
| if: matrix.platform == 'windows-latest' | |
| shell: pwsh | |
| working-directory: 'openless-all/app' | |
| run: | | |
| $nsis = Get-ChildItem "src-tauri\target\release\bundle\nsis\*.exe" -ErrorAction Stop | Select-Object -First 1 | |
| $msi = Get-ChildItem "src-tauri\target\release\bundle\msi\*.msi" -ErrorAction Stop | Select-Object -First 1 | |
| if (-not $nsis) { throw "NSIS installer not found." } | |
| if (-not $msi) { throw "MSI installer not found." } | |
| powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\windows-ime-install-smoke.ps1 -InstallerPath $nsis.FullName -InstallerKind nsis | |
| if ($LASTEXITCODE -ne 0) { | |
| throw "NSIS installer smoke failed with exit $LASTEXITCODE" | |
| } | |
| powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\windows-ime-install-smoke.ps1 -InstallerPath $msi.FullName -InstallerKind msi | |
| if ($LASTEXITCODE -ne 0) { | |
| throw "MSI installer smoke failed with exit $LASTEXITCODE" | |
| } | |
| # ── Linux:产 deb / rpm / AppImage ── | |
| # bundle.resources 里的 Windows TSF DLL 占位对 Linux 包没意义,用空 map 覆盖跳过。 | |
| - name: Build (Linux) | |
| if: matrix.platform == 'ubuntu-22.04' | |
| shell: bash | |
| working-directory: 'openless-all/app' | |
| env: | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| run: | | |
| if [ -n "${TAURI_SIGNING_PRIVATE_KEY:-}" ]; then | |
| npm run tauri -- build --bundles deb,rpm,appimage \ | |
| --config '{"bundle":{"resources":{},"createUpdaterArtifacts":true}}' | |
| else | |
| npm run tauri -- build --bundles deb,rpm,appimage \ | |
| --config '{"bundle":{"resources":{}}}' | |
| fi | |
| - name: Disambiguate macOS updater bundle filename | |
| if: startsWith(matrix.platform, 'macos') && env.TAURI_SIGNING_PRIVATE_KEY != '' | |
| shell: bash | |
| working-directory: 'openless-all/app/src-tauri/target/release/bundle/macos' | |
| run: | | |
| if [ -f OpenLess.app.tar.gz ]; then | |
| mv OpenLess.app.tar.gz "OpenLess_${{ matrix.updater-arch }}.app.tar.gz" | |
| fi | |
| if [ -f OpenLess.app.tar.gz.sig ]; then | |
| mv OpenLess.app.tar.gz.sig "OpenLess_${{ matrix.updater-arch }}.app.tar.gz.sig" | |
| fi | |
| - name: Write updater manifest | |
| if: env.TAURI_SIGNING_PRIVATE_KEY != '' | |
| shell: bash | |
| working-directory: 'openless-all/app' | |
| env: | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| OPENLESS_UPDATE_TARGET: ${{ matrix.updater-target }} | |
| OPENLESS_UPDATE_ARCH: ${{ matrix.updater-arch }} | |
| OPENLESS_UPDATE_REPO: appergb/openless | |
| OPENLESS_UPDATE_MIRROR_BASE_URL: https://fastgit.cc/https://github.com | |
| run: node scripts/write-updater-manifest.mjs | |
| # ── 收集产物 ── | |
| - name: List artifacts (debug) | |
| shell: bash | |
| working-directory: 'openless-all/app/src-tauri/target/release/bundle' | |
| run: ls -la macos/ dmg/ nsis/ msi/ deb/ rpm/ appimage/ 2>/dev/null || true | |
| # 防御性步骤:剥掉 macOS 产物上任何残留扩展属性 / quarantine。 | |
| # 理论上 GitHub Actions 输出的 .app/.dmg 不会带 com.apple.quarantine | |
| # (xattr 也不会通过 actions/upload-artifact 跨机器持久化),但保留这一步 | |
| # 让"云端 artifact 一定干净"成为可验证的承诺。用户下载后再被本地浏览器 | |
| # 加 quarantine 时,按 release notes 的 `xattr -cr` 一行即可消除。 | |
| - name: Strip xattr / quarantine on macOS bundles | |
| if: startsWith(matrix.platform, 'macos') | |
| shell: bash | |
| working-directory: 'openless-all/app/src-tauri/target/release/bundle' | |
| run: | | |
| for path in macos/*.app dmg/*.dmg; do | |
| if [ -e "$path" ]; then | |
| echo "▶ stripping xattr: $path" | |
| xattr -cr "$path" || true | |
| xattr -lr "$path" || true | |
| fi | |
| done | |
| - name: Upload macOS artifacts | |
| if: startsWith(matrix.platform, 'macos') | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: openless-macos-${{ matrix.updater-arch }} | |
| path: | | |
| openless-all/app/src-tauri/target/release/bundle/dmg/*.dmg | |
| if-no-files-found: error | |
| - name: Upload macOS updater artifacts | |
| if: startsWith(matrix.platform, 'macos') && env.TAURI_SIGNING_PRIVATE_KEY != '' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: openless-macos-${{ matrix.updater-arch }}-updater | |
| path: | | |
| openless-all/app/src-tauri/target/release/bundle/macos/*.app.tar.gz | |
| openless-all/app/src-tauri/target/release/bundle/macos/*.app.tar.gz.sig | |
| openless-all/app/src-tauri/target/release/bundle/latest-darwin-${{ matrix.updater-arch }}.json | |
| openless-all/app/src-tauri/target/release/bundle/latest-darwin-${{ matrix.updater-arch }}-mirror.json | |
| if-no-files-found: error | |
| - name: Upload Windows artifacts | |
| if: matrix.platform == 'windows-latest' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: openless-windows-x64 | |
| path: | | |
| openless-all/app/src-tauri/target/release/bundle/nsis/*.exe | |
| openless-all/app/src-tauri/target/release/bundle/msi/*.msi | |
| if-no-files-found: error | |
| - name: Upload Windows updater artifacts | |
| if: matrix.platform == 'windows-latest' && env.TAURI_SIGNING_PRIVATE_KEY != '' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: openless-windows-x64-updater | |
| path: | | |
| openless-all/app/src-tauri/target/release/bundle/nsis/*.exe.sig | |
| openless-all/app/src-tauri/target/release/bundle/msi/*.msi.sig | |
| openless-all/app/src-tauri/target/release/bundle/latest-windows-x86_64.json | |
| openless-all/app/src-tauri/target/release/bundle/latest-windows-x86_64-mirror.json | |
| if-no-files-found: error | |
| - name: Upload Linux artifacts | |
| if: matrix.platform == 'ubuntu-22.04' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: openless-linux-x64 | |
| path: | | |
| openless-all/app/src-tauri/target/release/bundle/deb/*.deb | |
| openless-all/app/src-tauri/target/release/bundle/rpm/*.rpm | |
| openless-all/app/src-tauri/target/release/bundle/appimage/*.AppImage | |
| if-no-files-found: error | |
| - name: Upload Linux updater artifacts | |
| if: matrix.platform == 'ubuntu-22.04' && env.TAURI_SIGNING_PRIVATE_KEY != '' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: openless-linux-x64-updater | |
| path: | | |
| openless-all/app/src-tauri/target/release/bundle/appimage/*.AppImage.sig | |
| openless-all/app/src-tauri/target/release/bundle/latest-linux-x86_64.json | |
| openless-all/app/src-tauri/target/release/bundle/latest-linux-x86_64-mirror.json | |
| if-no-files-found: error | |
| # ── tag 推送时,同步上传到 GitHub Release ── | |
| - name: Create / update release | |
| if: startsWith(github.ref, 'refs/tags/v') && endsWith(github.ref, '-tauri') | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ github.ref_name }} | |
| name: 'OpenLess ${{ github.ref_name }}' | |
| draft: false | |
| prerelease: false | |
| # Matrix jobs all upload assets to the same release. Generate notes once | |
| # so macOS, Windows, and Linux jobs do not duplicate the release body. | |
| generate_release_notes: ${{ matrix.updater-target == 'darwin' && matrix.updater-arch == 'aarch64' }} | |
| files: | | |
| openless-all/app/src-tauri/target/release/bundle/dmg/*.dmg | |
| openless-all/app/src-tauri/target/release/bundle/macos/*.app.tar.gz | |
| openless-all/app/src-tauri/target/release/bundle/macos/*.app.tar.gz.sig | |
| openless-all/app/src-tauri/target/release/bundle/nsis/*.exe | |
| openless-all/app/src-tauri/target/release/bundle/nsis/*.exe.sig | |
| openless-all/app/src-tauri/target/release/bundle/msi/*.msi | |
| openless-all/app/src-tauri/target/release/bundle/msi/*.msi.sig | |
| openless-all/app/src-tauri/target/release/bundle/deb/*.deb | |
| openless-all/app/src-tauri/target/release/bundle/rpm/*.rpm | |
| openless-all/app/src-tauri/target/release/bundle/appimage/*.AppImage | |
| openless-all/app/src-tauri/target/release/bundle/appimage/*.AppImage.sig | |
| openless-all/app/src-tauri/target/release/bundle/latest-*.json |