| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| name: Create Release and Publish to PyPI |
|
|
| on: |
| push: |
| tags: |
| - 'v*.*.*' |
|
|
| |
| env: |
| UV_VERSION: "0.8.0" |
| PYTHON_VERSION: "3.12" |
|
|
| jobs: |
| |
| build-and-publish: |
| name: Build and publish Python distributions |
| runs-on: ubuntu-latest |
| if: github.repository == 'huggingface/lerobot' |
| outputs: |
| version: ${{ steps.extract_info.outputs.tag_version }} |
| permissions: |
| contents: write |
| id-token: write |
|
|
| steps: |
| - name: Checkout code |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd |
| with: |
| persist-credentials: false |
|
|
| - name: Set up Python |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 |
| with: |
| python-version: '3.12' |
|
|
| - name: Extract Version |
| id: extract_info |
| |
| |
| run: | |
| VERSION=${{ github.ref_name }} |
| VERSION_NUMBER=${VERSION#v} |
| echo "tag_version=$VERSION_NUMBER" >> $GITHUB_OUTPUT |
| - name: Check if version matches pyproject.toml |
| if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-') |
| |
| run: | |
| TAG_VERSION=${{ steps.extract_info.outputs.tag_version }} |
| |
| PYPROJECT_VERSION=$(grep '^version = ' pyproject.toml | awk -F' = ' '{print $2}' | tr -d '"') |
| |
| if [[ "$TAG_VERSION" != "$PYPROJECT_VERSION" ]]; then |
| echo "Error: Tag version ($TAG_VERSION) does not match pyproject.toml version ($PYPROJECT_VERSION)." >&2 |
| exit 1 |
| else |
| echo "Tag version matches pyproject.toml version: $TAG_VERSION. Proceeding with release." |
| fi |
|
|
| - name: Check if version exists on PyPI |
| |
| run: | |
| NEW_VERSION=${{ steps.extract_info.outputs.tag_version }} |
| |
| response=$(curl -s "https://pypi.org/pypi/lerobot/$NEW_VERSION/json") |
| if echo "$response" | grep -q "message"; then |
| echo "Version $NEW_VERSION is available on PyPI. Proceeding with release." |
| else |
| echo "Error: Version $NEW_VERSION already exists on PyPI. Aborting." |
| exit 1 |
| fi |
|
|
| - name: Install build dependencies |
| run: python -m pip install build |
|
|
| - name: Build package |
| run: python -m build |
|
|
| - name: Create GitHub Release |
| env: |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| |
| run: | |
| gh release create ${{ github.ref_name }} \ |
| --title "Release ${{ github.ref_name }}" \ |
| --generate-notes \ |
| --draft=$([[ "${{ github.ref_name }}" == *-* ]] && echo true || echo false) \ |
| --prerelease=$([[ "${{ github.ref_name }}" == *-* ]] && echo true || echo false) \ |
| ./dist/* |
| |
| - name: Publish to TestPyPI for pre-releases |
| |
| if: startsWith(github.ref, 'refs/tags/v') && contains(github.ref, '-') |
| uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e |
| with: |
| repository-url: https://test.pypi.org/legacy/ |
| verbose: true |
| print-hash: true |
|
|
| - name: Publish to PyPI |
| if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-') |
| uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e |
| with: |
| verbose: true |
| print-hash: true |
|
|
| |
| test-release: |
| name: Test Release |
| needs: [build-and-publish] |
| runs-on: ubuntu-latest |
| permissions: |
| contents: read |
| env: |
| MUJOCO_GL: egl |
| steps: |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd |
| with: |
| lfs: true |
| persist-credentials: false |
| - name: Install apt dependencies |
| run: | |
| sudo apt-get update && sudo apt-get install -y build-essential \ |
| git curl libglib2.0-0 libegl1-mesa-dev ffmpeg libusb-1.0-0-dev \ |
| speech-dispatcher libgeos-dev portaudio19-dev |
| - name: Setup uv and Python |
| uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e |
| with: |
| enable-cache: true |
| version: ${{ env.UV_VERSION }} |
| python-version: ${{ env.PYTHON_VERSION }} |
| - name: Create uv virtual environment |
| run: uv venv |
| - name: Install lerobot release |
| |
| run: | |
| VERSION="${{ needs.build-and-publish.outputs.version }}" |
| if [[ "$VERSION" == *-* ]]; then |
| BASE_VERSION="${VERSION%%-*}" |
| echo "Installing pre-release version $BASE_VERSION from TestPyPI..." |
| uv pip install \ |
| --torch-backend cpu \ |
| --index-url https://test.pypi.org/simple/ \ |
| --extra-index-url https://pypi.org/simple \ |
| --index-strategy unsafe-best-match \ |
| "lerobot[all]==$BASE_VERSION" |
| else |
| echo "Installing release version $VERSION from PyPI..." |
| uv pip install --torch-backend cpu "lerobot[all]==$VERSION" |
| fi |
| - name: Check lerobot version |
| run: uv run python -c "import lerobot; print(lerobot.__version__)" |
|
|
| - name: Run end-to-end tests |
| run: uv run make test-end-to-end |
|
|
|
|
| |
| |
|
|