name: Release
on:
push:
branches: [master, develop]
tags:
- 'v*'
pull_request:
branches: [master, develop]
env:
CARGO_TERM_COLOR: always
jobs:
test:
name: Test & Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Install protoc
run: |
sudo apt-get update
sudo apt-get install -y protobuf-compiler
- name: Cache cargo
uses: Swatinem/rust-cache@v2
- name: Check formatting
run: cargo fmt -- --check
- name: Run clippy
run: cargo clippy -- -D warnings
- name: Run tests
run: cargo test --all-features
- name: Run doc tests
run: cargo test --doc
pre-publish-check:
name: Pre-Publish Checklist
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install protoc
run: |
sudo apt-get update
sudo apt-get install -y protobuf-compiler
- name: ✅ Check Cargo.toml metadata
run: |
echo "Checking Cargo.toml metadata..."
for field in name version description license repository; do
if ! grep -q "^$field = " Cargo.toml; then
echo "❌ Missing required field: $field"
exit 1
fi
echo " ✅ $field present"
done
CARGO_VERSION=$(grep "^version = " Cargo.toml | head -1 | cut -d'"' -f2)
TAG_VERSION=${GITHUB_REF#refs/tags/v}
if [ "$CARGO_VERSION" != "$TAG_VERSION" ]; then
echo "❌ Version mismatch: Cargo.toml ($CARGO_VERSION) != Tag ($TAG_VERSION)"
exit 1
fi
echo " ✅ Version matches tag: $CARGO_VERSION"
- name: ✅ Check LICENSE file
run: |
LICENSE_TYPE=$(grep "^license = " Cargo.toml | cut -d'"' -f2)
echo "Declared license: $LICENSE_TYPE"
if [ ! -f "LICENSE" ] && [ ! -f "LICENSE.txt" ] && [ ! -f "LICENSE-MIT" ]; then
echo "❌ LICENSE file not found"
exit 1
fi
echo " ✅ LICENSE file exists"
- name: ✅ Check for uncommitted changes
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "❌ Uncommitted changes detected:"
git status --short
exit 1
fi
echo " ✅ No uncommitted changes"
- name: ✅ Verify package
run: |
echo "Running cargo package --allow-dirty..."
cargo package --allow-dirty --no-verify 2>&1 | head -20
echo " ✅ Package structure valid"
- name: ✅ Check exclude patterns
run: |
echo "Checking exclude patterns..."
CHECK_PATTERNS="benchmark testdata scripts docs .github benches"
for pattern in $CHECK_PATTERNS; do
if grep -q "exclude.*=.*\".*$pattern" Cargo.toml || \
grep -q "exclude.*=.*\[.*\".*$pattern" Cargo.toml; then
echo " ✅ $pattern is excluded"
else
if [ -d "$pattern" ]; then
echo "⚠️ $pattern directory exists but not excluded in Cargo.toml"
fi
fi
done
build:
name: Build Binaries
needs: test
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/tags/v')
strategy:
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
- target: x86_64-apple-darwin
os: macos-latest
- target: aarch64-apple-darwin
os: macos-latest
- target: x86_64-pc-windows-msvc
os: windows-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install protoc (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y protobuf-compiler
- name: Install protoc (macOS)
if: matrix.os == 'macos-latest'
run: brew install protobuf
- name: Install protoc (Windows)
if: matrix.os == 'windows-latest'
run: choco install protoc
- name: Cache cargo
uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}
- name: Build release binary
run: cargo build --release --target ${{ matrix.target }}
- name: Package binary (Unix)
if: matrix.os != 'windows-latest'
run: |
cd target/${{ matrix.target }}/release
tar czvf ../../../wootype-${{ matrix.target }}.tar.gz wootype-daemon
cd -
- name: Package binary (Windows)
if: matrix.os == 'windows-latest'
run: |
cd target/${{ matrix.target }}/release
7z a ../../../wootype-${{ matrix.target }}.zip wootype-daemon.exe
cd -
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: wootype-${{ matrix.target }}
path: |
wootype-*.tar.gz
wootype-*.zip
publish-crate:
name: Publish to crates.io
needs: [test, pre-publish-check, build]
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install protoc
run: |
sudo apt-get update
sudo apt-get install -y protobuf-compiler
- name: Cache cargo
uses: Swatinem/rust-cache@v2
- name: Verify package
run: cargo package --allow-dirty
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
if [ -z "$CARGO_REGISTRY_TOKEN" ]; then
echo "⚠️ CARGO_REGISTRY_TOKEN not configured, skipping publish"
exit 0
fi
cargo publish --allow-dirty
release:
name: Create GitHub Release
needs: build
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
pattern: wootype-*
- name: Generate changelog
id: changelog
run: |
echo "changelog<<EOF" >> $GITHUB_OUTPUT
git log --pretty=format:"- %s (%h)" $(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo HEAD~10)..HEAD >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Create Release
uses: softprops/action-gh-release@v1
with:
body: |
## Changes
${{ steps.changelog.outputs.changelog }}
## Installation
```bash
cargo install wootype
```
Or download the binary for your platform below.
files: artifacts/**/*.tar.gz,artifacts/**/*.zip
draft: false
prerelease: ${{ contains(github.ref, '-alpha') || contains(github.ref, '-beta') || contains(github.ref, '-rc') }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
version-check:
name: Version Check
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check version bump
run: |
CURRENT_VERSION=$(grep "^version" Cargo.toml | head -1 | cut -d'"' -f2)
git fetch origin master
MAIN_VERSION=$(git show origin/master:Cargo.toml 2>/dev/null | grep "^version" | head -1 | cut -d'"' -f2 || echo "0.0.0")
echo "Current PR version: $CURRENT_VERSION"
echo "Main branch version: $MAIN_VERSION"
if [ "$CURRENT_VERSION" = "$MAIN_VERSION" ]; then
echo "⚠️ Warning: Version not bumped. Consider updating version in Cargo.toml"
else
echo "✅ Version bumped from $MAIN_VERSION to $CURRENT_VERSION"
fi