name: Release
on:
push:
branches: [main]
paths:
- "src/**"
- "Cargo.toml"
- "Cargo.lock"
- ".github/workflows/release.yml"
workflow_dispatch:
inputs:
version_bump:
description: "版本递增类型(push 自动触发时固定为 patch)"
type: choice
default: patch
options:
- patch
- minor
- major
publish:
description: "是否发布到 crates.io(需仓库配置 CARGO_REGISTRY_TOKEN secret)"
type: boolean
default: true
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Bump version
id: next_version
run: |
KIND="${{ github.event.inputs.version_bump || 'patch' }}"
[ -z "$KIND" ] && KIND=patch
VER="$(grep -m1 '^version' Cargo.toml | cut -d '"' -f2)"
IFS=. read -r MAJ MIN PAT <<< "$VER"
if [ "$KIND" = "major" ]; then MAJ=$((MAJ+1)); MIN=0; PAT=0
elif [ "$KIND" = "minor" ]; then MIN=$((MIN+1)); PAT=0
else PAT=$((PAT+1)); fi
NV="$MAJ.$MIN.$PAT"
sed -i "s/^version = .*/version = \"$NV\"/" Cargo.toml
cargo metadata --no-deps --format-version 1 >/dev/null
echo "version=$NV" >> "$GITHUB_OUTPUT"
- name: Commit and tag
if: steps.next_version.outputs.version != ''
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add Cargo.toml
# Cargo.lock 被 .gitignore 忽略(库 crate 惯例,不随 checkout 存在):
# 存在才 add(cargo metadata 会在本地生成它),不存在则跳过
git add Cargo.lock 2>/dev/null || true
git commit -m "release: v${{ steps.next_version.outputs.version }} [skip ci]"
git tag "v${{ steps.next_version.outputs.version }}"
git push origin HEAD:main
git push origin "v${{ steps.next_version.outputs.version }}"
- name: Package verify
run: cargo package --allow-dirty
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: cargo publish --registry crates-io
if: |
env.CARGO_REGISTRY_TOKEN != '' &&
(
(github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true') ||
(github.event_name == 'push' && contains(github.event.head_commit.message, '[publish]'))
)
- name: Build demo binary
run: cargo build --release --example demo
- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "v${{ steps.next_version.outputs.version }}" \
--repo "${{ github.repository }}" \
--title "v${{ steps.next_version.outputs.version }}" \
--generate-notes \
target/package/multiavatar-*.crate \
target/release/examples/demo