name: Release on: workflow_dispatch: # 只允许手动触发 inputs: version: description: '版本号(例如:v1.0.0)' required: true default: 'v1.0.0' env: CARGO_TERM_COLOR: always jobs: # ────────────────────────────────────────────────────────────────── # 各平台 Rust 构建(example 可执行 + JNI so/dll/dylib) # ────────────────────────────────────────────────────────────────── build-and-release: name: Build and Release for ${{ matrix.target }} runs-on: ${{ matrix.os }} permissions: contents: write strategy: fail-fast: false matrix: include: # Linux x86_64 (GNU) - target: x86_64-unknown-linux-gnu os: ubuntu-latest use_cross: false platform: linux jni_lib: libdht_crawler.so build_features: mimalloc,metrics,jni # Linux ARM64 - target: aarch64-unknown-linux-gnu os: ubuntu-latest use_cross: true platform: linux jni_lib: libdht_crawler.so build_features: mimalloc,metrics,jni # Windows x86_64 (GNU/MinGW,在 Windows 上原生构建,无需交叉编译) - target: x86_64-pc-windows-gnu os: windows-latest use_cross: false platform: windows jni_lib: dht_crawler.dll build_features: mimalloc,metrics,jni # macOS x86_64 - target: x86_64-apple-darwin os: macos-latest use_cross: false platform: macos jni_lib: libdht_crawler.dylib build_features: mimalloc,metrics,jni # macOS ARM64 (Apple Silicon) - target: aarch64-apple-darwin os: macos-latest use_cross: false platform: macos jni_lib: libdht_crawler.dylib build_features: mimalloc,metrics,jni steps: - name: Checkout code uses: actions/checkout@v3 - name: Install Rust uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.target }} - name: Install cross if: matrix.use_cross run: cargo install cross --git https://github.com/cross-rs/cross - name: Setup MSYS2 MinGW (Windows GNU) if: matrix.target == 'x86_64-pc-windows-gnu' uses: msys2/setup-msys2@v2 with: update: true install: mingw-w64-x86_64-gcc - name: Add MinGW to PATH (Windows GNU) if: matrix.target == 'x86_64-pc-windows-gnu' run: echo "C:\msys64\mingw64\bin" >> $env:GITHUB_PATH shell: pwsh - name: Cache cargo registry uses: actions/cache@v3 with: path: ~/.cargo/registry key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} - name: Cache cargo index uses: actions/cache@v3 with: path: ~/.cargo/git key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} # release 构建不缓存 target 目录,避免占用 GitHub 缓存配额 - name: Run tests run: | if [ "${{ matrix.use_cross }}" = "true" ]; then cross test --target ${{ matrix.target }} --verbose else cargo test --target ${{ matrix.target }} --verbose fi shell: bash - name: Run tests with features run: | if [ "${{ matrix.use_cross }}" = "true" ]; then cross test --target ${{ matrix.target }} --verbose --features ${{ matrix.build_features }} else cargo test --target ${{ matrix.target }} --verbose --features ${{ matrix.build_features }} fi shell: bash - name: Build (lib cdylib + examples) run: | if [ "${{ matrix.use_cross }}" = "true" ]; then cross build --release --target ${{ matrix.target }} --lib --examples --features ${{ matrix.build_features }} else cargo build --release --target ${{ matrix.target }} --lib --examples --features ${{ matrix.build_features }} fi shell: bash - name: Get version id: get_version run: | VERSION="${{ github.event.inputs.version }}" echo "version=$VERSION" >> $GITHUB_OUTPUT shell: bash # ────────── example 产物打包 ────────── - name: Prepare example artifacts (Linux/macOS) if: "!contains(matrix.target, 'windows')" run: | cd target/${{ matrix.target }}/release/examples tar czf dht_crawler_example-${{ steps.get_version.outputs.version }}-${{ matrix.target }}.tar.gz dht_crawler_example mv dht_crawler_example-${{ steps.get_version.outputs.version }}-${{ matrix.target }}.tar.gz ${{ github.workspace }}/ shell: bash - name: Prepare example artifacts (Windows GNU) if: contains(matrix.target, 'windows') run: | cd target/${{ matrix.target }}/release/examples Compress-Archive -Path dht_crawler_example.exe -DestinationPath dht_crawler_example-${{ steps.get_version.outputs.version }}-${{ matrix.target }}.zip Move-Item -Path dht_crawler_example-${{ steps.get_version.outputs.version }}-${{ matrix.target }}.zip -Destination ${{ github.workspace }}/ shell: pwsh # ────────── JNI 动态库打包(仅含单个 so/dll/dylib,体积最小)────────── - name: Prepare JNI artifacts (Linux/macOS) if: "!contains(matrix.target, 'windows')" run: | VERSION=${{ steps.get_version.outputs.version }} TARGET=${{ matrix.target }} LIB=${{ matrix.jni_lib }} WORKDIR=$(mktemp -d) cp target/${TARGET}/release/${LIB} ${WORKDIR}/ cd ${WORKDIR} zip dht_crawler_jni-${VERSION}-${TARGET}.zip ${LIB} mv dht_crawler_jni-${VERSION}-${TARGET}.zip ${{ github.workspace }}/ shell: bash - name: Prepare JNI artifacts (Windows) if: contains(matrix.target, 'windows') run: | $VERSION = "${{ steps.get_version.outputs.version }}" $TARGET = "${{ matrix.target }}" $LIB = "${{ matrix.jni_lib }}" $WORKDIR = New-TemporaryFile | ForEach-Object { Remove-Item $_; New-Item -ItemType Directory -Path $_.FullName } Copy-Item "target/$TARGET/release/$LIB" -Destination $WORKDIR.FullName Set-Location $WORKDIR.FullName Compress-Archive -Path $LIB -DestinationPath "dht_crawler_jni-$VERSION-$TARGET.zip" Move-Item -Path "dht_crawler_jni-$VERSION-$TARGET.zip" -Destination "${{ github.workspace }}/" shell: pwsh # ────────── 上传到 Release ────────── - name: Upload Release Assets uses: softprops/action-gh-release@v1 with: tag_name: ${{ github.event.inputs.version }} files: | dht_crawler_example-${{ steps.get_version.outputs.version }}-${{ matrix.target }}.* dht_crawler_jni-${{ steps.get_version.outputs.version }}-${{ matrix.target }}.zip