build #96
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: build | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "版本号(例如 1.2.3 或 v1.2.3)" | |
| required: true | |
| build: | |
| description: "构建命令标记(build:win|build:mac|build:linux|build:all)" | |
| required: true | |
| permissions: | |
| contents: write | |
| jobs: | |
| parse: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.parse.outputs.version }} | |
| tag: ${{ steps.parse.outputs.tag }} | |
| build_script: ${{ steps.parse.outputs.build_script }} | |
| run_win: ${{ steps.parse.outputs.run_win }} | |
| run_mac: ${{ steps.parse.outputs.run_mac }} | |
| run_linux: ${{ steps.parse.outputs.run_linux }} | |
| run_android: ${{ steps.parse.outputs.run_android }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: 读取提交信息 | |
| id: msg | |
| shell: bash | |
| run: | | |
| { | |
| echo "message<<__EOF__" | |
| echo "${{ github.event.inputs.version }} ${{ github.event.inputs.build }}" | |
| echo "__EOF__" | |
| } >> "$GITHUB_OUTPUT" | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| - name: 解析版本与构建命令 | |
| id: parse | |
| env: | |
| RELEASE_MESSAGE: ${{ steps.msg.outputs.message }} | |
| run: node scripts/ci/parse-commit.mjs | |
| build_win: | |
| needs: parse | |
| if: ${{ needs.parse.outputs.run_win == 'true' }} | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| - uses: pnpm/action-setup@v4 | |
| with: | |
| version: 10 | |
| - name: 安装 Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: x86_64-pc-windows-msvc | |
| - name: 应用版本号 | |
| run: node scripts/ci/apply-version.mjs ${{ needs.parse.outputs.version }} | |
| - name: 安装依赖 | |
| run: pnpm install --frozen-lockfile | |
| - name: 构建(Windows) | |
| run: pnpm tauri build --target x86_64-pc-windows-msvc | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist-win | |
| path: | | |
| src-tauri/target/x86_64-pc-windows-msvc/release/bundle/** | |
| src-tauri/target/release/bundle/** | |
| build_mac: | |
| needs: parse | |
| if: ${{ needs.parse.outputs.run_mac == 'true' }} | |
| runs-on: macos-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| - uses: pnpm/action-setup@v4 | |
| with: | |
| version: 10 | |
| - name: 安装 Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: x86_64-apple-darwin | |
| - name: 应用版本号 | |
| run: node scripts/ci/apply-version.mjs ${{ needs.parse.outputs.version }} | |
| - name: 安装依赖 | |
| run: pnpm install --frozen-lockfile | |
| - name: 构建(macOS) | |
| run: pnpm tauri build --target x86_64-apple-darwin | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist-mac | |
| path: | | |
| src-tauri/target/x86_64-apple-darwin/release/bundle/** | |
| src-tauri/target/aarch64-apple-darwin/release/bundle/** | |
| src-tauri/target/universal-apple-darwin/release/bundle/** | |
| src-tauri/target/release/bundle/** | |
| build_linux: | |
| needs: parse | |
| if: ${{ needs.parse.outputs.run_linux == 'true' }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| - uses: pnpm/action-setup@v4 | |
| with: | |
| version: 10 | |
| - name: 安装 Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: 安装系统依赖 | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf | |
| - name: 应用版本号 | |
| run: node scripts/ci/apply-version.mjs ${{ needs.parse.outputs.version }} | |
| - name: 安装依赖 | |
| run: pnpm install --frozen-lockfile | |
| - name: 构建(Linux) | |
| run: pnpm tauri build --target x86_64-unknown-linux-gnu | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist-linux | |
| path: | | |
| src-tauri/target/x86_64-unknown-linux-gnu/release/bundle/** | |
| src-tauri/target/release/bundle/** | |
| build_android: | |
| needs: parse | |
| if: ${{ needs.parse.outputs.run_android == 'true' }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| - uses: pnpm/action-setup@v4 | |
| with: | |
| version: 10 | |
| - name: 安装 Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: aarch64-linux-android, armv7-linux-androideabi, x86_64-linux-android, i686-linux-android | |
| - name: 安装 NDK | |
| uses: nttld/setup-ndk@v1 | |
| with: | |
| ndk-version: r25c | |
| - name: 安装 Java | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: "temurin" | |
| java-version: "17" | |
| - name: 应用版本号 | |
| run: node scripts/ci/apply-version.mjs ${{ needs.parse.outputs.version }} | |
| - name: 安装依赖 | |
| run: pnpm install --frozen-lockfile | |
| - name: 初始化 Android 项目 | |
| run: pnpm tauri android init | |
| - name: 构建 Android Universal APK | |
| run: pnpm tauri android build --target aarch64 --target armv7 --target x86_64 | |
| - name: 签名 APK | |
| env: | |
| ANDROID_SIGNING_KEY: ${{ secrets.ANDROID_SIGNING_KEY }} | |
| ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} | |
| ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} | |
| ANDROID_STORE_PASSWORD: ${{ secrets.ANDROID_STORE_PASSWORD }} | |
| if: ${{ env.ANDROID_SIGNING_KEY != '' }} | |
| run: | | |
| # 找到 Android SDK 中的 apksigner | |
| APKSIGNER=$(find ${ANDROID_SDK_ROOT} -name "apksigner" -type f 2>/dev/null | head -1) | |
| if [ -z "$APKSIGNER" ]; then | |
| echo "错误: 未找到 apksigner" | |
| exit 1 | |
| fi | |
| echo "使用 apksigner: $APKSIGNER" | |
| # 创建临时密钥库文件 | |
| echo "$ANDROID_SIGNING_KEY" | base64 -d > /tmp/android_keystore.jks | |
| # 找到所有未签名的 APK 文件 | |
| find src-tauri/gen/android/app/build/outputs -name "*-unsigned.apk" -type f | while read -r apk; do | |
| # 生成签名后的文件名 | |
| signed_apk="${apk/-unsigned/-signed}" | |
| # 使用 apksigner 签名 | |
| "$APKSIGNER" sign \ | |
| --ks /tmp/android_keystore.jks \ | |
| --ks-key-alias "$ANDROID_KEY_ALIAS" \ | |
| --ks-pass pass:"$ANDROID_STORE_PASSWORD" \ | |
| --key-pass pass:"$ANDROID_KEY_PASSWORD" \ | |
| --out "$signed_apk" \ | |
| "$apk" | |
| echo "已签名: $signed_apk" | |
| # 验证签名 | |
| "$APKSIGNER" verify "$signed_apk" | |
| # 删除未签名版本,重命名签名版本 | |
| rm "$apk" | |
| mv "$signed_apk" "${apk/-unsigned/}" | |
| done | |
| # 清理密钥库 | |
| rm -f /tmp/android_keystore.jks | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist-android | |
| path: | | |
| src-tauri/gen/android/app/build/outputs/**/*.apk | |
| !src-tauri/gen/android/app/build/outputs/**/*-unsigned.apk | |
| release: | |
| needs: [parse, build_win, build_mac, build_linux, build_android] | |
| if: ${{ always() && needs.parse.outputs.tag != '' && (needs.build_win.result == 'success' || needs.build_win.result == 'skipped') && (needs.build_mac.result == 'success' || needs.build_mac.result == 'skipped') && (needs.build_linux.result == 'success' || needs.build_linux.result == 'skipped') && (needs.build_android.result == 'success' || needs.build_android.result == 'skipped') }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| merge-multiple: true | |
| - name: 列出产物文件 | |
| run: | | |
| echo "Artifacts found:" | |
| find artifacts -type f -name "*.msi" -o -name "*.exe" -o -name "*.dmg" -o -name "*.app.tar.gz" -o -name "*.deb" -o -name "*.rpm" -o -name "*.AppImage" -o -name "*.apk" 2>/dev/null || true | |
| - name: 发布 Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ needs.parse.outputs.tag }} | |
| name: SecScore ${{ needs.parse.outputs.tag }} | |
| draft: True | |
| prerelease: ${{ contains(needs.parse.outputs.version, '-') }} | |
| files: | | |
| artifacts/**/*.msi | |
| artifacts/**/*.exe | |
| artifacts/**/*.dmg | |
| artifacts/**/*.app.tar.gz | |
| artifacts/**/*.deb | |
| artifacts/**/*.rpm | |
| artifacts/**/*.AppImage | |
| artifacts/**/*.apk |