name: Release
on:
push:
tags:
- "v*.*.*"
workflow_dispatch:
inputs:
version:
description: "Release version (e.g., v1.0.0)"
required: true
dry_run:
description: "Dry run (don't actually publish)"
type: boolean
default: false
permissions:
contents: write
id-token: write
env:
CARGO_TERM_COLOR: always
jobs:
validate:
name: Validate Release
runs-on: ubuntu-latest
outputs:
version: ${{ steps.get_version.outputs.version }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Get version from tag
id: get_version
env:
INPUT_VERSION: ${{ github.event.inputs.version }}
REF_NAME: ${{ github.ref_name }}
EVENT_NAME: ${{ github.event_name }}
run: |
if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
echo "version=$INPUT_VERSION" >> "$GITHUB_OUTPUT"
else
echo "version=$REF_NAME" >> "$GITHUB_OUTPUT"
fi
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install protobuf compiler
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq protobuf-compiler
- name: Verify Cargo.toml version matches tag
env:
TAG_VERSION: ${{ steps.get_version.outputs.version }}
run: |
CARGO_VERSION=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "inferadb") | .version')
TAG_VERSION_CLEAN="${TAG_VERSION#v}"
if [ "$CARGO_VERSION" != "$TAG_VERSION_CLEAN" ]; then
echo "Version mismatch: Cargo.toml has $CARGO_VERSION but tag is $TAG_VERSION_CLEAN"
exit 1
fi
echo "Version validated: $CARGO_VERSION"
- name: Run tests
run: cargo test --lib --all-features
- name: Check documentation builds
env:
RUSTDOCFLAGS: -D warnings
run: cargo doc --workspace --no-deps --all-features
create-release:
name: Create GitHub Release
needs: validate
runs-on: ubuntu-latest
if: github.event.inputs.dry_run != 'true'
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.validate.outputs.version }}
name: ${{ needs.validate.outputs.version }}
draft: false
prerelease: ${{ contains(needs.validate.outputs.version, '-') }}
generate_release_notes: true
publish:
name: Publish to crates.io
needs: [validate, create-release]
runs-on: ubuntu-latest
environment: release
if: github.event.inputs.dry_run != 'true'
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install protobuf compiler
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq protobuf-compiler
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
- name: Authenticate with crates.io
uses: rust-lang/crates-io-auth-action@v1
id: auth
- name: Publish inferadb-derive
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
run: |
if [ -d "inferadb-derive" ]; then
cd inferadb-derive
cargo publish --token "$CARGO_REGISTRY_TOKEN" --allow-dirty || echo "inferadb-derive may already be published"
cd ..
# Wait for crates.io to index
sleep 30
fi
- name: Publish inferadb
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
run: cargo publish --token "$CARGO_REGISTRY_TOKEN" --allow-dirty
docs:
name: Build Documentation
needs: [validate, publish]
runs-on: ubuntu-latest
if: github.event.inputs.dry_run != 'true'
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@nightly
- name: Install protobuf compiler
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq protobuf-compiler
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
- name: Build documentation
env:
RUSTDOCFLAGS: --cfg docsrs
run: cargo +nightly doc --workspace --no-deps --all-features
- name: Add index redirect
run: |
echo '<meta http-equiv="refresh" content="0; url=inferadb">' > target/doc/index.html
- name: Upload documentation artifact
uses: actions/upload-artifact@v6
with:
name: documentation
path: target/doc
retention-days: 30