dht-crawler 0.1.2

高性能的 Rust DHT (Distributed Hash Table) 爬虫库 | A high-performance Rust DHT crawler library for fetching torrent information from the BitTorrent DHT network
Documentation
name: Release

on:
  workflow_dispatch:  # 只允许手动触发
    inputs:
      version:
        description: '版本号(例如:v1.0.0)'
        required: true
        default: 'v1.0.0'

env:
  CARGO_TERM_COLOR: always

jobs:
  # ──────────────────────────────────────────────────────────────────
  # Java fat JAR(平台无关,只需构建一次)
  # 运行方式:java -Djava.library.path=<so/dll 目录> -jar dht-crawler-jni-example-<ver>.jar
  # ──────────────────────────────────────────────────────────────────
  build-java-jar:
    name: Build Java Example JAR
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: '17'

      - name: Build fat JAR
        working-directory: examples-jni
        run: |

          chmod +x gradlew
          ./gradlew shadowJar -PprojectVersion=${{ github.event.inputs.version }} --no-daemon
        shell: bash

      - name: Upload JAR to Release
        uses: softprops/action-gh-release@v1
        with:
          tag_name: ${{ github.event.inputs.version }}
          files: examples-jni/build/libs/dht-crawler-jni-example-${{ github.event.inputs.version }}.jar

  # ──────────────────────────────────────────────────────────────────
  # 各平台 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