release #15
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: | |
| 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 | |
| # ── 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_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_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 | |
| 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 | |
| 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 | |
| # riscv64 | |
| - release_for: linux_riscv64gc_gnu | |
| target: riscv64gc-unknown-linux-gnu | |
| binary_name: nodeget-agent-linux-riscv64gc-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 |