diff --git a/.github/workflows/build_release.yml b/.github/workflows/build_release.yml new file mode 100644 index 0000000..ffbbadb --- /dev/null +++ b/.github/workflows/build_release.yml @@ -0,0 +1,57 @@ +name: build and test release + +on: + workflow_call: + workflow_dispatch: + inputs: + ref: + description: "Commit, tag or branch to build" + required: false + default: "" + type: string + +permissions: + contents: read + +jobs: + build-and-test-wheel: + name: wheel install py3.12 + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ inputs.ref }} + # Needed for setuptools-scm + fetch-depth: 0 + + - uses: actions/setup-python@v6 + with: + python-version: "3.12" + + - name: Install build tooling + run: python -m pip install --upgrade pip build twine setuptools-scm + + - name: Show SCM-derived version + run: python -m setuptools_scm + + - name: Build and check metadata + run: | + python -m build + python -m twine check --strict dist/* + ls dist + + - name: Install the wheel + run: python -m pip install "$(ls dist/*.whl)" "pytest>=8" + + - name: Test the wheel outside the source tree + run: | + cp -r tests "$RUNNER_TEMP/wheeltest" + cd "$RUNNER_TEMP" + pytest wheeltest + + - uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ + if-no-files-found: error diff --git a/.github/workflows/release-pypi.yml b/.github/workflows/release-pypi.yml index 12d6a91..9f87897 100644 --- a/.github/workflows/release-pypi.yml +++ b/.github/workflows/release-pypi.yml @@ -1,54 +1,52 @@ name: Release on: - pull_request: - branches: - - main push: tags: - "v*.*.*" - workflow_dispatch: permissions: contents: read -concurrency: - group: release-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - jobs: - build-and-publish: + tests: + uses: ./.github/workflows/test_package.yml + + build: + needs: [tests] + uses: ./.github/workflows/build_release.yml + + publish: + needs: [build] runs-on: ubuntu-latest + concurrency: + group: pypi-deploy + cancel-in-progress: false + steps: - - name: Check out source - uses: actions/checkout@v6 + - uses: actions/download-artifact@v4 with: - fetch-depth: 0 + name: dist + path: dist/ - - name: Set up Python - uses: actions/setup-python@v6 + - uses: actions/setup-python@v6 with: python-version: "3.12" - cache: "pip" - - name: Install build tooling + - name: Check the PyPI token is set + env: + TWINE_PASSWORD: ${{ secrets.TWINE_API_KEY }} run: | - python -m pip install --upgrade pip - python -m pip install build twine setuptools-scm - - - name: Show SCM-derived version - run: python -m setuptools_scm - - - name: Build distributions - run: python -m build - - - name: Check built distributions - run: python -m twine check dist/* + if [ -z "$TWINE_PASSWORD" ]; then + echo "::error::secrets.TWINE_API_KEY is empty" + exit 1 + fi - name: Publish to PyPI - if: startsWith(github.ref, 'refs/tags/v') env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.TWINE_API_KEY }} - run: python -m twine upload --non-interactive dist/* \ No newline at end of file + run: | + python -m pip install --upgrade pip twine + python -m twine upload --non-interactive dist/* diff --git a/.github/workflows/test_package.yml b/.github/workflows/test_package.yml index 10d65dc..3795484 100644 --- a/.github/workflows/test_package.yml +++ b/.github/workflows/test_package.yml @@ -2,36 +2,62 @@ name: Test suite on: push: - branches: [ main ] + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: + workflow_call: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +permissions: + contents: read jobs: - build: + test: + name: ${{ matrix.os }} py${{ matrix.python-version }} runs-on: ${{ matrix.os }} - strategy: - fail-fast: true + fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - python-version: [3.9,"3.10"] + os: [ubuntu-latest, windows-latest, macos-latest] + # Keep in sync w/ DeepLabCut + python-version: ["3.10", "3.11", "3.12"] steps: - - name: Checkout code - uses: actions/checkout@v3 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + - uses: actions/checkout@v6 + + - uses: astral-sh/setup-uv@v7 with: python-version: ${{ matrix.python-version }} + activate-environment: true + + - name: Install + run: uv pip install . "pytest>=8" + + - name: Test the installed package + run: pytest tests + + test-dependency-floor: + name: dependency floor py3.10 + runs-on: ubuntu-latest - - name: Install dependencies - shell: bash - run: | - python -m pip install --upgrade pip - pip install pytest - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - - name: Install DLClibrary - run: pip install . - - - name: Run pytest tests - run: | - pytest + steps: + - uses: actions/checkout@v6 + + - uses: astral-sh/setup-uv@v7 + with: + python-version: "3.10" + activate-environment: true + + - name: Install the lowest version each dependency declares + run: uv pip install --resolution lowest-direct . "pytest>=8" + + - name: Test + run: pytest tests + + build: + if: ${{ !startsWith(github.ref, 'refs/tags/') }} + uses: ./.github/workflows/build_release.yml diff --git a/pyproject.toml b/pyproject.toml index 3c0b143..299f33f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,15 +15,18 @@ authors = [ { name = "The DeepLabCut team", email = "admin@deeplabcut.org" } ] license = { text = "GNU Lesser General Public License v3.0" } -requires-python = ">=3.9" +requires-python = ">=3.10" classifiers = [ "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", "Operating System :: OS Independent", ] dependencies = [ "huggingface_hub>=0.11.1", - "ruamel.yaml>=0.15.0", + "ruamel.yaml>=0.16", ] [project.urls]