name: Release
on:
push:
tags:
- "v*"
env:
CARGO_TERM_COLOR: always
jobs:
create-release:
name: Create Release
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.get_version.outputs.version }}
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Get version from tag
id: get_version
run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Generate release notes
id: generate_notes
run: |
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
if [ -n "$PREV_TAG" ]; then
echo "## Changes since $PREV_TAG" > release_notes.md
echo "" >> release_notes.md
git log --pretty=format:"- %s (%h)" $PREV_TAG..HEAD >> release_notes.md
else
echo "## Initial Release" > release_notes.md
echo "" >> release_notes.md
echo "This is the first release of pgkv, a high-performance key-value store backed by PostgreSQL." >> release_notes.md
fi
echo "" >> release_notes.md
echo "## Features" >> release_notes.md
echo "- 🚀 High-performance PostgreSQL UNLOGGED tables" >> release_notes.md
echo "- 🔄 Runtime agnostic synchronous API" >> release_notes.md
echo "- 📦 Minimal dependencies (postgres + thiserror)" >> release_notes.md
echo "- ⏰ TTL support with configurable cleanup strategies" >> release_notes.md
echo "- 🔒 Atomic operations (CAS, increment)" >> release_notes.md
echo "- 📊 Batch operations for efficiency" >> release_notes.md
echo "" >> release_notes.md
echo "## Installation" >> release_notes.md
echo "" >> release_notes.md
echo '```toml' >> release_notes.md
echo "[dependencies]" >> release_notes.md
echo "pgkv = \"${{ steps.get_version.outputs.version }}\"" >> release_notes.md
echo '```' >> release_notes.md
- name: Create Release
uses: softprops/action-gh-release@v2
with:
name: Release ${{ steps.get_version.outputs.version }}
body_path: release_notes.md
draft: false
prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-crate:
name: Publish to crates.io
runs-on: ubuntu-latest
needs: create-release
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: pgkv_test
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v5
- name: Install Rust toolchain
run: |
rustup update stable
rustup default stable
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-stable-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-stable-
${{ runner.os }}-cargo-
- name: Verify version matches tag
run: |
CARGO_VERSION=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version')
TAG_VERSION="${{ needs.create-release.outputs.version }}"
if [ "$CARGO_VERSION" != "$TAG_VERSION" ]; then
echo "Version mismatch: Cargo.toml has $CARGO_VERSION, tag has $TAG_VERSION"
exit 1
fi
- name: Run tests
run: cargo test --all-features
env:
DATABASE_URL: postgresql://postgres:postgres@localhost/pgkv_test
- name: Check documentation
run: cargo doc --no-deps --all-features
- name: Publish to crates.io
run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}