Skip to content

Use a single workflow for CI and release #2305

Use a single workflow for CI and release

Use a single workflow for CI and release #2305

Workflow file for this run

name: CI
on:
push:
branches:
- dev
pull_request:
release:
types: [published]
env:
UV_CACHE_DIR: "/tmp/.uv-cache"
DEFAULT_PYTHON: "3.13"
ALL_PYTHON_VERSIONS: "['3.12', '3.13']"
UV_PROJECT_ENVIRONMENT: "venv"
jobs:
info:
name: Collect information & changes data
outputs:
venv_cache_key_partly: ${{ steps.info.outputs.venv_key_partly }}
python_versions: ${{ steps.info.outputs.python_versions }}
runs-on: ubuntu-latest
steps:
- name: ⤵️ Check out code from GitHub
uses: actions/[email protected]
- name: Collect information
id: info
run: |
venv_key_partly=venv-${{ runner.os }}-${{hashFiles('uv.lock', 'pyproject.toml', 'Cargo.lock', 'Cargo.toml') }}
echo "venv cache key partly : ${venv_key_partly}"
echo "venv_key_partly=${venv_key_partly}" >> $GITHUB_OUTPUT
echo "python_versions: ${ALL_PYTHON_VERSIONS}"
echo "python_versions=${ALL_PYTHON_VERSIONS}" >> $GITHUB_OUTPUT
base:
name: Prepare dependencies
runs-on: ubuntu-latest
needs: info
strategy:
matrix:
python-version: ${{ fromJSON(needs.info.outputs.python_versions) }}
steps:
- name: ⤵️ Check out code from GitHub
uses: actions/[email protected]
- name: 🏗 Set up Python ${{ matrix.python-version }}
id: python
uses: actions/[email protected]
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: 🏗 Restore base Python virtual environment
id: cache-venv
uses: actions/[email protected]
with:
path: venv
key: ${{ matrix.python-version }}-${{ needs.info.outputs.venv_cache_key_partly }}
restore-keys: ${{ matrix.python-version }}-venv-${{ runner.os }}-
- name: 🏗 Set up uv
if: steps.cache-venv.outputs.cache-hit != 'true'
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
- name: 🏗 Install additional OS dependencies
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
sudo apt-get update
sudo apt-get -y install \
pkg-config \
liblzma-dev
- name: 📦 Build project
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
python -m venv ${{ env.UV_PROJECT_ENVIRONMENT }}
. venv/bin/activate
uv sync --locked --dev
code-quality:
runs-on: "ubuntu-latest"
name: Check code quality
needs:
- info
- base
steps:
- name: ⤵️ Checkout repository
uses: actions/checkout@v4
- name: 🏗 Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/[email protected]
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: 🏗 Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/[email protected]
with:
path: venv
fail-on-cache-miss: true
key: ${{ env.DEFAULT_PYTHON }}-${{ needs.info.outputs.venv_cache_key_partly }}
# Following steps cannot run by pre-commit.ci as repo = local
- name: Run mypy
run: |
. venv/bin/activate
mypy deebot_client/
- name: Pylint review
run: |
. venv/bin/activate
pylint deebot_client/**/*.py
- name: Verify no getLogger usages
run: |
. venv/bin/activate
scripts/check_getLogger.sh
tests:
runs-on: "ubuntu-latest"
name: Run tests
needs:
- info
- base
strategy:
matrix:
python-version: ${{ fromJSON(needs.info.outputs.python_versions) }}
steps:
- name: ⤵️ Checkout repository
uses: actions/checkout@v4
- name: 🏗 Set up Python ${{ matrix.python-version }}
id: python
uses: actions/[email protected]
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: 🏗 Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/[email protected]
with:
path: venv
fail-on-cache-miss: true
key: ${{ matrix.python-version }}-${{ needs.info.outputs.venv_cache_key_partly }}
- name: Run pytest
run: |
. venv/bin/activate
pytest tests --cov=./ --cov-report=xml --junitxml=junit.xml -o junit_family=legacy
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
- name: Upload test results to Codecov
if: ${{ !cancelled() && steps.cache-venv.conclusion == 'success' }}
uses: codecov/test-results-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
wheels:
name: Build wheels
runs-on: ubuntu-latest
needs: base
strategy:
matrix:
python-version:
- "3.12"
- "3.13"
linux-compatibility:
- "manylinux_2_34"
steps:
- name: ⤵️ Check out code from GitHub
uses: actions/[email protected]
- name: 🏗 Set up uv and Python ${{ matrix.python-version }}
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
python-version: ${{ matrix.python-version }}
- name: Install additional OS dependencies
run: |
sudo apt-get update
sudo apt-get -y install \
pkg-config \
liblzma-dev
- name: 🏗 Set package version
if: ${{ github.event_name == 'release' }}
run: |
sed -i "s/^version = \".*\"/version = \"${{ github.event.release.tag_name }}\"/" pyproject.toml
- name: 📦 Build package
run: uv build --wheel --config-settings build-args='--compatibility ${{ matrix.linux-compatibility }}'
- name: ⬆️ Upload wheels
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.python-version }}-${{ matrix.linux-compatibility }}
path: dist
sdist:
if: ${{ github.event_name == 'release' }}
runs-on: ubuntu-latest
needs: base
steps:
- uses: actions/checkout@v4
- name: 🏗 Set package version
run: |
sed -i "s/^version = \".*\"/version = \"${{ github.event.release.tag_name }}\"/" pyproject.toml
- name: Build sdist
uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out dist
- name: Upload sdist
uses: actions/upload-artifact@v4
with:
name: wheels-sdist
path: dist
release:
name: Releasing to PyPi
runs-on: ubuntu-latest
needs:
- "wheels"
- "sdist"
- "tests"
- "code-quality"
environment:
name: release
url: https://pypi.org/manage/project/deebot-client/releases/
permissions:
contents: write
id-token: write
steps:
- name: ⤵️ Check out code from GitHub
uses: actions/[email protected]
- name: 🏗 Set up uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
- name: ⬇️ Download wheels
uses: actions/download-artifact@v4
with:
pattern: wheels-*
path: dist
merge-multiple: true
- name: 🚀 Publish to PyPi
run: uv publish
- name: ✍️ Sign published artifacts
uses: sigstore/[email protected]
with:
inputs: ./dist/*.tar.gz ./dist/*.whl
release-signing-artifacts: true