name: 🚀 Release & Publish
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+" - "v[0-9]+.[0-9]+.[0-9]+-*" concurrency:
group: release
cancel-in-progress: false
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
validate:
name: 🔍 Validate Release
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
version: ${{ steps.version.outputs.version }}
is_prerelease: ${{ steps.version.outputs.is_prerelease }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Extract version from tag
id: version
run: |
TAG="${GITHUB_REF#refs/tags/v}"
echo "version=${TAG}" >> "$GITHUB_OUTPUT"
if [[ "${TAG}" == *"-"* ]]; then
echo "is_prerelease=true" >> "$GITHUB_OUTPUT"
echo "📦 Prerelease version: ${TAG}"
else
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
echo "📦 Release version: $TAG"
fi
- name: Verify version matches Cargo.toml
run: |
CARGO_VERSION=$(grep '^version = ' Cargo.toml | head -1 | cut -d '"' -f 2)
TAG_VERSION="${{ steps.version.outputs.version }}"
echo "📋 Tag version: $TAG_VERSION"
echo "📋 Cargo.toml version: $CARGO_VERSION"
if [[ "$CARGO_VERSION" != "$TAG_VERSION" ]]; then
echo "❌ Version mismatch!"
echo " Tag: v$TAG_VERSION"
echo " Cargo.toml: $CARGO_VERSION"
exit 1
fi
echo "✅ Versions match!"
build:
name: 🔨 Build & Test
runs-on: ubuntu-latest
needs: validate
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
components: rustfmt, clippy
- name: Cache dependencies
uses: Swatinem/rust-cache@v2
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run clippy
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Run tests
run: cargo test --tests --all-features
- name: Build release
run: cargo build --release --all-features
- name: Verify package
run: cargo publish --dry-run
publish:
name: 📤 Publish to crates.io
runs-on: ubuntu-latest
needs: [validate, build]
permissions:
contents: read
environment:
name: crates-io
url: https://crates.io/crates/streamweave
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
echo "🚀 Publishing v${{ needs.validate.outputs.version }} to crates.io..."
cargo publish
echo "✅ Published successfully!"
release:
name: 🎉 Create GitHub Release
runs-on: ubuntu-latest
needs: [validate, publish]
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Generate changelog
id: changelog
run: |
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
{
echo "## What's Changed"
echo ""
if [[ -n "${PREV_TAG}" ]]; then
echo "Changes since ${PREV_TAG}:"
echo ""
git log --pretty=format:"* %s (%h)" "${PREV_TAG}"..HEAD
else
echo "Initial release! 🎉"
fi
echo ""
echo ""
echo "---"
echo ""
} > CHANGELOG.md
{
echo "📦 **Install from crates.io:**"
echo '```toml'
echo '[dependencies]'
echo 'streamweave = "${{ needs.validate.outputs.version }}"'
echo '```'
echo ""
echo "📚 **Documentation:** [docs.rs/streamweave](https://docs.rs/streamweave)"
} >> CHANGELOG.md
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
name: v${{ needs.validate.outputs.version }}
body_path: CHANGELOG.md
draft: false
prerelease: ${{ needs.validate.outputs.is_prerelease == 'true' }}
generate_release_notes: true
make_latest: ${{ needs.validate.outputs.is_prerelease != 'true' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
docs:
name: 📚 Publish Documentation
runs-on: ubuntu-latest
needs: [validate, publish]
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Cache dependencies
uses: Swatinem/rust-cache@v2
- name: Generate documentation
run: |
echo "📚 Generating documentation..."
./bin/docs
notify:
name: 📢 Release Complete
runs-on: ubuntu-latest
needs: [validate, publish, release, docs]
if: always()
steps:
- name: Check release status
run: |
if [[ "${{ needs.publish.result }}" != "success" ]]; then
echo "❌ Release failed at publish step"
exit 1
fi
echo "🎉 StreamWeave v${{ needs.validate.outputs.version }} released!"
echo ""
echo "📦 crates.io: https://crates.io/crates/streamweave/${{ needs.validate.outputs.version }}"
echo "📚 docs.rs: https://docs.rs/streamweave/${{ needs.validate.outputs.version }}"