fix(ci): use base tag for testpy to mimic the pyproject.toml version … #3
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Copyright 2025 The HuggingFace Inc. team. All rights reserved. | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
name: Create Release and Publish to PyPI | |
on: | |
push: | |
tags: | |
- 'v*.*.*' # Trigger on tags like v0.1.0, v1.0.0 | |
# Sets up the environment variables | |
env: | |
UV_VERSION: "0.8.0" | |
PYTHON_VERSION: "3.10" | |
jobs: | |
# This job builds the Python package and publishes it to PyPI | |
build-and-publish: | |
name: Build and publish Python distributions | |
runs-on: ubuntu-latest | |
outputs: | |
version: ${{ steps.extract_info.outputs.tag_version }} | |
permissions: | |
contents: write | |
id-token: write | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
with: | |
persist-credentials: false | |
- name: Set up Python | |
uses: actions/setup-python@v5 | |
with: | |
python-version: '3.10' | |
- name: Extract Version | |
id: extract_info | |
# Extract version from tag (e.g., v0.1.0 -> 0.1.0) | |
# zizmor: ignore[template-injection] | |
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, '-') | |
# zizmor: ignore[template-injection] | |
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 | |
# zizmor: ignore[template-injection] | |
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 }} | |
# zizmor: ignore[template-injection] | |
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 | |
# True for tags like 'v0.2.0-rc1' | |
if: startsWith(github.ref, 'refs/tags/v') && contains(github.ref, '-') | |
uses: pypa/[email protected] # zizmor: ignore[unpinned-uses, use-trusted-publishing] | |
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/[email protected] # zizmor: ignore[unpinned-uses, use-trusted-publishing] | |
with: | |
verbose: true | |
print-hash: true | |
# This job runs end-to-end tests on the release | |
test-release: | |
name: Test Release | |
needs: [build-and-publish] | |
runs-on: ubuntu-latest | |
permissions: | |
contents: read | |
env: | |
MUJOCO_GL: egl | |
steps: | |
- uses: actions/checkout@v4 | |
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@v6 # zizmor: ignore[unpinned-uses] | |
with: | |
enable-cache: true | |
version: ${{ env.UV_VERSION }} | |
python-version: ${{ env.PYTHON_VERSION }} | |
- name: Install lerobot release | |
# zizmor: ignore[template-injection] | |
run: | | |
VERSION="${{ needs.build-and-publish.outputs.version }}" | |
if [[ "$VERSION" == *-* ]]; then | |
BASE_VERSION="${VERSION%%-*}" | |
echo "Installing pre-release version $BASE_VERSION from TestPyPI..." | |
uv run pip install \ | |
--index-url https://test.pypi.org/simple/ \ | |
--extra-index-url https://pypi.org/simple \ | |
"lerobot[all]==$BASE_VERSION" | |
else | |
echo "Installing release version $VERSION from PyPI..." | |
uv run pip install "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 | |
# TODO(Steven): Publish draft/pre-release and to test pypi weekly | |
# TODO(Steven): Separate build and publish job | |
# TODO(Steven): Tag documentation with the same version as the package |