Files
LEANN/.github/workflows/release-manual.yml

289 lines
10 KiB
YAML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Manual Release
on:
workflow_dispatch:
inputs:
version:
description: 'Version to release (e.g., 0.1.1)'
required: true
type: string
test_pypi:
description: 'Test on TestPyPI first'
required: false
type: boolean
default: true
jobs:
validate-and-release:
runs-on: ubuntu-latest
permissions:
contents: write
actions: read
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Check CI status
run: |
echo " This workflow will download build artifacts from the latest CI run."
echo " CI must have completed successfully on the current commit."
echo ""
- name: Validate version format
run: |
if ! [[ "${{ inputs.version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "❌ Invalid version format. Use semantic versioning (e.g., 0.1.1)"
exit 1
fi
echo "✅ Version format valid: ${{ inputs.version }}"
- name: Check if version already exists
run: |
if git tag | grep -q "^v${{ inputs.version }}$"; then
echo "❌ Version v${{ inputs.version }} already exists!"
exit 1
fi
echo "✅ Version is new"
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
- name: Install uv
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Update versions
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 }}"
- name: Push version update
run: |
git push origin HEAD:main
echo "✅ Pushed version update to main branch"
COMMIT_SHA=$(git rev-parse HEAD)
echo "commit-sha=$COMMIT_SHA" >> $GITHUB_OUTPUT
id: push-version
- name: Trigger CI build
run: |
echo "🚀 Manually triggering CI for the new version..."
# Check if we have a PAT for triggering workflows
if [ -z "${{ secrets.WORKFLOW_PAT }}" ]; then
echo "⚠️ No WORKFLOW_PAT found. CI will be triggered by the push event."
echo " Note: If CI doesn't trigger automatically, you'll need to:"
echo " 1. Add a Personal Access Token with 'workflow' scope as WORKFLOW_PAT secret"
echo " 2. Or manually run the CI workflow after this release completes"
exit 0
fi
gh workflow run "CI - Build Multi-Platform Packages" \
--ref main \
-f publish=false
# Give GitHub a moment to register the new workflow run
sleep 5
env:
GH_TOKEN: ${{ secrets.WORKFLOW_PAT || secrets.GITHUB_TOKEN }}
- name: Wait for CI to complete
id: wait-for-ci
run: |
echo "⏳ Waiting for CI to build new version..."
COMMIT_SHA="${{ steps.push-version.outputs.commit-sha }}"
# First, wait a bit for CI to potentially start
echo "⏳ Waiting for CI to start..."
sleep 30
# Check if there's any CI run for this commit
CI_EXISTS=$(gh run list \
--workflow="CI - Build Multi-Platform Packages" \
--commit=$COMMIT_SHA \
--json databaseId \
--jq 'length')
if [ "$CI_EXISTS" -eq "0" ]; then
echo "⚠️ No CI run found for commit $COMMIT_SHA"
echo " This might be because:"
echo " 1. WORKFLOW_PAT is not configured"
echo " 2. CI hasn't started yet"
echo ""
echo " You can manually trigger CI after this release completes:"
echo " gh workflow run 'CI - Build Multi-Platform Packages' --ref main"
echo ""
echo " For now, we'll use the artifacts from the latest successful CI run."
# Get the latest successful CI run
LATEST_RUN=$(gh run list \
--workflow="CI - Build Multi-Platform Packages" \
--status=success \
--json databaseId \
--jq '.[0].databaseId')
if [ -z "$LATEST_RUN" ]; then
echo "❌ No successful CI runs found!"
exit 1
fi
echo "📦 Using artifacts from CI run: $LATEST_RUN"
echo "run-id=$LATEST_RUN" >> $GITHUB_OUTPUT
exit 0
fi
# Wait up to 20 minutes for CI to complete
for i in {1..40}; do
# First check if CI is running
RUNNING_ID=$(gh run list \
--workflow="CI - Build Multi-Platform Packages" \
--commit=$COMMIT_SHA \
--status=in_progress \
--json databaseId \
--jq '.[0].databaseId')
if [ ! -z "$RUNNING_ID" ]; then
echo "⏳ CI is running (ID: $RUNNING_ID)..."
fi
# Check if CI has completed
RUN_ID=$(gh run list \
--workflow="CI - Build Multi-Platform Packages" \
--commit=$COMMIT_SHA \
--json databaseId,status,conclusion \
--jq '.[] | select(.status == "completed" and .conclusion == "success") | .databaseId' | head -1)
if [ ! -z "$RUN_ID" ]; then
echo "✅ Found completed CI run: $RUN_ID"
echo "run-id=$RUN_ID" >> $GITHUB_OUTPUT
exit 0
fi
echo "⏳ Waiting for CI... (attempt $i/40)"
sleep 30
done
echo "❌ CI did not complete within 20 minutes"
exit 1
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Download artifacts from CI run
run: |
echo "📦 Downloading artifacts from CI run ${{ steps.wait-for-ci.outputs.run-id }}..."
# Download all artifacts (not just wheels-*)
gh run download ${{ steps.wait-for-ci.outputs.run-id }} \
--dir ./dist-downloads
# Consolidate all wheels into packages/*/dist/
mkdir -p packages/leann-core/dist
mkdir -p packages/leann-backend-hnsw/dist
mkdir -p packages/leann-backend-diskann/dist
mkdir -p packages/leann/dist
find ./dist-downloads -name "*.whl" -exec cp {} ./packages/ \;
# Move wheels to correct package directories
for wheel in packages/*.whl; do
if [[ $wheel == *"leann_core"* ]]; then
mv "$wheel" packages/leann-core/dist/
elif [[ $wheel == *"leann_backend_hnsw"* ]]; then
mv "$wheel" packages/leann-backend-hnsw/dist/
elif [[ $wheel == *"leann_backend_diskann"* ]]; then
mv "$wheel" packages/leann-backend-diskann/dist/
elif [[ $wheel == *"leann-"* ]] && [[ $wheel != *"backend"* ]] && [[ $wheel != *"core"* ]]; then
mv "$wheel" packages/leann/dist/
fi
done
# List downloaded wheels
echo "✅ Downloaded wheels:"
find packages/*/dist -name "*.whl" -type f | sort
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Test on TestPyPI (optional)
if: inputs.test_pypi
continue-on-error: true
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
run: |
if [ -z "$TWINE_PASSWORD" ]; then
echo "⚠️ TEST_PYPI_API_TOKEN not configured, skipping TestPyPI upload"
echo " To enable TestPyPI testing, add TEST_PYPI_API_TOKEN to repository secrets"
exit 0
fi
pip install twine
echo "📦 Uploading to TestPyPI..."
twine upload --repository testpypi packages/*/dist/* --verbose || {
echo "⚠️ TestPyPI upload failed, but continuing with release"
echo " This is optional and won't block the release"
exit 0
}
echo "✅ Test upload successful!"
echo "📋 Check packages at: https://test.pypi.org/user/your-username/"
echo ""
echo "To test installation:"
echo "pip install -i https://test.pypi.org/simple/ leann"
- 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!"
echo " Please add PYPI_API_TOKEN to repository secrets"
exit 1
fi
pip install twine
echo "📦 Publishing to PyPI..."
# Collect all wheels in one place
mkdir -p all_wheels
find packages/*/dist -name "*.whl" -exec cp {} all_wheels/ \;
find packages/*/dist -name "*.tar.gz" -exec cp {} all_wheels/ \;
echo "📋 Packages to publish:"
ls -la all_wheels/
# Upload to PyPI
twine upload all_wheels/* --skip-existing --verbose
echo "✅ Published to PyPI!"
echo "🎉 Check packages at: https://pypi.org/project/leann/"
- name: Create and push tag
run: |
git tag "v${{ inputs.version }}"
git push origin main
git push origin "v${{ inputs.version }}"
echo "✅ Tag v${{ inputs.version }} created and pushed"
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: v${{ inputs.version }}
name: Release v${{ inputs.version }}
body: |
## 🚀 Release v${{ inputs.version }}
### What's Changed
See the [full changelog](https://github.com/${{ github.repository }}/compare/...v${{ inputs.version }})
### Installation
```bash
pip install leann==${{ inputs.version }}
```