tidepool-gvm 0.2.2

A simple, high-performance Go version management tool written in Rust with clean architecture and minimal dependencies
Documentation
name: Release

on:
  push:
    tags:
      - "v*"
  workflow_dispatch:

env:
  CARGO_TERM_COLOR: always

jobs:
  build:
    name: Build ${{ matrix.target }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          # Linux x86_64
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
            cross: false
            strip: true
            compress: true

          # macOS Apple Silicon (M 系列)
          - target: aarch64-apple-darwin
            os: macos-latest
            cross: false
            strip: true
            compress: true

          # Windows x86_64
          - target: x86_64-pc-windows-msvc
            os: windows-latest
            cross: false
            strip: false
            compress: true

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      - name: Cache Cargo registry
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
          key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-${{ matrix.target }}-cargo-

      - name: Cache target directory
        uses: actions/cache@v4
        with:
          path: target
          key: ${{ runner.os }}-${{ matrix.target }}-target-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-${{ matrix.target }}-target-

      - name: Build release binary
        run: |
          cargo build --release --target ${{ matrix.target }}
        shell: bash

      - name: Strip binary (Unix)
        if: matrix.strip && runner.os != 'Windows'
        run: |
          strip target/${{ matrix.target }}/release/gvm

      - name: Create archive name
        id: archive
        run: |
          if [ "${{ runner.os }}" = "Windows" ]; then
            echo "name=tidepool-gvm-${{ matrix.target }}" >> $GITHUB_OUTPUT
            echo "file=tidepool-gvm-${{ matrix.target }}.zip" >> $GITHUB_OUTPUT
            echo "binary=gvm.exe" >> $GITHUB_OUTPUT
          else
            echo "name=tidepool-gvm-${{ matrix.target }}" >> $GITHUB_OUTPUT
            echo "file=tidepool-gvm-${{ matrix.target }}.tar.gz" >> $GITHUB_OUTPUT
            echo "binary=gvm" >> $GITHUB_OUTPUT
          fi
        shell: bash

      - name: Create archive (Windows)
        if: runner.os == 'Windows'
        run: |
          cd target/${{ matrix.target }}/release
          7z a ../../../${{ steps.archive.outputs.file }} gvm.exe
          cd ../../..

      - name: Create archive (Unix)
        if: runner.os != 'Windows'
        run: |
          cd target/${{ matrix.target }}/release
          tar -czf ../../../${{ steps.archive.outputs.file }} gvm
          cd ../../..

      - name: Calculate checksums
        id: checksums
        run: |
          if [ "${{ runner.os }}" = "Windows" ]; then
            echo "sha256=$(certutil -hashfile ${{ steps.archive.outputs.file }} SHA256 | findstr /v "hash")" >> $GITHUB_OUTPUT
          else
            echo "sha256=$(shasum -a 256 ${{ steps.archive.outputs.file }} | cut -d ' ' -f1)" >> $GITHUB_OUTPUT
          fi
        shell: bash

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: ${{ steps.archive.outputs.name }}
          path: ${{ steps.archive.outputs.file }}
          retention-days: 1

    outputs:
      archive-name: ${{ steps.archive.outputs.name }}
      archive-file: ${{ steps.archive.outputs.file }}
      checksum: ${{ steps.checksums.outputs.sha256 }}

  release:
    name: Create Release
    needs: build
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/')

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Download all artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts

      - name: Prepare release assets
        run: |
          mkdir -p release-assets
          find artifacts -name "*.tar.gz" -o -name "*.zip" | while read file; do
            cp "$file" release-assets/
          done
          ls -la release-assets/

      - name: Generate checksums
        run: |
          cd release-assets
          shasum -a 256 * > SHA256SUMS
          cat SHA256SUMS

      - name: Extract release notes
        id: release_notes
        run: |
          if [ -f CHANGELOG.md ]; then
            # 提取最新版本的更新日志
            awk '/^## /{if(p) exit; if(/^## \[?[0-9]/) p=1} p' CHANGELOG.md > release_notes.md
          else
            echo "## 发布说明" > release_notes.md
            echo "" >> release_notes.md
            echo "这是 Tidepool GVM (Go Version Manager) 的新版本发布。" >> release_notes.md
            echo "" >> release_notes.md
            echo "### 📥 下载说明" >> release_notes.md
            echo "" >> release_notes.md
            echo "请根据您的操作系统选择对应的二进制文件:" >> release_notes.md
            echo "" >> release_notes.md
            echo "- **Linux x86_64**: \`tidepool-gvm-x86_64-unknown-linux-gnu.tar.gz\`" >> release_notes.md
            echo "- **macOS Apple Silicon**: \`tidepool-gvm-aarch64-apple-darwin.tar.gz\`" >> release_notes.md
            echo "- **Windows x86_64**: \`tidepool-gvm-x86_64-pc-windows-msvc.zip\`" >> release_notes.md
            echo "" >> release_notes.md
            echo "### 🔒 安全验证" >> release_notes.md
            echo "" >> release_notes.md
            echo "所有二进制文件的 SHA256 校验和都包含在 \`SHA256SUMS\` 文件中。" >> release_notes.md
            echo "" >> release_notes.md
            echo "### 🚀 安装方法" >> release_notes.md
            echo "" >> release_notes.md
            echo "1. 下载对应平台的压缩包" >> release_notes.md
            echo "2. 解压缩到您选择的目录" >> release_notes.md
            echo "3. 将 \`gvm\` 可执行文件添加到系统 PATH" >> release_notes.md
            echo "4. 运行 \`gvm --help\` 查看使用说明" >> release_notes.md
            echo "" >> release_notes.md
            echo "### 🛠️ 使用方法" >> release_notes.md
            echo "" >> release_notes.md
            echo "安装 Go 版本:" >> release_notes.md
            echo "\`\`\`bash" >> release_notes.md
            echo "gvm install 1.21.3" >> release_notes.md
            echo "\`\`\`" >> release_notes.md
            echo "" >> release_notes.md
            echo "切换到指定版本:" >> release_notes.md
            echo "\`\`\`bash" >> release_notes.md
            echo "gvm switch 1.21.3" >> release_notes.md
            echo "\`\`\`" >> release_notes.md
            echo "" >> release_notes.md
            echo "查看已安装版本:" >> release_notes.md
            echo "\`\`\`bash" >> release_notes.md
            echo "gvm list" >> release_notes.md
            echo "\`\`\`" >> release_notes.md
          fi

      - name: Create Release
        uses: softprops/action-gh-release@v1
        with:
          name: Release ${{ github.ref_name }}
          body_path: release_notes.md
          files: |
            release-assets/*
          draft: false
          prerelease: ${{ contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta') || contains(github.ref_name, 'rc') }}
          generate_release_notes: false
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  # 发布到 crates.io
  publish-crates:
    name: Publish to crates.io
    needs: build
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/') && !contains(github.ref_name, 'alpha') && !contains(github.ref_name, 'beta') && !contains(github.ref_name, 'rc')

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Publish to crates.io
        run: |
          cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}