Skip to content

Release

Release #3

Workflow file for this run

# =============================================================================
# ToonDB Python SDK Release Pipeline
# =============================================================================
#
# WORKFLOW FLOW:
#
# ┌─────────────────────────────────────────────────────────────────┐
# │ 1. Download binaries from toondb/toondb + Build (PARALLEL) │
# ├─────────────────────────────────────────────────────────────────┤
# │ ├─ build-wheel (Linux x86_64) → downloads binary + builds │
# │ ├─ build-wheel (macOS ARM64) → downloads binary + builds │
# │ ├─ build-wheel (Windows x64) → downloads binary + builds │
# │ └─ build-sdist → builds source distribution │
# └─────────────────────────────────────────────────────────────────┘
# ↓
# ┌─────────────────────────────────────────────────────────────────┐
# │ 2. Publish packages (PARALLEL) │
# ├─────────────────────────────────────────────────────────────────┤
# │ ├─ create-release → Creates GitHub release + attaches wheels │
# │ └─ publish → Uploads wheels to PyPI │
# └─────────────────────────────────────────────────────────────────┘
# ↓
# ┌─────────────────────────────────────────────────────────────────┐
# │ 3. summary → Shows comprehensive status │
# └─────────────────────────────────────────────────────────────────┘
#
# This workflow packages pre-built ToonDB binaries into Python wheels.
#
# IMPORTANT: This SDK pulls pre-compiled binaries from the main ToonDB
# repository (toondb/toondb) and wraps them in Python wheels. Each wheel
# contains platform-specific binaries:
# - toondb-bulk (CLI tool for bulk operations)
# - toondb-server (standalone server)
# - toondb-grpc-server (gRPC server)
# - libtoondb_storage.* (FFI library)
# - libtoondb_index.* (FFI library)
#
# The version input MUST match an existing release in toondb/toondb repo.
#
# Platforms supported:
# - Linux x86_64 (manylinux_2_17)
# - macOS ARM64 (Apple Silicon)
# - Windows x64
#
# Python versions supported: 3.9, 3.10, 3.11, 3.12, 3.13
#
# =============================================================================
# REQUIRED SETUP:
# =============================================================================
#
# PyPI - NO TOKEN NEEDED!
# Uses OIDC Trusted Publisher (configure at PyPI project settings)
# https://pypi.org/manage/project/toondb-client/settings/publishing/
#
# GitHub Releases - Requires write permission
# Uses GITHUB_TOKEN with contents: write permission
#
# =============================================================================
name: Release
on:
workflow_dispatch:
inputs:
version:
description: 'Release version (e.g., 0.3.1) - MUST match an existing toondb/toondb release tag'
required: true
type: string
toondb_version:
description: 'ToonDB binary version (defaults to same as version if not specified)'
required: false
type: string
dry_run:
description: 'Dry run (validate without publishing)'
required: false
default: false
type: boolean
env:
TOONDB_REPO: toondb/toondb
jobs:
# ===========================================================================
# Build Python Wheels (All Platforms)
# ===========================================================================
build-wheel:
name: Build Wheel (${{ matrix.target }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
wheel_platform: manylinux_2_17_x86_64
archive_ext: tar.gz
- os: macos-latest
target: aarch64-apple-darwin
wheel_platform: macosx_11_0_arm64
archive_ext: tar.gz
- os: windows-latest
target: x86_64-pc-windows-msvc
wheel_platform: win_amd64
archive_ext: zip
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Create directory structure
shell: bash
run: |
mkdir -p src/toondb/_bin/${{ matrix.target }}
mkdir -p src/toondb/lib/${{ matrix.target }}
- name: Download binaries from main ToonDB release
shell: bash
run: |
# Use toondb_version if provided, otherwise use version
VERSION="${{ inputs.toondb_version }}"
if [ -z "$VERSION" ]; then
VERSION="${{ inputs.version }}"
fi
TAG="v${VERSION}"
TARGET="${{ matrix.target }}"
if [ "${{ matrix.archive_ext }}" = "zip" ]; then
ASSET_NAME="toondb-${VERSION}-${TARGET}.zip"
else
ASSET_NAME="toondb-${VERSION}-${TARGET}.tar.gz"
fi
DOWNLOAD_URL="https://github.com/${{ env.TOONDB_REPO }}/releases/download/${TAG}/${ASSET_NAME}"
echo "Downloading ToonDB binaries from main repository:"
echo " Repository: ${{ env.TOONDB_REPO }}"
echo " Version: ${VERSION}"
echo " URL: $DOWNLOAD_URL"
curl -L -f -o release-archive.${{ matrix.archive_ext }} "$DOWNLOAD_URL"
# Extract the archive
if [ "${{ matrix.archive_ext }}" = "zip" ]; then
unzip -o release-archive.zip
else
tar -xzf release-archive.tar.gz
fi
ls -la
ls -la ${TARGET}/ || true
- name: Copy binaries and libraries to SDK (Unix)
if: matrix.os != 'windows-latest'
shell: bash
run: |
TARGET="${{ matrix.target }}"
# Copy binaries to _bin/
cp ${TARGET}/toondb-bulk src/toondb/_bin/${TARGET}/ 2>/dev/null || \
find . -maxdepth 2 -name "toondb-bulk" -type f -exec cp {} src/toondb/_bin/${TARGET}/ \;
cp ${TARGET}/toondb-server src/toondb/_bin/${TARGET}/ 2>/dev/null || \
find . -maxdepth 2 -name "toondb-server" -type f -exec cp {} src/toondb/_bin/${TARGET}/ \;
cp ${TARGET}/toondb-grpc-server src/toondb/_bin/${TARGET}/ 2>/dev/null || \
find . -maxdepth 2 -name "toondb-grpc-server" -type f -exec cp {} src/toondb/_bin/${TARGET}/ \;
# Copy shared libraries to lib/
cp ${TARGET}/libtoondb_storage* src/toondb/lib/${TARGET}/ 2>/dev/null || \
find . -maxdepth 2 -name "libtoondb_storage*" -type f -exec cp {} src/toondb/lib/${TARGET}/ \;
cp ${TARGET}/libtoondb_index* src/toondb/lib/${TARGET}/ 2>/dev/null || \
find . -maxdepth 2 -name "libtoondb_index*" -type f -exec cp {} src/toondb/lib/${TARGET}/ \;
# Make executables
chmod +x src/toondb/_bin/${TARGET}/* 2>/dev/null || true
chmod +x src/toondb/lib/${TARGET}/* 2>/dev/null || true
echo "=== Binaries ==="
ls -la src/toondb/_bin/${TARGET}/
echo "=== Libraries ==="
ls -la src/toondb/lib/${TARGET}/
- name: Copy binaries and libraries to SDK (Windows)
if: matrix.os == 'windows-latest'
shell: bash
run: |
TARGET="${{ matrix.target }}"
# Copy binaries to _bin/ (no toondb-server on Windows)
cp ${TARGET}/toondb-bulk.exe src/toondb/_bin/${TARGET}/ 2>/dev/null || \
find . -maxdepth 2 -name "toondb-bulk.exe" -type f -exec cp {} src/toondb/_bin/${TARGET}/ \;
cp ${TARGET}/toondb-grpc-server.exe src/toondb/_bin/${TARGET}/ 2>/dev/null || \
find . -maxdepth 2 -name "toondb-grpc-server.exe" -type f -exec cp {} src/toondb/_bin/${TARGET}/ \;
# Copy shared libraries (DLLs) to lib/
cp ${TARGET}/toondb_storage.dll src/toondb/lib/${TARGET}/ 2>/dev/null || \
find . -maxdepth 2 -name "toondb_storage.dll" -type f -exec cp {} src/toondb/lib/${TARGET}/ \;
cp ${TARGET}/toondb_index.dll src/toondb/lib/${TARGET}/ 2>/dev/null || \
find . -maxdepth 2 -name "toondb_index.dll" -type f -exec cp {} src/toondb/lib/${TARGET}/ \;
echo "=== Binaries ==="
ls -la src/toondb/_bin/${TARGET}/
echo "=== Libraries ==="
ls -la src/toondb/lib/${TARGET}/
- name: Update package version
shell: bash
run: |
sed -i.bak 's/version = ".*"/version = "${{ inputs.version }}"/' pyproject.toml
rm -f pyproject.toml.bak
grep "version" pyproject.toml | head -1
- name: Build wheel
run: |
pip install build wheel
python -m build --wheel
- name: Rename wheel with correct platform tag
shell: bash
run: |
cd dist
for f in *-py3-none-any.whl; do
if [ -f "$f" ]; then
newname=$(echo $f | sed 's/-py3-none-any/-py3-none-${{ matrix.wheel_platform }}/')
mv "$f" "$newname"
fi
done
ls -la
- name: Upload wheel artifact
uses: actions/upload-artifact@v4
with:
name: wheel-${{ matrix.target }}
path: dist/*.whl
retention-days: 5
# ===========================================================================
# Build Source Distribution
# ===========================================================================
build-sdist:
name: Build Source Distribution
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Update package version
run: |
sed -i 's/version = ".*"/version = "${{ inputs.version }}"/' pyproject.toml
- name: Build sdist
run: |
pip install build
python -m build --sdist
- name: Upload sdist artifact
uses: actions/upload-artifact@v4
with:
name: sdist
path: dist/*.tar.gz
retention-days: 5
# ===========================================================================
# Create GitHub Release
# ===========================================================================
create-release:
name: Create GitHub Release
runs-on: ubuntu-latest
needs: [build-wheel, build-sdist]
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: dist/
merge-multiple: true
- name: List release packages
run: |
echo "=== Packages for release ==="
ls -la dist/
echo ""
echo "Total packages: $(ls dist/ | wc -l)"
- name: Generate release notes
id: release_notes
run: |
cat > release_notes.md << 'EOF'
## ToonDB Python SDK v${{ inputs.version }}
Python SDK wrapping pre-built binaries from [toondb/toondb v${{ inputs.toondb_version || inputs.version }}](https://github.com/toondb/toondb/releases/tag/v${{ inputs.toondb_version || inputs.version }})
### Installation
```bash
pip install toondb-client==${{ inputs.version }}
```
### What's Included
This release contains platform-specific wheels with pre-compiled ToonDB binaries:
- **toondb-bulk**: CLI tool for bulk data operations
- **toondb-server**: Standalone database server
- **toondb-grpc-server**: gRPC server implementation
- **libtoondb_storage**: Native storage FFI library
- **libtoondb_index**: Native indexing FFI library
### Supported Platforms
- ✅ **Linux x86_64** (manylinux_2_17_x86_64)
- ✅ **macOS ARM64** (Apple Silicon, macosx_11_0_arm64)
- ✅ **Windows x64** (win_amd64)
### Python Version Support
- Python 3.9
- Python 3.10
- Python 3.11
- Python 3.12
- Python 3.13
### Package Contents
Each wheel includes:
- Python SDK code (`toondb` package)
- Platform-specific binaries in `_bin/<platform>/`
- Shared libraries in `lib/<platform>/`
### Source Distribution
The source distribution (`.tar.gz`) is also available for custom builds, though binaries are not included and would need to be obtained separately from the main ToonDB repository.
---
**Binary Source**: These Python wheels bundle pre-compiled binaries from the [ToonDB main repository](https://github.com/toondb/toondb) release v${{ inputs.toondb_version || inputs.version }}.
EOF
- name: Create GitHub Release
if: ${{ inputs.dry_run != true }}
uses: softprops/action-gh-release@v1
with:
tag_name: v${{ inputs.version }}
name: Release v${{ inputs.version }}
body_path: release_notes.md
draft: false
prerelease: false
files: dist/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Dry run - show what would be released
if: ${{ inputs.dry_run == true }}
run: |
echo "🔍 Dry run mode - GitHub release would be created with:"
echo ""
cat release_notes.md
echo ""
echo "=== Files to attach ==="
ls -lh dist/
# ===========================================================================
# Publish to PyPI (parallel with GitHub release creation)
# ===========================================================================
publish:
name: Publish to PyPI
runs-on: ubuntu-latest
needs: [build-wheel, build-sdist]
# Required for PyPI Trusted Publisher (OIDC) - no token needed!
permissions:
id-token: write
contents: read
steps:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: dist/
merge-multiple: true
- name: List packages
run: |
echo "=== Packages to upload ==="
ls -la dist/
if [ -z "$(ls -A dist/)" ]; then
echo "ERROR: No Python packages found!"
exit 1
fi
- name: Validate packages
run: |
pip install twine
twine check dist/*
- name: Publish to PyPI (Trusted Publisher)
if: ${{ inputs.dry_run != true }}
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/
skip-existing: true
verbose: true
- name: Dry run validation
if: ${{ inputs.dry_run == true }}
run: |
echo "🔍 Dry run - packages validated but not uploaded"
echo "Packages:"
ls -la dist/
# ===========================================================================
# Release Summary
# ===========================================================================
summary:
name: Release Summary
runs-on: ubuntu-latest
needs: [build-wheel, build-sdist, create-release, publish]
if: always()
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: dist/
merge-multiple: true
- name: Generate comprehensive summary
run: |
echo "## 🎉 ToonDB Python SDK v${{ inputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ inputs.dry_run }}" = "true" ]; then
echo "**Mode:** 🧪 Dry Run (validation only - nothing published)" >> $GITHUB_STEP_SUMMARY
else
echo "**Mode:** 🚀 Production Release" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📦 Binary Source" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
TOONDB_VERSION="${{ inputs.toondb_version }}"
if [ -z "$TOONDB_VERSION" ]; then
TOONDB_VERSION="${{ inputs.version }}"
fi
echo "**Binaries pulled from:** [toondb/toondb v${TOONDB_VERSION}](https://github.com/${{ env.TOONDB_REPO }}/releases/tag/v${TOONDB_VERSION})" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "This Python SDK wraps pre-compiled binaries from the main ToonDB repository." >> $GITHUB_STEP_SUMMARY
echo "Each wheel contains platform-specific:" >> $GITHUB_STEP_SUMMARY
echo "- \`toondb-bulk\`, \`toondb-server\`, \`toondb-grpc-server\` (executables)" >> $GITHUB_STEP_SUMMARY
echo "- \`libtoondb_storage.*\`, \`libtoondb_index.*\` (FFI libraries)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📥 Installation" >> $GITHUB_STEP_SUMMARY
echo '```bash' >> $GITHUB_STEP_SUMMARY
echo "pip install toondb-client==${{ inputs.version }}" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 🐍 Python Version Support" >> $GITHUB_STEP_SUMMARY
echo "Python 3.9 | 3.10 | 3.11 | 3.12 | 3.13" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 💻 Platform Support" >> $GITHUB_STEP_SUMMARY
echo "| Platform | Wheel Tag | Status |" >> $GITHUB_STEP_SUMMARY
echo "|----------|-----------|--------|" >> $GITHUB_STEP_SUMMARY
echo "| Linux x86_64 | manylinux_2_17_x86_64 | ✅ Built |" >> $GITHUB_STEP_SUMMARY
echo "| macOS ARM64 | macosx_11_0_arm64 | ✅ Built |" >> $GITHUB_STEP_SUMMARY
echo "| Windows x64 | win_amd64 | ✅ Built |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📦 Packages Created" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
ls -lh dist/ | tail -n +2 | awk '{printf "%-8s %s\n", $5, $9}'
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### ✅ Build Status" >> $GITHUB_STEP_SUMMARY
echo "| Job | Result |" >> $GITHUB_STEP_SUMMARY
echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY
function status_icon() {
case "$1" in
success) echo "✅ Success" ;;
failure) echo "❌ Failed" ;;
cancelled) echo "⏸️ Cancelled" ;;
skipped) echo "⏭️ Skipped" ;;
*) echo "❔ $1" ;;
esac
}
echo "| Build Wheels | $(status_icon '${{ needs.build-wheel.result }}') |" >> $GITHUB_STEP_SUMMARY
echo "| Build Source Dist | $(status_icon '${{ needs.build-sdist.result }}') |" >> $GITHUB_STEP_SUMMARY
echo "| Create GitHub Release | $(status_icon '${{ needs.create-release.result }}') |" >> $GITHUB_STEP_SUMMARY
echo "| Publish to PyPI | $(status_icon '${{ needs.publish.result }}') |" >> $GITHUB_STEP_SUMMARY
if [ "${{ inputs.dry_run }}" != "true" ]; then
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 🔗 Links" >> $GITHUB_STEP_SUMMARY
echo "- 📦 [PyPI Package](https://pypi.org/project/toondb-client/${{ inputs.version }}/)" >> $GITHUB_STEP_SUMMARY
echo "- 🏷️ [GitHub Release](https://github.com/${{ github.repository }}/releases/tag/v${{ inputs.version }})" >> $GITHUB_STEP_SUMMARY
echo "- 🔧 [Source Binaries](https://github.com/${{ env.TOONDB_REPO }}/releases/tag/v${TOONDB_VERSION})" >> $GITHUB_STEP_SUMMARY
fi