背景
当前发布 Pre-release 版本需要手动创建 GitHub Release,流程繁琐。建议实现推送 tag 时自动发布 Pre-release。
修改内容
1. 触发条件更新
在 on.push 下添加 tag 触发:
on:
push:
branches: [main, develop]
tags:
- 'v*' # 推送 v 开头的 tag 时触发自动发布
2. 新增 auto-prerelease Job
- 触发条件: 推送 tag 且 tag 包含
-(如 -rc, -beta, -alpha)
- 功能:
- 自动构建多平台二进制文件
- 读取
RELEASE_NOTES_{VERSION}.md 作为 release notes
- 自动创建 GitHub Pre-release
- 上传构建产物和 checksums
3. Homebrew 更新优化
- 仅稳定版触发 Homebrew 更新(tag 不包含
-)
- Pre-release 不会自动更新 Homebrew
使用方式
推送 tag 即可自动发布 Pre-release:
git tag v0.7.0-rc.2
git push origin v0.7.0-rc.2
GitHub Actions 会自动:
- 运行测试和构建
- 创建 Pre-release
- 上传二进制文件
完整文件内容
name: CI
on:
push:
branches: [main, develop]
tags:
- 'v*' # 推送 v 开头的 tag 时触发自动发布
pull_request:
branches: [main]
release:
types: [published]
env:
CARGO_TERM_COLOR: always
permissions:
contents: write
jobs:
# 基础检查 (Linux x86_64)
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
- name: Check formatting
run: cargo fmt -- --check
- name: Run clippy
run: cargo clippy -- -D warnings
# 多平台构建矩阵
build-matrix:
strategy:
matrix:
include:
# macOS Apple Silicon (ARM64)
- os: macos-latest
target: aarch64-apple-darwin
cross: false
# Linux x86_64
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
cross: false
# Linux ARM64 (交叉编译)
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
cross: true
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install cross (for ARM64 Linux)
if: matrix.cross
run: cargo install cross --git https://github.com/cross-rs/cross
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Build (native)
if: '!matrix.cross'
run: cargo build --release --target ${{ matrix.target }}
- name: Build (cross)
if: matrix.cross
env:
RUSTFLAGS: "-C linker=aarch64-linux-gnu-gcc"
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
run: cross build --release --target ${{ matrix.target }}
- name: Upload binary
uses: actions/upload-artifact@v4
with:
name: standx-${{ matrix.target }}
path: target/${{ matrix.target }}/release/standx
# 发布 Release (手动创建 release 时触发)
release:
needs: [check, build-matrix]
runs-on: ubuntu-latest
if: github.event_name == 'release'
steps:
- uses: actions/checkout@v4
- name: Download all binaries
uses: actions/download-artifact@v4
with:
path: ./binaries
- name: Package binaries
run: |
VERSION="${{ github.event.release.tag_name }}"
mkdir -p ./packages
for target in aarch64-apple-darwin x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu; do
if [ -f "./binaries/standx-${target}/standx" ]; then
chmod +x "./binaries/standx-${target}/standx"
tar -czf "./packages/standx-${VERSION}-${target}.tar.gz" -C "./binaries/standx-${target}" standx
echo "Packaged: standx-${VERSION}-${target}.tar.gz"
fi
done
- name: Generate checksums
run: |
cd ./packages
sha256sum *.tar.gz > checksums.txt
cat checksums.txt
- name: Upload install.sh to release
run: |
cp install.sh ./packages/
- name: Upload to release
uses: softprops/action-gh-release@v1
with:
files: |
./packages/*.tar.gz
./packages/checksums.txt
./packages/install.sh
token: ${{ secrets.GITHUB_TOKEN }}
# 自动发布 Pre-release (推送 tag 时触发)
auto-prerelease:
needs: [check, build-matrix]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v') && contains(github.ref, '-')
steps:
- uses: actions/checkout@v4
- name: Download all binaries
uses: actions/download-artifact@v4
with:
path: ./binaries
- name: Package binaries
run: |
VERSION="${GITHUB_REF#refs/tags/}"
mkdir -p ./packages
for target in aarch64-apple-darwin x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu; do
if [ -f "./binaries/standx-${target}/standx" ]; then
chmod +x "./binaries/standx-${target}/standx"
tar -czf "./packages/standx-${VERSION}-${target}.tar.gz" -C "./binaries/standx-${target}" standx
echo "Packaged: standx-${VERSION}-${target}.tar.gz"
fi
done
- name: Generate checksums
run: |
cd ./packages
sha256sum *.tar.gz > checksums.txt
cat checksums.txt
- name: Read release notes
id: notes
run: |
VERSION="${GITHUB_REF#refs/tags/}"
if [ -f "RELEASE_NOTES_${VERSION}.md" ]; then
echo "body<<EOF" >> $GITHUB_OUTPUT
cat "RELEASE_NOTES_${VERSION}.md" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
fi
- name: Create/Update Pre-release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ github.ref_name }}
name: ${{ github.ref_name }}
body: ${{ steps.notes.outputs.body }}
prerelease: true
files: |
./packages/*.tar.gz
./packages/checksums.txt
# 更新 Homebrew (稳定版发布时触发)
update-homebrew:
needs: release
runs-on: ubuntu-latest
if: github.event_name == 'release' && !contains(github.event.release.tag_name, '-')
steps:
- name: Checkout homebrew tap
uses: actions/checkout@v4
with:
repository: wjllance/homebrew-standx-cli
token: ${{ secrets.HOMEBREW_TAP_TOKEN || secrets.GITHUB_TOKEN }}
path: homebrew-tap
- name: Download source tarball
run: |
curl -L -o standx-cli.tar.gz "https://github.com/wjllance/standx-cli/archive/refs/tags/${{ github.event.release.tag_name }}.tar.gz"
SHA256=$(sha256sum standx-cli.tar.gz | cut -d' ' -f1)
echo "SHA256=$SHA256" >> $GITHUB_ENV
echo "VERSION=${{ github.event.release.tag_name }}" >> $GITHUB_ENV
- name: Update Homebrew formula
run: |
cd homebrew-tap
sed -i "s|url \"https://github.com/wjllance/standx-cli/archive/refs/tags/v.*.tar.gz\"|url \"https://github.com/wjllance/standx-cli/archive/refs/tags/${{ env.VERSION }}.tar.gz\"|" Formula/standx-cli.rb
sed -i "s|sha256 \"[^\"]*\"|sha256 \"${{ env.SHA256 }}\"|" Formula/standx-cli.rb
- name: Commit and push to tap
run: |
cd homebrew-tap
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git add Formula/standx-cli.rb
git commit -m "Update standx-cli to ${{ env.VERSION }}"
git push
注意: 需要 GitHub Token 有 workflow scope 才能推送 workflow 文件修改。
背景
当前发布 Pre-release 版本需要手动创建 GitHub Release,流程繁琐。建议实现推送 tag 时自动发布 Pre-release。
修改内容
1. 触发条件更新
在
on.push下添加 tag 触发:2. 新增
auto-prereleaseJob-(如-rc,-beta,-alpha)RELEASE_NOTES_{VERSION}.md作为 release notes3. Homebrew 更新优化
-)使用方式
推送 tag 即可自动发布 Pre-release:
GitHub Actions 会自动:
完整文件内容
注意: 需要 GitHub Token 有
workflowscope 才能推送 workflow 文件修改。