ci: add release workflow for crates.io publishing

- Automated publishing to crates.io on version tags
- Cross-platform binary builds
- GitHub release creation with artifacts
- Manual workflow dispatch support
This commit is contained in:
Stefano Amorelli
2025-08-16 17:21:41 +03:00
parent 765337f89d
commit 34cc3712b8

194
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,194 @@
name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
version:
description: 'Version to publish (e.g., 0.1.0)'
required: true
type: string
env:
CARGO_TERM_COLOR: always
jobs:
test:
name: Final Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Run tests
run: cargo test --all-features --release
- name: Check formatting
run: cargo fmt -- --check
- name: Run clippy
run: cargo clippy --all-features -- -D warnings
publish-crates-io:
name: Publish to crates.io
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: Verify version
run: |
# Extract version from Cargo.toml
CARGO_VERSION=$(grep -E "^version" Cargo.toml | head -1 | cut -d'"' -f2)
echo "Cargo.toml version: $CARGO_VERSION"
# For manual workflow dispatch
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
INPUT_VERSION="${{ github.event.inputs.version }}"
if [ "$CARGO_VERSION" != "$INPUT_VERSION" ]; then
echo "Error: Cargo.toml version ($CARGO_VERSION) doesn't match input version ($INPUT_VERSION)"
exit 1
fi
fi
# For tag push
if [ "${{ github.event_name }}" = "push" ]; then
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
if [ "$CARGO_VERSION" != "$TAG_VERSION" ]; then
echo "Error: Cargo.toml version ($CARGO_VERSION) doesn't match tag version ($TAG_VERSION)"
exit 1
fi
fi
- name: Check if version exists on crates.io
run: |
CRATE_NAME=$(grep -E "^name" Cargo.toml | head -1 | cut -d'"' -f2)
VERSION=$(grep -E "^version" Cargo.toml | head -1 | cut -d'"' -f2)
if cargo search "$CRATE_NAME" | grep -q "^$CRATE_NAME = \"$VERSION\""; then
echo "Version $VERSION already exists on crates.io"
exit 1
fi
- name: Build release
run: cargo build --release --all-features
- name: Package for crates.io
run: cargo package --all-features
- name: Publish to crates.io
run: cargo publish --all-features --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
create-github-release:
name: Create GitHub Release
needs: publish-crates-io
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: Build release binaries
run: |
cargo build --release --all-features
mkdir -p release
cp target/release/crabrl release/crabrl-linux-x64
chmod +x release/crabrl-linux-x64
- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: release/*
generate_release_notes: true
body: |
## Installation
### From crates.io
```bash
cargo install crabrl
```
### Download Binary
Download the pre-built binary for your platform from the assets below.
## What's Changed
See the full changelog below.
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
build-cross-platform:
name: Build ${{ matrix.target }}
needs: test
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact: crabrl-linux-x64
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
artifact: crabrl-linux-arm64
use-cross: true
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact: crabrl-windows-x64.exe
- os: macos-latest
target: x86_64-apple-darwin
artifact: crabrl-macos-x64
- os: macos-latest
target: aarch64-apple-darwin
artifact: crabrl-macos-arm64
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install cross
if: matrix.use-cross
run: cargo install cross
- name: Build
run: |
if [ "${{ matrix.use-cross }}" = "true" ]; then
cross build --release --target ${{ matrix.target }} --all-features
else
cargo build --release --target ${{ matrix.target }} --all-features
fi
shell: bash
- name: Package
run: |
mkdir -p release
if [ "${{ matrix.os }}" = "windows-latest" ]; then
cp target/${{ matrix.target }}/release/crabrl.exe release/${{ matrix.artifact }}
else
cp target/${{ matrix.target }}/release/crabrl release/${{ matrix.artifact }}
chmod +x release/${{ matrix.artifact }}
fi
shell: bash
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
path: release/${{ matrix.artifact }}