Skip to content

Merge pull request #12 from saorsa-labs/release/v0.10.2 #7

Merge pull request #12 from saorsa-labs/release/v0.10.2

Merge pull request #12 from saorsa-labs/release/v0.10.2 #7

Workflow file for this run

# Release - Publish to crates.io
# Triggered by version tags (v*)
name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
version:
description: 'Version to release (e.g., v0.9.6)'
required: true
dry_run:
description: 'Dry run (no actual publish)'
type: boolean
default: false
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
validate:
name: Validate Release
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
version_number: ${{ steps.version.outputs.version_number }}
is_prerelease: ${{ steps.version.outputs.is_prerelease }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Extract version
id: version
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
VERSION="${{ github.event.inputs.version }}"
else
VERSION="${GITHUB_REF#refs/tags/}"
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
# Extract version number without 'v' prefix
VERSION_NUMBER="${VERSION#v}"
echo "version_number=$VERSION_NUMBER" >> $GITHUB_OUTPUT
# Check if pre-release
if [[ "$VERSION" =~ -(alpha|beta|rc) ]]; then
echo "is_prerelease=true" >> $GITHUB_OUTPUT
else
echo "is_prerelease=false" >> $GITHUB_OUTPUT
fi
echo "Version: $VERSION (number: $VERSION_NUMBER)"
- name: Validate version format
run: |
VERSION="${{ steps.version.outputs.version }}"
VERSION_REGEX="^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+(\.[0-9]+)?)?$"
if ! [[ "$VERSION" =~ $VERSION_REGEX ]]; then
echo "::error::Invalid version format: $VERSION"
exit 1
fi
- name: Check Cargo.toml version
run: |
CARGO_VERSION=$(grep "^version" Cargo.toml | head -1 | cut -d'"' -f2)
EXPECTED="${{ steps.version.outputs.version_number }}"
if [[ "$CARGO_VERSION" != "$EXPECTED" ]]; then
echo "::error::Cargo.toml version mismatch"
echo "::error::Expected $EXPECTED but found $CARGO_VERSION"
exit 1
fi
test:
name: Test Suite
needs: validate
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: Free disk space
run: |
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
sudo rm -rf /usr/local/share/boost
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y pkg-config libssl-dev build-essential protobuf-compiler
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-release-${{ hashFiles('**/Cargo.lock') }}
- name: Run tests
run: cargo test --lib --features "default,mocks,test-utils"
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run clippy
run: cargo clippy --all-features -- -D warnings
security-audit:
name: Security Audit
needs: validate
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Install cargo-audit
run: cargo install cargo-audit
- name: Run audit
run: cargo audit
publish-crate:
name: Publish to crates.io
needs: [validate, test, security-audit]
runs-on: ubuntu-latest
if: github.event.inputs.dry_run != 'true'
steps:
- uses: actions/checkout@v4
- name: Free disk space
run: |
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
sudo rm -rf /usr/local/share/boost
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y pkg-config libssl-dev build-essential protobuf-compiler
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-publish-${{ hashFiles('**/Cargo.lock') }}
- name: Verify crate
run: cargo publish --dry-run --allow-dirty
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}
run: cargo publish --no-verify --allow-dirty
release:
name: Create GitHub Release
needs: [validate, publish-crate]
runs-on: ubuntu-latest
permissions:
contents: write
if: github.event.inputs.dry_run != 'true'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate changelog
id: changelog
run: |
PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
if [ -z "$PREVIOUS_TAG" ]; then
echo "No previous tag found"
CHANGELOG="Initial release"
else
echo "Generating changelog from $PREVIOUS_TAG to HEAD"
CHANGELOG=$(git log --oneline "$PREVIOUS_TAG"..HEAD | head -50)
fi
{
echo 'changelog<<EOF'
echo "$CHANGELOG"
echo 'EOF'
} >> $GITHUB_OUTPUT
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.validate.outputs.version }}
draft: false
prerelease: ${{ needs.validate.outputs.is_prerelease }}
generate_release_notes: true
body: |
## saorsa-core ${{ needs.validate.outputs.version }}
### Installation
Add to your `Cargo.toml`:
```toml
[dependencies]
saorsa-core = "${{ needs.validate.outputs.version_number }}"
```
Or install via cargo:
```bash
cargo add saorsa-core
```
### What's Changed
${{ steps.changelog.outputs.changelog }}
---
See [crates.io](https://crates.io/crates/saorsa-core) for full documentation.