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:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
cross: false
strip: true
compress: true
- target: aarch64-apple-darwin
os: macos-latest
cross: false
strip: true
compress: true
- 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 }}
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 }}