Skip to content

feat: add Rust implementation and reorganize codebase #6

feat: add Rust implementation and reorganize codebase

feat: add Rust implementation and reorganize codebase #6

Workflow file for this run

name: Rust Checks and Release
on:
push:
branches:
- main
paths:
- 'rust/**'
- '.github/workflows/rust.yml'
pull_request:
types: [opened, synchronize, reopened]
paths:
- 'rust/**'
- '.github/workflows/rust.yml'
workflow_dispatch:
inputs:
release_mode:
description: 'Manual release mode'
required: true
type: choice
default: 'instant'
options:
- instant
bump_type:
description: 'Manual release type'
required: true
type: choice
options:
- patch
- minor
- major
description:
description: 'Manual release description (optional)'
required: false
type: string
concurrency: ${{ github.workflow }}-${{ github.ref }}
defaults:
run:
working-directory: rust
jobs:
# Linting and formatting
lint:
name: Rust - Lint and Format Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
rust/target
key: ${{ runner.os }}-cargo-${{ hashFiles('rust/Cargo.lock') }}
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run Clippy
run: cargo clippy --all-targets --all-features -- -D warnings
# Test matrix: Rust on multiple OS
test:
name: Rust - Test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
rust/target
key: ${{ runner.os }}-cargo-${{ hashFiles('rust/Cargo.lock') }}
- name: Run tests
run: cargo test --all-features
# Build check
build:
name: Rust - Build
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
rust/target
key: ${{ runner.os }}-cargo-${{ hashFiles('rust/Cargo.lock') }}
- name: Build release
run: cargo build --release
- name: Build Docker image
run: docker build -t web-capture-rust .
# Release - only runs on main after tests pass (for push events)
release:
name: Rust - Release
needs: [lint, test, build]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
rust/target
key: ${{ runner.os }}-cargo-${{ hashFiles('rust/Cargo.lock') }}
- name: Check if version changed
id: version_check
run: |
# Get current version from Cargo.toml
CURRENT_VERSION=$(grep -m1 '^version' Cargo.toml | sed 's/.*"\(.*\)".*/\1/')
echo "Current version: $CURRENT_VERSION"
# Check if tag exists
if git rev-parse "rust-v$CURRENT_VERSION" >/dev/null 2>&1; then
echo "Tag rust-v$CURRENT_VERSION already exists"
echo "should_release=false" >> $GITHUB_OUTPUT
else
echo "Tag rust-v$CURRENT_VERSION does not exist, will release"
echo "should_release=true" >> $GITHUB_OUTPUT
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
fi
- name: Publish to crates.io
if: steps.version_check.outputs.should_release == 'true'
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
cargo publish --allow-dirty || echo "Publish failed or already published"
- name: Create GitHub Release
if: steps.version_check.outputs.should_release == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ steps.version_check.outputs.version }}"
gh release create "rust-v$VERSION" \
--title "Rust v$VERSION" \
--notes "Rust web-capture version $VERSION" \
--target ${{ github.sha }}
# Manual Instant Release
instant-release:
name: Rust - Instant Release
if: github.event_name == 'workflow_dispatch' && github.event.inputs.release_mode == 'instant'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
rust/target
key: ${{ runner.os }}-cargo-${{ hashFiles('rust/Cargo.lock') }}
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Bump version
id: bump
run: |
# Get current version
CURRENT=$(grep -m1 '^version' Cargo.toml | sed 's/.*"\(.*\)".*/\1/')
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT"
# Bump based on type
case "${{ github.event.inputs.bump_type }}" in
major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0 ;;
minor) MINOR=$((MINOR + 1)); PATCH=0 ;;
patch) PATCH=$((PATCH + 1)) ;;
esac
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
echo "New version: $NEW_VERSION"
# Update Cargo.toml
sed -i "s/^version = \"$CURRENT\"/version = \"$NEW_VERSION\"/" Cargo.toml
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
- name: Commit version bump
run: |
git add Cargo.toml
git commit -m "chore(rust): bump version to ${{ steps.bump.outputs.version }}"
git push
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
cargo publish --allow-dirty || echo "Publish failed or already published"
- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ steps.bump.outputs.version }}"
DESCRIPTION="${{ github.event.inputs.description || 'Manual release' }}"
gh release create "rust-v$VERSION" \
--title "Rust v$VERSION" \
--notes "$DESCRIPTION" \
--target ${{ github.sha }}