fix: load Windows TIP installer dynamically #77
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 | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| permissions: | |
| contents: write | |
| jobs: | |
| create-release: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| release-id: ${{ steps.create.outputs.result }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - id: create | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const tag = context.ref.replace('refs/tags/', '') | |
| const { data } = await github.rest.repos.createRelease({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| tag_name: tag, | |
| name: tag, | |
| generate_release_notes: true, | |
| draft: false, | |
| prerelease: tag.includes('alpha'), | |
| }) | |
| return data.id | |
| build-desktop: | |
| needs: create-release | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - platform: ubuntu-22.04 | |
| os_name: linux | |
| package_arch: x64 | |
| - platform: ubuntu-24.04-arm | |
| os_name: linux | |
| package_arch: arm64 | |
| - platform: macos-15-intel | |
| os_name: macos | |
| package_arch: x86_64 | |
| - platform: macos-15 | |
| os_name: macos | |
| package_arch: arm64 | |
| - platform: windows-latest | |
| os_name: windows | |
| package_arch: x64 | |
| windows_arch: x64 | |
| runs-on: ${{ matrix.platform }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: pnpm/action-setup@v4 | |
| with: | |
| version: 10 | |
| - uses: actions/setup-node@v4 | |
| if: matrix.os_name == 'linux' | |
| with: | |
| node-version: 22 | |
| - uses: actions/setup-node@v4 | |
| if: matrix.os_name != 'linux' | |
| with: | |
| node-version: 22 | |
| cache: pnpm | |
| - uses: dtolnay/rust-toolchain@stable | |
| if: matrix.os_name == 'macos' | |
| with: | |
| targets: aarch64-apple-darwin,x86_64-apple-darwin | |
| - uses: dtolnay/rust-toolchain@stable | |
| if: matrix.os_name == 'windows' | |
| - uses: Swatinem/rust-cache@v2 | |
| if: matrix.os_name != 'linux' | |
| with: | |
| workspaces: src-tauri | |
| - name: Install Linux verification deps | |
| if: matrix.os_name == 'linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends \ | |
| dpkg-dev patchelf rpm | |
| - name: Install Windows system deps | |
| if: startsWith(matrix.platform, 'windows') | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| choco install 7zip -y --no-progress | |
| choco install llvm -y --no-progress | |
| $llvmBin = "C:\Program Files\LLVM\bin" | |
| $llvmBin | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append | |
| "LIBCLANG_PATH=$llvmBin" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
| - if: matrix.os_name != 'linux' | |
| run: pnpm install --frozen-lockfile | |
| - name: Set version from tag | |
| shell: bash | |
| run: | | |
| node scripts/sync-version.mjs --set "${GITHUB_REF_NAME#v}" | |
| - name: Build Linux packages | |
| if: matrix.os_name == 'linux' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| scripts/build-linux.sh | |
| - name: Build Windows installer | |
| if: startsWith(matrix.platform, 'windows') | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| powershell -ExecutionPolicy Bypass -File scripts\build-windows.ps1 -Arch ${{ matrix.windows_arch }} | |
| - name: Build macOS pkg | |
| if: matrix.os_name == 'macos' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| pnpm build:macos | |
| - name: Verify macOS pkg | |
| if: matrix.os_name == 'macos' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| scripts/verify-macos-pkg.sh target/keytao-macos-pkg/KeyTao.pkg | |
| - name: Upload macOS pkg to release | |
| if: matrix.os_name == 'macos' | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| VERSION="${GITHUB_REF_NAME#v}" | |
| pkg="target/keytao-macos-pkg/KeyTao.pkg" | |
| renamed="target/keytao-macos-pkg/keytao-app-${VERSION}-macos-${{ matrix.package_arch }}.pkg" | |
| test -f "$pkg" | |
| cp "$pkg" "$renamed" | |
| gh release upload ${{ github.ref_name }} "$renamed" --clobber | |
| - name: Upload Windows installer to release | |
| if: startsWith(matrix.platform, 'windows') | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| $installer = Get-ChildItem -Path "target\release\bundle\nsis" -Filter "*.exe" -File | Select-Object -First 1 | |
| if (-not $installer) { | |
| throw "Missing Windows NSIS installer" | |
| } | |
| $version = $env:GITHUB_REF_NAME -replace '^v', '' | |
| $renamed = Join-Path $installer.DirectoryName "keytao-app-$version-windows-${{ matrix.windows_arch }}-setup.exe" | |
| Copy-Item -Force -LiteralPath $installer.FullName -Destination $renamed | |
| gh release upload $env:GITHUB_REF_NAME $renamed --clobber | |
| - name: Verify Linux bundles | |
| if: matrix.os_name == 'linux' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| scripts/verify-linux-bundles.sh target/release/bundle | |
| - name: Upload Linux artifacts to release | |
| if: matrix.os_name == 'linux' | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| VERSION="${GITHUB_REF_NAME#v}" | |
| mkdir -p dist/release-upload | |
| rm -f dist/release-upload/* | |
| while IFS= read -r artifact; do | |
| ext="${artifact##*.}" | |
| renamed="dist/release-upload/keytao-app-${VERSION}-linux-${{ matrix.package_arch }}.${ext}" | |
| cp "$artifact" "$renamed" | |
| done < <(find dist -maxdepth 1 -type f \( -name '*.deb' -o -name '*.rpm' \) | sort) | |
| mapfile -t artifacts < <(find dist/release-upload -maxdepth 1 -type f \( -name '*.deb' -o -name '*.rpm' \) | sort) | |
| if [[ "${#artifacts[@]}" -eq 0 ]]; then | |
| echo "::error::No Linux artifacts found in dist" | |
| find target/release/bundle -maxdepth 4 -type f -print 2>/dev/null | sort || true | |
| exit 1 | |
| fi | |
| gh release upload ${{ github.ref_name }} "${artifacts[@]}" --clobber | |
| build-android: | |
| needs: create-release | |
| runs-on: ubuntu-latest | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| KEYTAO_ANDROID_LIBRIME_HEADERS_VERSION: "1.17.0" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: pnpm/action-setup@v4 | |
| with: | |
| version: 10 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: pnpm | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: aarch64-linux-android,armv7-linux-androideabi,i686-linux-android,x86_64-linux-android | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: src-tauri | |
| - uses: actions/setup-java@v4 | |
| with: | |
| java-version: 17 | |
| distribution: temurin | |
| - uses: android-actions/setup-android@v3 | |
| - run: sdkmanager "ndk;27.0.12077973" | |
| - run: pnpm install --frozen-lockfile | |
| - name: Set version from tag | |
| run: | | |
| node scripts/sync-version.mjs --set "${GITHUB_REF_NAME#v}" | |
| - name: Init Android project | |
| run: | | |
| export NDK_HOME="$ANDROID_HOME/ndk/27.0.12077973" | |
| export ANDROID_NDK_HOME="$NDK_HOME" | |
| pnpm tauri android init --ci --skip-targets-install | |
| - name: Setup Android signing | |
| env: | |
| ANDROID_KEY_BASE64: ${{ secrets.ANDROID_KEY_BASE64 }} | |
| ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} | |
| ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} | |
| run: | | |
| set -euo pipefail | |
| if [[ -z "${ANDROID_KEY_BASE64:-}" || -z "${ANDROID_KEY_ALIAS:-}" || -z "${ANDROID_KEY_PASSWORD:-}" ]]; then | |
| echo "::error::ANDROID_KEY_BASE64, ANDROID_KEY_ALIAS and ANDROID_KEY_PASSWORD are required for release APK signing" | |
| exit 1 | |
| fi | |
| cd src-tauri/gen/android | |
| echo "$ANDROID_KEY_BASE64" | base64 -d > "$RUNNER_TEMP/keystore_orig.jks" | |
| keytool -importkeystore \ | |
| -srckeystore "$RUNNER_TEMP/keystore_orig.jks" \ | |
| -destkeystore "$RUNNER_TEMP/keystore.jks" \ | |
| -deststoretype JKS \ | |
| -srcstorepass "$ANDROID_KEY_PASSWORD" \ | |
| -deststorepass "$ANDROID_KEY_PASSWORD" \ | |
| -noprompt | |
| echo "keyAlias=$ANDROID_KEY_ALIAS" > keystore.properties | |
| echo "password=$ANDROID_KEY_PASSWORD" >> keystore.properties | |
| echo "storeFile=$RUNNER_TEMP/keystore.jks" >> keystore.properties | |
| - name: Import Android librime runtime | |
| run: | | |
| set -euo pipefail | |
| export NDK_HOME="$ANDROID_HOME/ndk/27.0.12077973" | |
| export ANDROID_NDK_HOME="$NDK_HOME" | |
| for abi in arm64-v8a armeabi-v7a x86 x86_64; do | |
| scripts/android-librime-runtime.sh import-fcitx5-rime --abi "$abi" | |
| done | |
| scripts/android-librime-runtime.sh verify --all | |
| scripts/android-librime-runtime.sh sync --all | |
| - name: Build Android APK | |
| run: | | |
| set -euo pipefail | |
| export NDK_HOME="$ANDROID_HOME/ndk/27.0.12077973" | |
| export ANDROID_NDK_HOME="$NDK_HOME" | |
| export KEYTAO_ANDROID_SKIP_RUNTIME_SYNC=1 | |
| unset BZIP2_LIB_DIR BZIP2_INCLUDE_DIR | |
| pnpm tauri android build --ci --apk --split-per-abi --target aarch64 armv7 i686 x86_64 | |
| - name: Upload APKs to release | |
| run: | | |
| set -euo pipefail | |
| VERSION="${GITHUB_REF_NAME#v}" | |
| mkdir -p dist/release-upload | |
| rm -f dist/release-upload/*.apk | |
| mapfile -t apks < <(find src-tauri/gen/android/app/build/outputs/apk -type f -name "*.apk" | grep -v "/androidTest/" | sort) | |
| if [[ "${#apks[@]}" -eq 0 ]]; then | |
| echo "::error::No Android APKs found" | |
| find src-tauri/gen/android -maxdepth 6 -type f -name "*.apk" -print 2>/dev/null | sort || true | |
| exit 1 | |
| fi | |
| artifacts=() | |
| for apk in "${apks[@]}"; do | |
| base="$(basename "$apk" .apk)" | |
| base="${base#app-}" | |
| renamed="dist/release-upload/keytao-app-${VERSION}-android-${base}.apk" | |
| cp "$apk" "$renamed" | |
| artifacts+=("$renamed") | |
| done | |
| gh release upload ${{ github.ref_name }} "${artifacts[@]}" --clobber | |
| build-ios: | |
| needs: create-release | |
| runs-on: macos-15 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: pnpm/action-setup@v4 | |
| with: | |
| version: 10 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: pnpm | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: aarch64-apple-ios,aarch64-apple-ios-sim,x86_64-apple-ios | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: src-tauri | |
| - run: pnpm install --frozen-lockfile | |
| - name: Set version from tag | |
| run: | | |
| node scripts/sync-version.mjs --set "${GITHUB_REF_NAME#v}" | |
| - name: Build unsigned iOS package | |
| run: | | |
| set -euo pipefail | |
| pnpm build:ios -- --no-sign --ci |