From bf4d50241a10fab288c513697892b5f580f34998 Mon Sep 17 00:00:00 2001 From: GenshinMinecraft Date: Tue, 9 Jun 2026 10:41:34 +0800 Subject: [PATCH 1/3] ci: enhance release.yml for improved Android target support and build-std configurations --- .github/workflows/release.yml | 141 +++- .github/workflows/release.yml.bak | 1242 ++++++++++++++--------------- 2 files changed, 750 insertions(+), 633 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a948da9..aebd6c0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -130,28 +130,41 @@ jobs: fail-fast: false matrix: platform: - # x86_64 + # ── x86_64 ── - release_for: linux_x86_64_musl target: x86_64-unknown-linux-musl binary_name: nodeget-agent-linux-x86_64-musl - release_for: linux_x86_64_gnu target: x86_64-unknown-linux-gnu binary_name: nodeget-agent-linux-x86_64-gnu - # i686 + # Android:NDK 缺少 libunwind,必须用 build-std 编译 panic_abort 版 std + - release_for: linux_x86_64_android + target: x86_64-linux-android + binary_name: nodeget-agent-linux-x86_64-android + build_std: true + # ── i686 ── - release_for: linux_i686_gnu target: i686-unknown-linux-gnu binary_name: nodeget-agent-linux-i686-gnu - release_for: linux_i686_musl target: i686-unknown-linux-musl binary_name: nodeget-agent-linux-i686-musl - # aarch64 + - release_for: linux_i686_android + target: i686-linux-android + binary_name: nodeget-agent-linux-i686-android + build_std: true + # ── aarch64 ── - release_for: linux_aarch64_gnu target: aarch64-unknown-linux-gnu binary_name: nodeget-agent-linux-aarch64-gnu - release_for: linux_aarch64_musl target: aarch64-unknown-linux-musl binary_name: nodeget-agent-linux-aarch64-musl - # arm (generic) + - release_for: linux_aarch64_android + target: aarch64-linux-android + binary_name: nodeget-agent-linux-aarch64-android + build_std: true + # ── arm (generic) ── - release_for: linux_arm_gnueabi target: arm-unknown-linux-gnueabi binary_name: nodeget-agent-linux-arm-gnueabi @@ -164,7 +177,12 @@ jobs: - release_for: linux_arm_musleabihf target: arm-unknown-linux-musleabihf binary_name: nodeget-agent-linux-arm-musleabihf - # armv7 + # Android:NDK 缺少 libunwind + - release_for: linux_arm_androideabi + target: arm-linux-androideabi + binary_name: nodeget-agent-linux-arm-androideabi + build_std: true + # ── armv7 ── - release_for: linux_armv7_gnueabi target: armv7-unknown-linux-gnueabi binary_name: nodeget-agent-linux-armv7-gnueabi @@ -177,16 +195,70 @@ jobs: - release_for: linux_armv7_musleabihf target: armv7-unknown-linux-musleabihf binary_name: nodeget-agent-linux-armv7-musleabihf - # thumbv7neon (ARMv7 with NEON SIMD) + # Android:NDK 缺少 libunwind + - release_for: linux_armv7_androideabi + target: armv7-linux-androideabi + binary_name: nodeget-agent-linux-armv7-androideabi + build_std: true + # ── armv5te (tier 3):无预编译 std,必须 build-std ── + - release_for: linux_armv5te_gnueabi + target: armv5te-unknown-linux-gnueabi + binary_name: nodeget-agent-linux-armv5te-gnueabi + build_std: true + - release_for: linux_armv5te_musleabi + target: armv5te-unknown-linux-musleabi + binary_name: nodeget-agent-linux-armv5te-musleabi + build_std: true + # ── thumb ── - release_for: linux_thumbv7neon_gnueabihf target: thumbv7neon-unknown-linux-gnueabihf binary_name: nodeget-agent-linux-thumbv7neon-gnueabihf - # riscv64 - - release_for: linux_riscv64gc_gnu - target: riscv64gc-unknown-linux-gnu - binary_name: nodeget-agent-linux-riscv64gc-gnu - no_upx: true + # Android:stable 无预编译 std,必须 nightly + build-std + - release_for: linux_thumbv7neon_androideabi + target: thumbv7neon-linux-androideabi + binary_name: nodeget-agent-linux-thumbv7neon-androideabi + build_std: true + # mips (tier 3):无预编译 std,必须 build-std + - release_for: linux_mips_gnu + target: mips-unknown-linux-gnu + binary_name: nodeget-agent-linux-mips-gnu + build_std: true + - release_for: linux_mips_musl + target: mips-unknown-linux-musl + binary_name: nodeget-agent-linux-mips-musl + build_std: true + # mipsel (tier 3) + - release_for: linux_mipsel_gnu + target: mipsel-unknown-linux-gnu + binary_name: nodeget-agent-linux-mipsel-gnu + build_std: true + - release_for: linux_mipsel_musl + target: mipsel-unknown-linux-musl + binary_name: nodeget-agent-linux-mipsel-musl + build_std: true + # mips64 (tier 3) + - release_for: linux_mips64_gnu + target: mips64-unknown-linux-gnuabi64 + binary_name: nodeget-agent-linux-mips64-gnu + build_std: true + - release_for: linux_mips64_musl + target: mips64-unknown-linux-muslabi64 + binary_name: nodeget-agent-linux-mips64-musl + build_std: true + # mips64el (tier 3) + - release_for: linux_mips64el_gnu + target: mips64el-unknown-linux-gnuabi64 + binary_name: nodeget-agent-linux-mips64el-gnu + build_std: true + - release_for: linux_mips64el_musl + target: mips64el-unknown-linux-muslabi64 + binary_name: nodeget-agent-linux-mips64el-musl + build_std: true # powerpc + - release_for: linux_powerpc_gnu + target: powerpc-unknown-linux-gnu + binary_name: nodeget-agent-linux-powerpc-gnu + build_std: true - release_for: linux_powerpc64_gnu target: powerpc64-unknown-linux-gnu binary_name: nodeget-agent-linux-powerpc64-gnu @@ -200,6 +272,30 @@ jobs: target: s390x-unknown-linux-gnu binary_name: nodeget-agent-linux-s390x-gnu no_upx: true + # LoongArch64 + - release_for: linux_loongarch64_gnu + target: loongarch64-unknown-linux-gnu + binary_name: nodeget-agent-linux-loongarch64-gnu + build_std: true + - release_for: linux_loongarch64_musl + target: loongarch64-unknown-linux-musl + binary_name: nodeget-agent-linux-loongarch64-musl + build_std: true + # riscv64 + - release_for: linux_riscv64gc_gnu + target: riscv64gc-unknown-linux-gnu + binary_name: nodeget-agent-linux-riscv64gc-gnu + no_upx: true + - release_for: linux_riscv64gc_musl + target: riscv64gc-unknown-linux-musl + binary_name: nodeget-agent-linux-riscv64gc-musl + no_upx: true + build_std: true + # sparc64 + - release_for: linux_sparc64_gnu + target: sparc64-unknown-linux-gnu + binary_name: nodeget-agent-linux-sparc64-gnu + no_upx: true steps: - name: Checkout uses: actions/checkout@v6 @@ -222,11 +318,32 @@ jobs: | tar -xz -C "${HOME}/.local/bin" echo "${HOME}/.local/bin" >> "${GITHUB_PATH}" - - name: Build binary + - name: Install nightly toolchain for build-std + if: ${{ matrix.platform.build_std }} + run: rustup install nightly && rustup component add rust-src --toolchain nightly + + # 清除 CI 缓存中残留的预编译 target std,防止与 -Z build-std 冲突 + # 产生 "duplicate lang item in crate 'core'" 错误 + - name: Clean cached target std for build-std + if: ${{ matrix.platform.build_std }} + run: rustup target remove --toolchain nightly ${{ matrix.platform.target }} 2>/dev/null || true + + - name: Build binary (stable) + if: ${{ !matrix.platform.build_std }} run: cross build --package nodeget-agent --target ${{ matrix.platform.target }} --profile minimal --jobs 32 env: CROSS_NO_WARNINGS: 0 + # cross v0.2.5 的 Cross.toml build-std 只支持布尔值(true), + # 不支持字符串 "std,panic_abort",因此 -Z build-std=std,panic_abort + # 必须在命令行显式传递以包含 panic_abort。 + # Cross.toml 中的 build-std = true 让 cross 跳过 rustup target add。 + - name: Build binary (nightly, build-std) + if: ${{ matrix.platform.build_std }} + run: cross +nightly build --package nodeget-agent --target ${{ matrix.platform.target }} --profile minimal --jobs 32 -Z build-std=std,panic_abort + env: + CROSS_NO_WARNINGS: 0 + - name: Compress binary if: ${{ !matrix.platform.no_upx }} run: upx -9 ./target/${{ matrix.platform.target }}/minimal/nodeget-agent diff --git a/.github/workflows/release.yml.bak b/.github/workflows/release.yml.bak index aebd6c0..3628d1b 100644 --- a/.github/workflows/release.yml.bak +++ b/.github/workflows/release.yml.bak @@ -1,621 +1,621 @@ -name: release - -on: - workflow_dispatch: - inputs: - release_tag: - description: "Release tag to publish, for example v0.3.7. Leave empty for artifact-only manual builds." - required: false - type: string - publish_release: - description: "Create/update the GitHub Release and Docker image. Requires release_tag." - required: false - default: false - type: boolean - -concurrency: - group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.ref_name || inputs.release_tag || github.run_id }} - cancel-in-progress: false - -permissions: - contents: read - -env: - CARGO_TERM_COLOR: always - -jobs: - prepare: - name: Prepare release - runs-on: ubuntu-latest - outputs: - publish: ${{ steps.release.outputs.publish }} - tag: ${{ steps.release.outputs.tag }} - steps: - - name: Resolve release mode - id: release - shell: bash - run: | - publish="false" - tag="" - - # push tag 触发 → 自动发布;手动触发 → 读取 inputs - if [[ "${GITHUB_EVENT_NAME}" == "push" ]]; then - publish="true" - tag="${GITHUB_REF_NAME}" - else - publish="${{ inputs.publish_release }}" - tag="${{ inputs.release_tag }}" - fi - - # 发布时校验 tag 格式:v + 语义版本,允许 pre-release 后缀如 -rc1, +build123 - if [[ "${publish}" == "true" ]]; then - if [[ ! "${tag}" =~ ^v[0-9]+(\.[0-9]+)*([-+][0-9A-Za-z.-]+)?$ ]]; then - echo "release_tag must look like v0.3.7 when publishing" >&2 - exit 1 - fi - fi - - echo "publish=${publish}" >> "${GITHUB_OUTPUT}" - echo "tag=${tag}" >> "${GITHUB_OUTPUT}" - - build-linux-server: - name: Build Server - ${{ matrix.platform.release_for }} - needs: prepare - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - platform: - - release_for: linux_x86_64_musl - target: x86_64-unknown-linux-musl - binary_name: nodeget-server-linux-x86_64-musl - - release_for: linux_x86_64_gnu - target: x86_64-unknown-linux-gnu - binary_name: nodeget-server-linux-x86_64-gnu - - release_for: linux_aarch64_gnu - target: aarch64-unknown-linux-gnu - binary_name: nodeget-server-linux-aarch64-gnu - - release_for: linux_aarch64_musl - target: aarch64-unknown-linux-musl - binary_name: nodeget-server-linux-aarch64-musl - - release_for: linux_armv7_gnueabihf - target: armv7-unknown-linux-gnueabihf - binary_name: nodeget-server-linux-armv7-gnueabihf - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Setup Rust - uses: ./.github/actions/setup-rust - with: - cache-shared-key: release-linux-${{ matrix.platform.target }} - - - name: Install cross - env: - CROSS_VERSION: v0.2.5 - GH_TOKEN: ${{ github.token }} - run: | - mkdir -p "${HOME}/.local/bin" - gh release download "${CROSS_VERSION}" \ - --repo cross-rs/cross \ - --pattern cross-x86_64-unknown-linux-gnu.tar.gz \ - -O - \ - | tar -xz -C "${HOME}/.local/bin" - echo "${HOME}/.local/bin" >> "${GITHUB_PATH}" - - - name: Build binary - run: cross build --package nodeget-server --target ${{ matrix.platform.target }} --profile minimal --jobs 32 - env: - CROSS_NO_WARNINGS: 0 - - - name: Compress binary - run: upx -9 ./target/${{ matrix.platform.target }}/minimal/nodeget-server - - - name: Rename binary - run: cp target/${{ matrix.platform.target }}/minimal/nodeget-server target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} - - - name: Upload binary - uses: actions/upload-artifact@v4 - with: - name: server-${{ matrix.platform.target }} - path: target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} - if-no-files-found: error - retention-days: 14 - - build-linux-agent: - name: Build Agent - ${{ matrix.platform.release_for }} - needs: prepare - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - platform: - # ── x86_64 ── - - release_for: linux_x86_64_musl - target: x86_64-unknown-linux-musl - binary_name: nodeget-agent-linux-x86_64-musl - - release_for: linux_x86_64_gnu - target: x86_64-unknown-linux-gnu - binary_name: nodeget-agent-linux-x86_64-gnu - # Android:NDK 缺少 libunwind,必须用 build-std 编译 panic_abort 版 std - - release_for: linux_x86_64_android - target: x86_64-linux-android - binary_name: nodeget-agent-linux-x86_64-android - build_std: true - # ── i686 ── - - release_for: linux_i686_gnu - target: i686-unknown-linux-gnu - binary_name: nodeget-agent-linux-i686-gnu - - release_for: linux_i686_musl - target: i686-unknown-linux-musl - binary_name: nodeget-agent-linux-i686-musl - - release_for: linux_i686_android - target: i686-linux-android - binary_name: nodeget-agent-linux-i686-android - build_std: true - # ── aarch64 ── - - release_for: linux_aarch64_gnu - target: aarch64-unknown-linux-gnu - binary_name: nodeget-agent-linux-aarch64-gnu - - release_for: linux_aarch64_musl - target: aarch64-unknown-linux-musl - binary_name: nodeget-agent-linux-aarch64-musl - - release_for: linux_aarch64_android - target: aarch64-linux-android - binary_name: nodeget-agent-linux-aarch64-android - build_std: true - # ── arm (generic) ── - - release_for: linux_arm_gnueabi - target: arm-unknown-linux-gnueabi - binary_name: nodeget-agent-linux-arm-gnueabi - - release_for: linux_arm_gnueabihf - target: arm-unknown-linux-gnueabihf - binary_name: nodeget-agent-linux-arm-gnueabihf - - release_for: linux_arm_musleabi - target: arm-unknown-linux-musleabi - binary_name: nodeget-agent-linux-arm-musleabi - - release_for: linux_arm_musleabihf - target: arm-unknown-linux-musleabihf - binary_name: nodeget-agent-linux-arm-musleabihf - # Android:NDK 缺少 libunwind - - release_for: linux_arm_androideabi - target: arm-linux-androideabi - binary_name: nodeget-agent-linux-arm-androideabi - build_std: true - # ── armv7 ── - - release_for: linux_armv7_gnueabi - target: armv7-unknown-linux-gnueabi - binary_name: nodeget-agent-linux-armv7-gnueabi - - release_for: linux_armv7_gnueabihf - target: armv7-unknown-linux-gnueabihf - binary_name: nodeget-agent-linux-armv7-gnueabihf - - release_for: linux_armv7_musleabi - target: armv7-unknown-linux-musleabi - binary_name: nodeget-agent-linux-armv7-musleabi - - release_for: linux_armv7_musleabihf - target: armv7-unknown-linux-musleabihf - binary_name: nodeget-agent-linux-armv7-musleabihf - # Android:NDK 缺少 libunwind - - release_for: linux_armv7_androideabi - target: armv7-linux-androideabi - binary_name: nodeget-agent-linux-armv7-androideabi - build_std: true - # ── armv5te (tier 3):无预编译 std,必须 build-std ── - - release_for: linux_armv5te_gnueabi - target: armv5te-unknown-linux-gnueabi - binary_name: nodeget-agent-linux-armv5te-gnueabi - build_std: true - - release_for: linux_armv5te_musleabi - target: armv5te-unknown-linux-musleabi - binary_name: nodeget-agent-linux-armv5te-musleabi - build_std: true - # ── thumb ── - - release_for: linux_thumbv7neon_gnueabihf - target: thumbv7neon-unknown-linux-gnueabihf - binary_name: nodeget-agent-linux-thumbv7neon-gnueabihf - # Android:stable 无预编译 std,必须 nightly + build-std - - release_for: linux_thumbv7neon_androideabi - target: thumbv7neon-linux-androideabi - binary_name: nodeget-agent-linux-thumbv7neon-androideabi - build_std: true - # mips (tier 3):无预编译 std,必须 build-std - - release_for: linux_mips_gnu - target: mips-unknown-linux-gnu - binary_name: nodeget-agent-linux-mips-gnu - build_std: true - - release_for: linux_mips_musl - target: mips-unknown-linux-musl - binary_name: nodeget-agent-linux-mips-musl - build_std: true - # mipsel (tier 3) - - release_for: linux_mipsel_gnu - target: mipsel-unknown-linux-gnu - binary_name: nodeget-agent-linux-mipsel-gnu - build_std: true - - release_for: linux_mipsel_musl - target: mipsel-unknown-linux-musl - binary_name: nodeget-agent-linux-mipsel-musl - build_std: true - # mips64 (tier 3) - - release_for: linux_mips64_gnu - target: mips64-unknown-linux-gnuabi64 - binary_name: nodeget-agent-linux-mips64-gnu - build_std: true - - release_for: linux_mips64_musl - target: mips64-unknown-linux-muslabi64 - binary_name: nodeget-agent-linux-mips64-musl - build_std: true - # mips64el (tier 3) - - release_for: linux_mips64el_gnu - target: mips64el-unknown-linux-gnuabi64 - binary_name: nodeget-agent-linux-mips64el-gnu - build_std: true - - release_for: linux_mips64el_musl - target: mips64el-unknown-linux-muslabi64 - binary_name: nodeget-agent-linux-mips64el-musl - build_std: true - # powerpc - - release_for: linux_powerpc_gnu - target: powerpc-unknown-linux-gnu - binary_name: nodeget-agent-linux-powerpc-gnu - build_std: true - - release_for: linux_powerpc64_gnu - target: powerpc64-unknown-linux-gnu - binary_name: nodeget-agent-linux-powerpc64-gnu - no_upx: true - - release_for: linux_powerpc64le_gnu - target: powerpc64le-unknown-linux-gnu - binary_name: nodeget-agent-linux-powerpc64le-gnu - no_upx: true - # s390x (IBM Z) - - release_for: linux_s390x_gnu - target: s390x-unknown-linux-gnu - binary_name: nodeget-agent-linux-s390x-gnu - no_upx: true - # LoongArch64 - - release_for: linux_loongarch64_gnu - target: loongarch64-unknown-linux-gnu - binary_name: nodeget-agent-linux-loongarch64-gnu - build_std: true - - release_for: linux_loongarch64_musl - target: loongarch64-unknown-linux-musl - binary_name: nodeget-agent-linux-loongarch64-musl - build_std: true - # riscv64 - - release_for: linux_riscv64gc_gnu - target: riscv64gc-unknown-linux-gnu - binary_name: nodeget-agent-linux-riscv64gc-gnu - no_upx: true - - release_for: linux_riscv64gc_musl - target: riscv64gc-unknown-linux-musl - binary_name: nodeget-agent-linux-riscv64gc-musl - no_upx: true - build_std: true - # sparc64 - - release_for: linux_sparc64_gnu - target: sparc64-unknown-linux-gnu - binary_name: nodeget-agent-linux-sparc64-gnu - no_upx: true - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Setup Rust - uses: ./.github/actions/setup-rust - with: - cache-shared-key: release-agent-linux-${{ matrix.platform.target }} - - - name: Install cross - env: - CROSS_VERSION: v0.2.5 - GH_TOKEN: ${{ github.token }} - run: | - mkdir -p "${HOME}/.local/bin" - gh release download "${CROSS_VERSION}" \ - --repo cross-rs/cross \ - --pattern cross-x86_64-unknown-linux-gnu.tar.gz \ - -O - \ - | tar -xz -C "${HOME}/.local/bin" - echo "${HOME}/.local/bin" >> "${GITHUB_PATH}" - - - name: Install nightly toolchain for build-std - if: ${{ matrix.platform.build_std }} - run: rustup install nightly && rustup component add rust-src --toolchain nightly - - # 清除 CI 缓存中残留的预编译 target std,防止与 -Z build-std 冲突 - # 产生 "duplicate lang item in crate 'core'" 错误 - - name: Clean cached target std for build-std - if: ${{ matrix.platform.build_std }} - run: rustup target remove --toolchain nightly ${{ matrix.platform.target }} 2>/dev/null || true - - - name: Build binary (stable) - if: ${{ !matrix.platform.build_std }} - run: cross build --package nodeget-agent --target ${{ matrix.platform.target }} --profile minimal --jobs 32 - env: - CROSS_NO_WARNINGS: 0 - - # cross v0.2.5 的 Cross.toml build-std 只支持布尔值(true), - # 不支持字符串 "std,panic_abort",因此 -Z build-std=std,panic_abort - # 必须在命令行显式传递以包含 panic_abort。 - # Cross.toml 中的 build-std = true 让 cross 跳过 rustup target add。 - - name: Build binary (nightly, build-std) - if: ${{ matrix.platform.build_std }} - run: cross +nightly build --package nodeget-agent --target ${{ matrix.platform.target }} --profile minimal --jobs 32 -Z build-std=std,panic_abort - env: - CROSS_NO_WARNINGS: 0 - - - name: Compress binary - if: ${{ !matrix.platform.no_upx }} - run: upx -9 ./target/${{ matrix.platform.target }}/minimal/nodeget-agent - - - name: Rename binary - run: cp target/${{ matrix.platform.target }}/minimal/nodeget-agent target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} - - - name: Upload binary - uses: actions/upload-artifact@v4 - with: - name: agent-${{ matrix.platform.target }} - path: target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} - if-no-files-found: error - retention-days: 14 - - build-windows-server: - name: Build Server - ${{ matrix.platform.release_for }} - needs: prepare - runs-on: windows-latest - strategy: - fail-fast: false - matrix: - platform: - - release_for: windows_x86_64 - target: x86_64-pc-windows-msvc - binary_name: nodeget-server-windows-x86_64.exe - - release_for: windows_aarch64 - target: aarch64-pc-windows-msvc - binary_name: nodeget-server-windows-aarch64.exe - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Setup Rust - uses: ./.github/actions/setup-rust - with: - targets: ${{ matrix.platform.target }} - cache-shared-key: release-windows-${{ matrix.platform.target }} - - - name: Build binary - run: cargo build --package nodeget-server --target ${{ matrix.platform.target }} --profile minimal --jobs 32 - env: - CROSS_NO_WARNINGS: 0 - - - name: Rename binary - run: copy target\${{ matrix.platform.target }}\minimal\nodeget-server.exe target\${{ matrix.platform.target }}\minimal\${{ matrix.platform.binary_name }} - - - name: Upload binary - uses: actions/upload-artifact@v4 - with: - name: server-${{ matrix.platform.target }} - path: target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} - if-no-files-found: error - retention-days: 14 - - build-windows-agent: - name: Build Agent - ${{ matrix.platform.release_for }} - needs: prepare - runs-on: windows-latest - strategy: - fail-fast: false - matrix: - platform: - - release_for: windows_x86_64 - target: x86_64-pc-windows-msvc - binary_name: nodeget-agent-windows-x86_64.exe - - release_for: windows_aarch64 - target: aarch64-pc-windows-msvc - binary_name: nodeget-agent-windows-aarch64.exe - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Setup Rust - uses: ./.github/actions/setup-rust - with: - targets: ${{ matrix.platform.target }} - cache-shared-key: release-agent-windows-${{ matrix.platform.target }} - - - name: Build binary - run: cargo build --package nodeget-agent --target ${{ matrix.platform.target }} --profile minimal --jobs 32 - env: - CROSS_NO_WARNINGS: 0 - - - name: Rename binary - run: copy target\${{ matrix.platform.target }}\minimal\nodeget-agent.exe target\${{ matrix.platform.target }}\minimal\${{ matrix.platform.binary_name }} - - - name: Upload binary - uses: actions/upload-artifact@v4 - with: - name: agent-${{ matrix.platform.target }} - path: target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} - if-no-files-found: error - retention-days: 14 - - build-macos-server: - name: Build Server - ${{ matrix.platform.release_for }} - needs: prepare - runs-on: macos-latest - strategy: - fail-fast: false - matrix: - platform: - - release_for: macos_aarch64 - target: aarch64-apple-darwin - binary_name: nodeget-server-macos-aarch64 - - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Setup Rust - uses: ./.github/actions/setup-rust - with: - targets: ${{ matrix.platform.target }} - cache-shared-key: release-macos-${{ matrix.platform.target }} - - - name: Build binary - run: cargo build --package nodeget-server --target ${{ matrix.platform.target }} --profile minimal --jobs 32 - env: - CROSS_NO_WARNINGS: 0 - - - name: Rename binary - run: cp target/${{ matrix.platform.target }}/minimal/nodeget-server target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} - - - name: Upload binary - uses: actions/upload-artifact@v4 - with: - name: server-${{ matrix.platform.target }} - path: target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} - if-no-files-found: error - retention-days: 14 - - build-macos-agent: - name: Build Agent - ${{ matrix.platform.release_for }} - needs: prepare - runs-on: macos-latest - strategy: - fail-fast: false - matrix: - platform: - - release_for: macos_aarch64 - target: aarch64-apple-darwin - binary_name: nodeget-agent-macos-aarch64 - - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Setup Rust - uses: ./.github/actions/setup-rust - with: - targets: ${{ matrix.platform.target }} - cache-shared-key: release-agent-macos-${{ matrix.platform.target }} - - - name: Build binary - run: cargo build --package nodeget-agent --target ${{ matrix.platform.target }} --profile minimal --jobs 32 - env: - CROSS_NO_WARNINGS: 0 - - - name: Rename binary - run: cp target/${{ matrix.platform.target }}/minimal/nodeget-agent target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} - - - name: Upload binary - uses: actions/upload-artifact@v4 - with: - name: agent-${{ matrix.platform.target }} - path: target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} - if-no-files-found: error - retention-days: 14 - - publish-release: - name: Publish GitHub Release - needs: - - prepare - - build-linux-server - - build-windows-server - - build-macos-server - - build-linux-agent - - build-windows-agent - - build-macos-agent - if: needs.prepare.outputs.publish == 'true' - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: Download artifacts - uses: actions/download-artifact@v8 - with: - path: dist - merge-multiple: true - - - name: Upload release assets - uses: softprops/action-gh-release@v3 - with: - tag_name: ${{ needs.prepare.outputs.tag }} - name: NodeGet ${{ needs.prepare.outputs.tag }} - make_latest: true - files: dist/* - - publish-docker-server: - name: Publish Docker image - needs: - - prepare - - build-linux-server - if: needs.prepare.outputs.publish == 'true' - runs-on: ubuntu-latest - permissions: - actions: write - contents: read - packages: write - env: - REGISTRY: docker.io - IMAGE_NAME: genshinmc/nodeget - DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} - DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Check Docker Hub credentials - shell: bash - run: | - test -n "${DOCKERHUB_USERNAME}" - test -n "${DOCKERHUB_TOKEN}" - - - name: Download Linux musl binaries - uses: actions/download-artifact@v8 - with: - pattern: server-*-musl - path: downloads - merge-multiple: true - - - name: Prepare bin directory - shell: bash - run: | - mkdir -p bin - cp downloads/nodeget-server-linux-x86_64-musl bin/nodeget-server-amd64 - cp downloads/nodeget-server-linux-aarch64-musl bin/nodeget-server-arm64 - chmod 0755 bin/nodeget-server-amd64 bin/nodeget-server-arm64 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v4 - - - name: Login to Docker Hub - uses: docker/login-action@v4 - with: - registry: ${{ env.REGISTRY }} - username: ${{ env.DOCKERHUB_USERNAME }} - password: ${{ env.DOCKERHUB_TOKEN }} - - - name: Docker metadata - id: meta - uses: docker/metadata-action@v6 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=raw,value=latest - type=raw,value=${{ needs.prepare.outputs.tag }} - - - name: Build and push - uses: docker/build-push-action@v7 - with: - context: . - file: ./Dockerfile - target: runtime - platforms: linux/amd64,linux/arm64 - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max \ No newline at end of file +·name: release + + on: + workflow_dispatch: + inputs: + release_tag: + description: "Release tag to publish, for example v0.3.7. Leave empty for artifact-only manual builds." + required: false + type: string + publish_release: + description: "Create/update the GitHub Release and Docker image. Requires release_tag." + required: false + default: false + type: boolean + + concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.ref_name || inputs.release_tag || github.run_id }} + cancel-in-progress: false + + permissions: + contents: read + + env: + CARGO_TERM_COLOR: always + + jobs: + prepare: + name: Prepare release + runs-on: ubuntu-latest + outputs: + publish: ${{ steps.release.outputs.publish }} + tag: ${{ steps.release.outputs.tag }} + steps: + - name: Resolve release mode + id: release + shell: bash + run: | + publish="false" + tag="" + + # push tag 触发 → 自动发布;手动触发 → 读取 inputs + if [[ "${GITHUB_EVENT_NAME}" == "push" ]]; then + publish="true" + tag="${GITHUB_REF_NAME}" + else + publish="${{ inputs.publish_release }}" + tag="${{ inputs.release_tag }}" + fi + + # 发布时校验 tag 格式:v + 语义版本,允许 pre-release 后缀如 -rc1, +build123 + if [[ "${publish}" == "true" ]]; then + if [[ ! "${tag}" =~ ^v[0-9]+(\.[0-9]+)*([-+][0-9A-Za-z.-]+)?$ ]]; then + echo "release_tag must look like v0.3.7 when publishing" >&2 + exit 1 + fi + fi + + echo "publish=${publish}" >> "${GITHUB_OUTPUT}" + echo "tag=${tag}" >> "${GITHUB_OUTPUT}" + + build-linux-server: + name: Build Server - ${{ matrix.platform.release_for }} + needs: prepare + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + platform: + - release_for: linux_x86_64_musl + target: x86_64-unknown-linux-musl + binary_name: nodeget-server-linux-x86_64-musl + - release_for: linux_x86_64_gnu + target: x86_64-unknown-linux-gnu + binary_name: nodeget-server-linux-x86_64-gnu + - release_for: linux_aarch64_gnu + target: aarch64-unknown-linux-gnu + binary_name: nodeget-server-linux-aarch64-gnu + - release_for: linux_aarch64_musl + target: aarch64-unknown-linux-musl + binary_name: nodeget-server-linux-aarch64-musl + - release_for: linux_armv7_gnueabihf + target: armv7-unknown-linux-gnueabihf + binary_name: nodeget-server-linux-armv7-gnueabihf + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup Rust + uses: ./.github/actions/setup-rust + with: + cache-shared-key: release-linux-${{ matrix.platform.target }} + + - name: Install cross + env: + CROSS_VERSION: v0.2.5 + GH_TOKEN: ${{ github.token }} + run: | + mkdir -p "${HOME}/.local/bin" + gh release download "${CROSS_VERSION}" \ + --repo cross-rs/cross \ + --pattern cross-x86_64-unknown-linux-gnu.tar.gz \ + -O - \ + | tar -xz -C "${HOME}/.local/bin" + echo "${HOME}/.local/bin" >> "${GITHUB_PATH}" + + - name: Build binary + run: cross build --package nodeget-server --target ${{ matrix.platform.target }} --profile minimal --jobs 32 + env: + CROSS_NO_WARNINGS: 0 + + - name: Compress binary + run: upx -9 ./target/${{ matrix.platform.target }}/minimal/nodeget-server + + - name: Rename binary + run: cp target/${{ matrix.platform.target }}/minimal/nodeget-server target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} + + - name: Upload binary + uses: actions/upload-artifact@v4 + with: + name: server-${{ matrix.platform.target }} + path: target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} + if-no-files-found: error + retention-days: 14 + + build-linux-agent: + name: Build Agent - ${{ matrix.platform.release_for }} + needs: prepare + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + platform: + # ── x86_64 ── + - release_for: linux_x86_64_musl + target: x86_64-unknown-linux-musl + binary_name: nodeget-agent-linux-x86_64-musl + - release_for: linux_x86_64_gnu + target: x86_64-unknown-linux-gnu + binary_name: nodeget-agent-linux-x86_64-gnu + # Android:NDK 缺少 libunwind,必须用 build-std 编译 panic_abort 版 std + - release_for: linux_x86_64_android + target: x86_64-linux-android + binary_name: nodeget-agent-linux-x86_64-android + build_std: true + # ── i686 ── + - release_for: linux_i686_gnu + target: i686-unknown-linux-gnu + binary_name: nodeget-agent-linux-i686-gnu + - release_for: linux_i686_musl + target: i686-unknown-linux-musl + binary_name: nodeget-agent-linux-i686-musl + - release_for: linux_i686_android + target: i686-linux-android + binary_name: nodeget-agent-linux-i686-android + build_std: true + # ── aarch64 ── + - release_for: linux_aarch64_gnu + target: aarch64-unknown-linux-gnu + binary_name: nodeget-agent-linux-aarch64-gnu + - release_for: linux_aarch64_musl + target: aarch64-unknown-linux-musl + binary_name: nodeget-agent-linux-aarch64-musl + - release_for: linux_aarch64_android + target: aarch64-linux-android + binary_name: nodeget-agent-linux-aarch64-android + build_std: true + # ── arm (generic) ── + - release_for: linux_arm_gnueabi + target: arm-unknown-linux-gnueabi + binary_name: nodeget-agent-linux-arm-gnueabi + - release_for: linux_arm_gnueabihf + target: arm-unknown-linux-gnueabihf + binary_name: nodeget-agent-linux-arm-gnueabihf + - release_for: linux_arm_musleabi + target: arm-unknown-linux-musleabi + binary_name: nodeget-agent-linux-arm-musleabi + - release_for: linux_arm_musleabihf + target: arm-unknown-linux-musleabihf + binary_name: nodeget-agent-linux-arm-musleabihf + # Android:NDK 缺少 libunwind + - release_for: linux_arm_androideabi + target: arm-linux-androideabi + binary_name: nodeget-agent-linux-arm-androideabi + build_std: true + # ── armv7 ── + - release_for: linux_armv7_gnueabi + target: armv7-unknown-linux-gnueabi + binary_name: nodeget-agent-linux-armv7-gnueabi + - release_for: linux_armv7_gnueabihf + target: armv7-unknown-linux-gnueabihf + binary_name: nodeget-agent-linux-armv7-gnueabihf + - release_for: linux_armv7_musleabi + target: armv7-unknown-linux-musleabi + binary_name: nodeget-agent-linux-armv7-musleabi + - release_for: linux_armv7_musleabihf + target: armv7-unknown-linux-musleabihf + binary_name: nodeget-agent-linux-armv7-musleabihf + # Android:NDK 缺少 libunwind + - release_for: linux_armv7_androideabi + target: armv7-linux-androideabi + binary_name: nodeget-agent-linux-armv7-androideabi + build_std: true + # ── armv5te (tier 3):无预编译 std,必须 build-std ── + - release_for: linux_armv5te_gnueabi + target: armv5te-unknown-linux-gnueabi + binary_name: nodeget-agent-linux-armv5te-gnueabi + build_std: true + - release_for: linux_armv5te_musleabi + target: armv5te-unknown-linux-musleabi + binary_name: nodeget-agent-linux-armv5te-musleabi + build_std: true + # ── thumb ── + - release_for: linux_thumbv7neon_gnueabihf + target: thumbv7neon-unknown-linux-gnueabihf + binary_name: nodeget-agent-linux-thumbv7neon-gnueabihf + # Android:stable 无预编译 std,必须 nightly + build-std + - release_for: linux_thumbv7neon_androideabi + target: thumbv7neon-linux-androideabi + binary_name: nodeget-agent-linux-thumbv7neon-androideabi + build_std: true + # mips (tier 3):无预编译 std,必须 build-std + - release_for: linux_mips_gnu + target: mips-unknown-linux-gnu + binary_name: nodeget-agent-linux-mips-gnu + build_std: true + - release_for: linux_mips_musl + target: mips-unknown-linux-musl + binary_name: nodeget-agent-linux-mips-musl + build_std: true + # mipsel (tier 3) + - release_for: linux_mipsel_gnu + target: mipsel-unknown-linux-gnu + binary_name: nodeget-agent-linux-mipsel-gnu + build_std: true + - release_for: linux_mipsel_musl + target: mipsel-unknown-linux-musl + binary_name: nodeget-agent-linux-mipsel-musl + build_std: true + # mips64 (tier 3) + - release_for: linux_mips64_gnu + target: mips64-unknown-linux-gnuabi64 + binary_name: nodeget-agent-linux-mips64-gnu + build_std: true + - release_for: linux_mips64_musl + target: mips64-unknown-linux-muslabi64 + binary_name: nodeget-agent-linux-mips64-musl + build_std: true + # mips64el (tier 3) + - release_for: linux_mips64el_gnu + target: mips64el-unknown-linux-gnuabi64 + binary_name: nodeget-agent-linux-mips64el-gnu + build_std: true + - release_for: linux_mips64el_musl + target: mips64el-unknown-linux-muslabi64 + binary_name: nodeget-agent-linux-mips64el-musl + build_std: true + # powerpc + - release_for: linux_powerpc_gnu + target: powerpc-unknown-linux-gnu + binary_name: nodeget-agent-linux-powerpc-gnu + build_std: true + - release_for: linux_powerpc64_gnu + target: powerpc64-unknown-linux-gnu + binary_name: nodeget-agent-linux-powerpc64-gnu + no_upx: true + - release_for: linux_powerpc64le_gnu + target: powerpc64le-unknown-linux-gnu + binary_name: nodeget-agent-linux-powerpc64le-gnu + no_upx: true + # s390x (IBM Z) + - release_for: linux_s390x_gnu + target: s390x-unknown-linux-gnu + binary_name: nodeget-agent-linux-s390x-gnu + no_upx: true + # LoongArch64 + - release_for: linux_loongarch64_gnu + target: loongarch64-unknown-linux-gnu + binary_name: nodeget-agent-linux-loongarch64-gnu + build_std: true + - release_for: linux_loongarch64_musl + target: loongarch64-unknown-linux-musl + binary_name: nodeget-agent-linux-loongarch64-musl + build_std: true + # riscv64 + - release_for: linux_riscv64gc_gnu + target: riscv64gc-unknown-linux-gnu + binary_name: nodeget-agent-linux-riscv64gc-gnu + no_upx: true + - release_for: linux_riscv64gc_musl + target: riscv64gc-unknown-linux-musl + binary_name: nodeget-agent-linux-riscv64gc-musl + no_upx: true + build_std: true + # sparc64 + - release_for: linux_sparc64_gnu + target: sparc64-unknown-linux-gnu + binary_name: nodeget-agent-linux-sparc64-gnu + no_upx: true + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup Rust + uses: ./.github/actions/setup-rust + with: + cache-shared-key: release-agent-linux-${{ matrix.platform.target }} + + - name: Install cross + env: + CROSS_VERSION: v0.2.5 + GH_TOKEN: ${{ github.token }} + run: | + mkdir -p "${HOME}/.local/bin" + gh release download "${CROSS_VERSION}" \ + --repo cross-rs/cross \ + --pattern cross-x86_64-unknown-linux-gnu.tar.gz \ + -O - \ + | tar -xz -C "${HOME}/.local/bin" + echo "${HOME}/.local/bin" >> "${GITHUB_PATH}" + + - name: Install nightly toolchain for build-std + if: ${{ matrix.platform.build_std }} + run: rustup install nightly && rustup component add rust-src --toolchain nightly + + # 清除 CI 缓存中残留的预编译 target std,防止与 -Z build-std 冲突 + # 产生 "duplicate lang item in crate 'core'" 错误 + - name: Clean cached target std for build-std + if: ${{ matrix.platform.build_std }} + run: rustup target remove --toolchain nightly ${{ matrix.platform.target }} 2>/dev/null || true + + - name: Build binary (stable) + if: ${{ !matrix.platform.build_std }} + run: cross build --package nodeget-agent --target ${{ matrix.platform.target }} --profile minimal --jobs 32 + env: + CROSS_NO_WARNINGS: 0 + + # cross v0.2.5 的 Cross.toml build-std 只支持布尔值(true), + # 不支持字符串 "std,panic_abort",因此 -Z build-std=std,panic_abort + # 必须在命令行显式传递以包含 panic_abort。 + # Cross.toml 中的 build-std = true 让 cross 跳过 rustup target add。 + - name: Build binary (nightly, build-std) + if: ${{ matrix.platform.build_std }} + run: cross +nightly build --package nodeget-agent --target ${{ matrix.platform.target }} --profile minimal --jobs 32 -Z build-std=std,panic_abort + env: + CROSS_NO_WARNINGS: 0 + + - name: Compress binary + if: ${{ !matrix.platform.no_upx }} + run: upx -9 ./target/${{ matrix.platform.target }}/minimal/nodeget-agent + + - name: Rename binary + run: cp target/${{ matrix.platform.target }}/minimal/nodeget-agent target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} + + - name: Upload binary + uses: actions/upload-artifact@v4 + with: + name: agent-${{ matrix.platform.target }} + path: target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} + if-no-files-found: error + retention-days: 14 + + build-windows-server: + name: Build Server - ${{ matrix.platform.release_for }} + needs: prepare + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + platform: + - release_for: windows_x86_64 + target: x86_64-pc-windows-msvc + binary_name: nodeget-server-windows-x86_64.exe + - release_for: windows_aarch64 + target: aarch64-pc-windows-msvc + binary_name: nodeget-server-windows-aarch64.exe + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup Rust + uses: ./.github/actions/setup-rust + with: + targets: ${{ matrix.platform.target }} + cache-shared-key: release-windows-${{ matrix.platform.target }} + + - name: Build binary + run: cargo build --package nodeget-server --target ${{ matrix.platform.target }} --profile minimal --jobs 32 + env: + CROSS_NO_WARNINGS: 0 + + - name: Rename binary + run: copy target\${{ matrix.platform.target }}\minimal\nodeget-server.exe target\${{ matrix.platform.target }}\minimal\${{ matrix.platform.binary_name }} + + - name: Upload binary + uses: actions/upload-artifact@v4 + with: + name: server-${{ matrix.platform.target }} + path: target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} + if-no-files-found: error + retention-days: 14 + + build-windows-agent: + name: Build Agent - ${{ matrix.platform.release_for }} + needs: prepare + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + platform: + - release_for: windows_x86_64 + target: x86_64-pc-windows-msvc + binary_name: nodeget-agent-windows-x86_64.exe + - release_for: windows_aarch64 + target: aarch64-pc-windows-msvc + binary_name: nodeget-agent-windows-aarch64.exe + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup Rust + uses: ./.github/actions/setup-rust + with: + targets: ${{ matrix.platform.target }} + cache-shared-key: release-agent-windows-${{ matrix.platform.target }} + + - name: Build binary + run: cargo build --package nodeget-agent --target ${{ matrix.platform.target }} --profile minimal --jobs 32 + env: + CROSS_NO_WARNINGS: 0 + + - name: Rename binary + run: copy target\${{ matrix.platform.target }}\minimal\nodeget-agent.exe target\${{ matrix.platform.target }}\minimal\${{ matrix.platform.binary_name }} + + - name: Upload binary + uses: actions/upload-artifact@v4 + with: + name: agent-${{ matrix.platform.target }} + path: target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} + if-no-files-found: error + retention-days: 14 + + build-macos-server: + name: Build Server - ${{ matrix.platform.release_for }} + needs: prepare + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + platform: + - release_for: macos_aarch64 + target: aarch64-apple-darwin + binary_name: nodeget-server-macos-aarch64 + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup Rust + uses: ./.github/actions/setup-rust + with: + targets: ${{ matrix.platform.target }} + cache-shared-key: release-macos-${{ matrix.platform.target }} + + - name: Build binary + run: cargo build --package nodeget-server --target ${{ matrix.platform.target }} --profile minimal --jobs 32 + env: + CROSS_NO_WARNINGS: 0 + + - name: Rename binary + run: cp target/${{ matrix.platform.target }}/minimal/nodeget-server target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} + + - name: Upload binary + uses: actions/upload-artifact@v4 + with: + name: server-${{ matrix.platform.target }} + path: target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} + if-no-files-found: error + retention-days: 14 + + build-macos-agent: + name: Build Agent - ${{ matrix.platform.release_for }} + needs: prepare + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + platform: + - release_for: macos_aarch64 + target: aarch64-apple-darwin + binary_name: nodeget-agent-macos-aarch64 + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup Rust + uses: ./.github/actions/setup-rust + with: + targets: ${{ matrix.platform.target }} + cache-shared-key: release-agent-macos-${{ matrix.platform.target }} + + - name: Build binary + run: cargo build --package nodeget-agent --target ${{ matrix.platform.target }} --profile minimal --jobs 32 + env: + CROSS_NO_WARNINGS: 0 + + - name: Rename binary + run: cp target/${{ matrix.platform.target }}/minimal/nodeget-agent target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} + + - name: Upload binary + uses: actions/upload-artifact@v4 + with: + name: agent-${{ matrix.platform.target }} + path: target/${{ matrix.platform.target }}/minimal/${{ matrix.platform.binary_name }} + if-no-files-found: error + retention-days: 14 + + publish-release: + name: Publish GitHub Release + needs: + - prepare + - build-linux-server + - build-windows-server + - build-macos-server + - build-linux-agent + - build-windows-agent + - build-macos-agent + if: needs.prepare.outputs.publish == 'true' + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Download artifacts + uses: actions/download-artifact@v8 + with: + path: dist + merge-multiple: true + + - name: Upload release assets + uses: softprops/action-gh-release@v3 + with: + tag_name: ${{ needs.prepare.outputs.tag }} + name: NodeGet ${{ needs.prepare.outputs.tag }} + make_latest: true + files: dist/* + + publish-docker-server: + name: Publish Docker image + needs: + - prepare + - build-linux-server + if: needs.prepare.outputs.publish == 'true' + runs-on: ubuntu-latest + permissions: + actions: write + contents: read + packages: write + env: + REGISTRY: docker.io + IMAGE_NAME: genshinmc/nodeget + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Check Docker Hub credentials + shell: bash + run: | + test -n "${DOCKERHUB_USERNAME}" + test -n "${DOCKERHUB_TOKEN}" + + - name: Download Linux musl binaries + uses: actions/download-artifact@v8 + with: + pattern: server-*-musl + path: downloads + merge-multiple: true + + - name: Prepare bin directory + shell: bash + run: | + mkdir -p bin + cp downloads/nodeget-server-linux-x86_64-musl bin/nodeget-server-amd64 + cp downloads/nodeget-server-linux-aarch64-musl bin/nodeget-server-arm64 + chmod 0755 bin/nodeget-server-amd64 bin/nodeget-server-arm64 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Login to Docker Hub + uses: docker/login-action@v4 + with: + registry: ${{ env.REGISTRY }} + username: ${{ env.DOCKERHUB_USERNAME }} + password: ${{ env.DOCKERHUB_TOKEN }} + + - name: Docker metadata + id: meta + uses: docker/metadata-action@v6 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=latest + type=raw,value=${{ needs.prepare.outputs.tag }} + + - name: Build and push + uses: docker/build-push-action@v7 + with: + context: . + file: ./Dockerfile + target: runtime + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max \ No newline at end of file From 5943eb7a4fe4382dd80611716350f70fb7ecf0e0 Mon Sep 17 00:00:00 2001 From: GenshinMinecraft Date: Tue, 9 Jun 2026 11:01:41 +0800 Subject: [PATCH 2/3] Fix: add getrandom shim for older glibc versions and update build dependencies --- .github/workflows/release.yml | 4 ++++ Cargo.lock | 1 + Cross.toml | 21 ++++++++++++++++----- agent/Cargo.toml | 3 +++ agent/build.rs | 25 +++++++++++++++++++++++++ agent/getrandom_shim.c | 18 ++++++++++++++++++ 6 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 agent/build.rs create mode 100644 agent/getrandom_shim.c diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index aebd6c0..819d9fb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -241,19 +241,23 @@ jobs: target: mips64-unknown-linux-gnuabi64 binary_name: nodeget-agent-linux-mips64-gnu build_std: true + no_upx: true - release_for: linux_mips64_musl target: mips64-unknown-linux-muslabi64 binary_name: nodeget-agent-linux-mips64-musl build_std: true + no_upx: true # mips64el (tier 3) - release_for: linux_mips64el_gnu target: mips64el-unknown-linux-gnuabi64 binary_name: nodeget-agent-linux-mips64el-gnu build_std: true + no_upx: true - release_for: linux_mips64el_musl target: mips64el-unknown-linux-muslabi64 binary_name: nodeget-agent-linux-mips64el-musl build_std: true + no_upx: true # powerpc - release_for: linux_powerpc_gnu target: powerpc-unknown-linux-gnu diff --git a/Cargo.lock b/Cargo.lock index e9d22a9..203db2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2944,6 +2944,7 @@ version = "0.5.11" dependencies = [ "anyhow", "base64", + "cc", "futures-util", "hickory-resolver", "libc", diff --git a/Cross.toml b/Cross.toml index 6b82679..6eb5cad 100644 --- a/Cross.toml +++ b/Cross.toml @@ -1,4 +1,4 @@ -## Android +### Android:NDK 缺少 libunwind,必须用 build-std 编译 panic_abort 版 std #[target.x86_64-linux-android] #build-std = true # @@ -17,25 +17,25 @@ #[target.thumbv7neon-linux-androideabi] #build-std = true # -## ARM 老款 (tier 3):无预编译 std,必须从源码构建 +### ARM 老款 (tier 3):无预编译 std,必须从源码构建 #[target.armv5te-unknown-linux-gnueabi] #build-std = true # #[target.armv5te-unknown-linux-musleabi] #build-std = true # -## 极老 x86 (tier 3) +### 极老 x86 (tier 3) #[target.i586-unknown-linux-gnu] #build-std = true # #[target.i586-unknown-linux-musl] #build-std = true # -## 32 位 PowerPC (tier 3) +### 32 位 PowerPC (tier 3) #[target.powerpc-unknown-linux-gnu] #build-std = true # -## MIPS 系列 (tier 3):无预编译 std,必须从源码构建 +### MIPS 系列 (tier 3):无预编译 std,必须从源码构建 #[target.mips-unknown-linux-gnu] #build-std = true # @@ -59,3 +59,14 @@ # #[target.mips64el-unknown-linux-muslabi64] #build-std = true +# +### LoongArch64 (tier 3) +#[target.loongarch64-unknown-linux-gnu] +#build-std = true +# +#[target.loongarch64-unknown-linux-musl] +#build-std = true +# +### RISC-V 64 musl (tier 3) +#[target.riscv64gc-unknown-linux-musl] +#build-std = true diff --git a/agent/Cargo.toml b/agent/Cargo.toml index b539376..0272839 100644 --- a/agent/Cargo.toml +++ b/agent/Cargo.toml @@ -3,6 +3,9 @@ name = "nodeget-agent" version.workspace = true edition.workspace = true +[build-dependencies] +cc = "1" + [dependencies] # Internal crates ng-core = { workspace = true, features = ["for-agent"] } diff --git a/agent/build.rs b/agent/build.rs new file mode 100644 index 0000000..6ab07bf --- /dev/null +++ b/agent/build.rs @@ -0,0 +1,25 @@ +fn main() { + let target = std::env::var("TARGET").unwrap_or_default(); + if needs_getrandom_shim(&target) { + cc::Build::new() + .file("getrandom_shim.c") + .compile("getrandom_shim"); + } +} + +/// Tier-3 glibc Linux 目标可能使用旧版 glibc(< 2.25),缺少 getrandom() C 函数。 +/// +/// Rust 标准库和 getrandom crate v0.3+ 在 glibc 环境下调用 libc::getrandom(), +/// 如果 glibc 版本太旧,链接器会报 `undefined reference to 'getrandom'`。 +/// +/// 通过弱符号提供 getrandom() 实现:如果 glibc 已有此函数则被覆盖,无副作用。 +fn needs_getrandom_shim(target: &str) -> bool { + // MIPS 系列 (tier 3):无预编译 std,cross Docker 镜像 glibc 较旧 + let is_mips_gnu = target.starts_with("mips") && target.contains("linux") && target.contains("gnu"); + // ARMv5TE (tier 3):同上 + let is_armv5te_gnu = target.contains("armv5te") && target.contains("linux") && target.contains("gnu"); + // PowerPC 32-bit (tier 3):同上 + let is_powerpc_gnu = target == "powerpc-unknown-linux-gnu"; + + is_mips_gnu || is_armv5te_gnu || is_powerpc_gnu +} diff --git a/agent/getrandom_shim.c b/agent/getrandom_shim.c new file mode 100644 index 0000000..f2dce6b --- /dev/null +++ b/agent/getrandom_shim.c @@ -0,0 +1,18 @@ +/* + * 为旧版 glibc(< 2.25)提供 getrandom() 函数 + * + * glibc 2.25 才引入了 getrandom() C 函数,但 getrandom 系统调用在 Linux 3.17 就已可用。 + * Rust 标准库(std::sys::random::linux)在 glibc 目标上调用 libc::getrandom(), + * getrandom crate v0.3+ 也改用了 libc::getrandom()(而非 v0.2 的 libc::syscall())。 + * 当交叉编译环境的 glibc 版本 < 2.25 时,链接器会报 undefined reference to 'getrandom'。 + * + * 使用弱符号:如果 glibc 已提供 getrandom(),则优先使用 glibc 版本。 + */ +#include +#include +#include + +__attribute__((weak)) +ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) { + return syscall(SYS_getrandom, buf, buflen, flags); +} From cf113c4a23f76804f616ca5d4090f4b058643ffe Mon Sep 17 00:00:00 2001 From: GenshinMinecraft Date: Tue, 9 Jun 2026 11:12:36 +0800 Subject: [PATCH 3/3] ci: remove Android and LoongArch64 build-std configurations from release.yml --- .github/workflows/release.yml | 32 ---------------- Cross.toml | 72 ----------------------------------- 2 files changed, 104 deletions(-) delete mode 100644 Cross.toml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 819d9fb..c97645e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -137,11 +137,6 @@ jobs: - release_for: linux_x86_64_gnu target: x86_64-unknown-linux-gnu binary_name: nodeget-agent-linux-x86_64-gnu - # Android:NDK 缺少 libunwind,必须用 build-std 编译 panic_abort 版 std - - release_for: linux_x86_64_android - target: x86_64-linux-android - binary_name: nodeget-agent-linux-x86_64-android - build_std: true # ── i686 ── - release_for: linux_i686_gnu target: i686-unknown-linux-gnu @@ -149,10 +144,6 @@ jobs: - release_for: linux_i686_musl target: i686-unknown-linux-musl binary_name: nodeget-agent-linux-i686-musl - - release_for: linux_i686_android - target: i686-linux-android - binary_name: nodeget-agent-linux-i686-android - build_std: true # ── aarch64 ── - release_for: linux_aarch64_gnu target: aarch64-unknown-linux-gnu @@ -160,10 +151,6 @@ jobs: - release_for: linux_aarch64_musl target: aarch64-unknown-linux-musl binary_name: nodeget-agent-linux-aarch64-musl - - release_for: linux_aarch64_android - target: aarch64-linux-android - binary_name: nodeget-agent-linux-aarch64-android - build_std: true # ── arm (generic) ── - release_for: linux_arm_gnueabi target: arm-unknown-linux-gnueabi @@ -276,30 +263,11 @@ jobs: target: s390x-unknown-linux-gnu binary_name: nodeget-agent-linux-s390x-gnu no_upx: true - # LoongArch64 - - release_for: linux_loongarch64_gnu - target: loongarch64-unknown-linux-gnu - binary_name: nodeget-agent-linux-loongarch64-gnu - build_std: true - - release_for: linux_loongarch64_musl - target: loongarch64-unknown-linux-musl - binary_name: nodeget-agent-linux-loongarch64-musl - build_std: true # riscv64 - release_for: linux_riscv64gc_gnu target: riscv64gc-unknown-linux-gnu binary_name: nodeget-agent-linux-riscv64gc-gnu no_upx: true - - release_for: linux_riscv64gc_musl - target: riscv64gc-unknown-linux-musl - binary_name: nodeget-agent-linux-riscv64gc-musl - no_upx: true - build_std: true - # sparc64 - - release_for: linux_sparc64_gnu - target: sparc64-unknown-linux-gnu - binary_name: nodeget-agent-linux-sparc64-gnu - no_upx: true steps: - name: Checkout uses: actions/checkout@v6 diff --git a/Cross.toml b/Cross.toml deleted file mode 100644 index 6eb5cad..0000000 --- a/Cross.toml +++ /dev/null @@ -1,72 +0,0 @@ -### Android:NDK 缺少 libunwind,必须用 build-std 编译 panic_abort 版 std -#[target.x86_64-linux-android] -#build-std = true -# -#[target.i686-linux-android] -#build-std = true -# -#[target.aarch64-linux-android] -#build-std = true -# -#[target.arm-linux-androideabi] -#build-std = true -# -#[target.armv7-linux-androideabi] -#build-std = true -# -#[target.thumbv7neon-linux-androideabi] -#build-std = true -# -### ARM 老款 (tier 3):无预编译 std,必须从源码构建 -#[target.armv5te-unknown-linux-gnueabi] -#build-std = true -# -#[target.armv5te-unknown-linux-musleabi] -#build-std = true -# -### 极老 x86 (tier 3) -#[target.i586-unknown-linux-gnu] -#build-std = true -# -#[target.i586-unknown-linux-musl] -#build-std = true -# -### 32 位 PowerPC (tier 3) -#[target.powerpc-unknown-linux-gnu] -#build-std = true -# -### MIPS 系列 (tier 3):无预编译 std,必须从源码构建 -#[target.mips-unknown-linux-gnu] -#build-std = true -# -#[target.mips-unknown-linux-musl] -#build-std = true -# -#[target.mipsel-unknown-linux-gnu] -#build-std = true -# -#[target.mipsel-unknown-linux-musl] -#build-std = true -# -#[target.mips64-unknown-linux-gnuabi64] -#build-std = true -# -#[target.mips64-unknown-linux-muslabi64] -#build-std = true -# -#[target.mips64el-unknown-linux-gnuabi64] -#build-std = true -# -#[target.mips64el-unknown-linux-muslabi64] -#build-std = true -# -### LoongArch64 (tier 3) -#[target.loongarch64-unknown-linux-gnu] -#build-std = true -# -#[target.loongarch64-unknown-linux-musl] -#build-std = true -# -### RISC-V 64 musl (tier 3) -#[target.riscv64gc-unknown-linux-musl] -#build-std = true