name: Release on: workflow_dispatch: inputs: version: description: 'Version to release (e.g., 0.1.2)' required: true type: string jobs: update-version: name: Update Version runs-on: ubuntu-latest outputs: commit-sha: ${{ steps.push.outputs.commit-sha }} steps: - uses: actions/checkout@v4 with: token: ${{ secrets.GITHUB_TOKEN }} - name: Validate version run: | if ! [[ "${{ inputs.version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "❌ Invalid version format" exit 1 fi echo "✅ Version format valid" - name: Update versions and push id: push run: | ./scripts/bump_version.sh ${{ inputs.version }} git config user.name "GitHub Actions" git config user.email "actions@github.com" git add packages/*/pyproject.toml git commit -m "chore: release v${{ inputs.version }}" git push origin main COMMIT_SHA=$(git rev-parse HEAD) echo "commit-sha=$COMMIT_SHA" >> $GITHUB_OUTPUT echo "✅ Pushed version update: $COMMIT_SHA" build-packages: name: Build packages needs: update-version strategy: matrix: include: - os: ubuntu-latest python: '3.11' - os: macos-latest python: '3.11' runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 with: ref: ${{ needs.update-version.outputs.commit-sha }} submodules: recursive - name: Setup Python uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} - name: Install uv uses: astral-sh/setup-uv@v4 - name: Install system dependencies (Ubuntu) if: runner.os == 'Linux' run: | sudo apt-get update sudo apt-get install -y libomp-dev libboost-all-dev protobuf-compiler libzmq3-dev - name: Install system dependencies (macOS) if: runner.os == 'macOS' run: | brew install llvm libomp boost protobuf zeromq - name: Build packages run: | # Build core (platform independent) if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then cd packages/leann-core uv build cd ../.. fi # Build HNSW backend cd packages/leann-backend-hnsw uv pip install --system -r pyproject.toml --extra build CC=$(brew --prefix llvm)/bin/clang CXX=$(brew --prefix llvm)/bin/clang++ uv build cd ../.. # Build DiskANN backend cd packages/leann-backend-diskann uv pip install --system -r pyproject.toml --extra build CC=$(brew --prefix llvm)/bin/clang CXX=$(brew --prefix llvm)/bin/clang++ uv build cd ../.. # Build meta package (platform independent) if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then cd packages/leann uv build cd ../.. fi echo "📦 Built packages:" find packages/*/dist -name "*.whl" -o -name "*.tar.gz" | sort env: CC: ${{ runner.os == 'macOS' && '$(brew --prefix llvm)/bin/clang' || '' }} CXX: ${{ runner.os == 'macOS' && '$(brew --prefix llvm)/bin/clang++' || '' }} - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: packages-${{ matrix.os }}-${{ matrix.python }} path: packages/*/dist/ publish: name: Publish and Release needs: build-packages runs-on: ubuntu-latest permissions: contents: write steps: - uses: actions/checkout@v4 with: ref: ${{ needs.update-version.outputs.commit-sha }} - name: Download all artifacts uses: actions/download-artifact@v4 with: path: dist-artifacts - name: Collect packages run: | mkdir -p dist find dist-artifacts -name "*.whl" -exec cp {} dist/ \; find dist-artifacts -name "*.tar.gz" -exec cp {} dist/ \; echo "📦 Packages to publish:" ls -la dist/ - name: Publish to PyPI env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} run: | if [ -z "$TWINE_PASSWORD" ]; then echo "❌ PYPI_API_TOKEN not configured!" exit 1 fi pip install twine twine upload dist/* --skip-existing --verbose echo "✅ Published to PyPI!" - name: Create release run: | git tag "v${{ inputs.version }}" git push origin "v${{ inputs.version }}" gh release create "v${{ inputs.version }}" \ --title "Release v${{ inputs.version }}" \ --notes "🚀 Released to PyPI: https://pypi.org/project/leann/${{ inputs.version }}/" \ --latest env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}