feat: issue mega sprint - allow package_data outside root, cli alias tesseract-core, flags to pass arguments to docker run and tesseract runtime, json+binref support in SDK, better support for tesseract serve --network host
#2430
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
| name: Run test suite | |
| on: | |
| pull_request: | |
| push: | |
| branches: | |
| - main | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| tests-base: | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| # test with oldest and latest supported Python versions | |
| # NOTE: If bumping the minimum Python version here, also do it in | |
| # ruff.toml, setup.py and other CI files as well. | |
| python-version: ["3.10", "3.13"] | |
| runtime-deps: ["latest"] | |
| include: | |
| - os: ubuntu-latest | |
| python-version: "3.10" | |
| runtime-deps: "oldest" | |
| fail-fast: false | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Set up Git repository | |
| uses: actions/checkout@v6 | |
| - name: Set up WSL (Windows) | |
| uses: Vampire/setup-wsl@v6 | |
| if: runner.os == 'Windows' | |
| with: | |
| distribution: Ubuntu-24.04 | |
| - name: Set up uv | |
| if: runner.os != 'Windows' | |
| uses: astral-sh/setup-uv@v7 | |
| with: | |
| enable-cache: true | |
| - name: Set up uv (Windows) | |
| if: runner.os == 'Windows' | |
| shell: wsl-bash {0} | |
| run: | | |
| curl -LsSf https://astral.sh/uv/install.sh | sh | |
| - name: Install package | |
| if: runner.os != 'Windows' | |
| run: | | |
| cp production.uv.lock uv.lock | |
| uv sync --python ${{ matrix.python-version }} --extra dev --frozen | |
| if [ "${{ matrix.runtime-deps }}" == "oldest" ]; then | |
| # replace >= with == in runtime deps section of pyproject.toml to install oldest runtime deps | |
| sed -i '/^runtime = \[$/,/^]$/s/>=/==/g' ./pyproject.toml | |
| uv pip install -e .[runtime] | |
| fi | |
| - name: Install package (Windows) | |
| if: runner.os == 'Windows' | |
| shell: wsl-bash {0} | |
| run: | | |
| source "$HOME/.local/bin/env" | |
| export UV_PROJECT_ENVIRONMENT="$HOME/venv" | |
| export UV_CACHE_DIR="$HOME/.cache/uv" | |
| cp production.uv.lock uv.lock | |
| uv sync --python ${{ matrix.python-version }} --extra dev --frozen | |
| if [ "${{ matrix.runtime-deps }}" == "oldest" ]; then | |
| # replace >= with == in runtime deps section of pyproject.toml to install oldest runtime deps | |
| sed -i '/^runtime = \[$/,/^]$/s/>=/==/g' ./pyproject.toml | |
| uv pip install -e .[runtime] | |
| fi | |
| - name: Run test suite | |
| if: runner.os != 'Windows' | |
| run: | | |
| uv run --no-sync pytest \ | |
| -v \ | |
| --skip-endtoend \ | |
| --timeout=300 \ | |
| --cov-report=term-missing:skip-covered \ | |
| --cov-report=xml:coverage.xml \ | |
| --cov=tesseract_core \ | |
| --cov-branch | |
| - name: Run test suite (Windows) | |
| if: runner.os == 'Windows' | |
| shell: wsl-bash {0} | |
| run: | | |
| source "$HOME/.local/bin/env" | |
| export UV_PROJECT_ENVIRONMENT="$HOME/venv" | |
| uv run --no-sync pytest \ | |
| -v \ | |
| --skip-endtoend \ | |
| --timeout=300 \ | |
| --cov-report=term-missing:skip-covered \ | |
| --cov-report=xml:coverage.xml \ | |
| --cov=tesseract_core \ | |
| --cov-branch | |
| - name: Upload coverage reports to Codecov | |
| uses: codecov/codecov-action@v5.5.2 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| slug: pasteurlabs/tesseract-core | |
| files: coverage*.xml | |
| fail_ci_if_error: true | |
| get-e2e-matrix: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.get-matrix.outputs.matrix }} | |
| demos: ${{ steps.get-matrix.outputs.demos }} | |
| steps: | |
| - name: Set up Git repository | |
| uses: actions/checkout@v6 | |
| - name: Get all changed files | |
| id: changed-files | |
| uses: tj-actions/changed-files@7dee1b0c1557f278e5c7dc244927139d78c0e22a # v47 | |
| with: | |
| files: | | |
| tesseract_core/** | |
| tests/endtoend_tests/** | |
| demo/** | |
| examples/** | |
| production.uv.lock | |
| .github/workflows/run_tests.yml | |
| - name: Get available test matrix | |
| id: get-matrix | |
| env: | |
| EXAMPLES_DIR: examples | |
| DEMO_DIR: demo | |
| run: | | |
| # if no changed files in the current PR, skip E2E tests | |
| if [[ "${{ steps.changed-files.outputs.any_changed }}" != "true" && ${{ github.event_name == 'pull_request' }} ]]; then | |
| echo "No changed files detected, skipping E2E tests." | |
| echo "matrix=[]" >> $GITHUB_OUTPUT | |
| echo "demos=[]" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| # get JSON array of directories in EXAMPLES_DIR, except ones that start with _ | |
| subjobs=$( | |
| find "${{ env.EXAMPLES_DIR }}" -type d -maxdepth 1 -mindepth 1 -exec basename {} \; \ | |
| | grep -v '^_' \ | |
| | jq -R -s -c 'split("\n")[:-1]' | |
| ) | |
| # add "base" to subjobs | |
| subjobs=$(echo "$subjobs" | jq -c -r '. + ["base"]') | |
| printf 'matrix=%s\n' "$subjobs" >> $GITHUB_OUTPUT | |
| # get JSON array of directories in DEMO_DIR, except ones that start with _ | |
| demos=$( | |
| find "${{ env.DEMO_DIR }}" -type d -maxdepth 1 -mindepth 1 -exec basename {} \; \ | |
| | grep -v '^_' \ | |
| | jq -R -s -c 'split("\n")[:-1]' | |
| ) | |
| printf 'demos=%s\n' "$demos" >> $GITHUB_OUTPUT | |
| tests-e2e: | |
| needs: [get-e2e-matrix] | |
| if: needs.get-e2e-matrix.outputs.matrix != '[]' | |
| strategy: | |
| matrix: | |
| os: [ubuntu-24.04] | |
| python-version: ["3.13"] | |
| arch: ["x64"] | |
| docker-engine: ["docker"] | |
| unit-tesseract: ${{ fromJson(needs.get-e2e-matrix.outputs.matrix) }} | |
| exclude: | |
| - arch: x64 | |
| unit-tesseract: "pyvista-arm64" | |
| include: | |
| # Test on arm to ensure compatibility with Apple M1 chips | |
| # (OSX runners don't have access to Docker so we use Linux ARM runners instead) | |
| - os: "ubuntu-24.04" | |
| python-version: "3.13" | |
| arch: "arm" | |
| docker-engine: "docker" | |
| unit-tesseract: "base" | |
| - os: "ubuntu-24.04" | |
| python-version: "3.13" | |
| arch: "arm" | |
| docker-engine: "docker" | |
| unit-tesseract: "pyvista-arm64" | |
| # Run tests using Podman | |
| - os: "ubuntu-24.04" | |
| python-version: "3.13" | |
| arch: "x64" | |
| docker-engine: "podman" | |
| unit-tesseract: "base" | |
| fail-fast: false | |
| runs-on: ${{ matrix.arch == 'x64' && matrix.os == 'ubuntu-24.04' && 'ubuntu-24.04' || matrix.arch == 'arm' && matrix.os == 'ubuntu-24.04' && 'ubuntu-24.04-arm'}} | |
| defaults: | |
| run: | |
| shell: bash -el {0} | |
| steps: | |
| - name: Set up Git repository | |
| uses: actions/checkout@v6 | |
| # Use Conda to install Python (setup-python action doesn't support ARM) | |
| - uses: conda-incubator/setup-miniconda@v3 | |
| with: | |
| auto-update-conda: true | |
| python-version: ${{ matrix.python-version }} | |
| channels: defaults | |
| - name: Set up uv | |
| uses: astral-sh/setup-uv@v7 | |
| with: | |
| enable-cache: true | |
| - name: Restore UV environment | |
| run: cp production.uv.lock uv.lock | |
| - name: Install package | |
| run: | | |
| uv sync --extra dev --frozen | |
| - name: Set up Podman | |
| if: matrix.docker-engine == 'podman' | |
| run: | | |
| systemctl start --user podman.socket | |
| systemctl status --user podman.socket | |
| podman --version | |
| export DOCKER_HOST=unix:///run/user/1001/podman/podman.sock | |
| echo "DOCKER_HOST=${DOCKER_HOST}" >> $GITHUB_ENV | |
| echo "TESSERACT_DOCKER_EXECUTABLE=podman" >> $GITHUB_ENV | |
| - name: Run test suite | |
| run: | | |
| if [ "${{ matrix.unit-tesseract }}" == "base" ]; then | |
| uv run --no-sync pytest \ | |
| --always-run-endtoend \ | |
| --timeout=300 \ | |
| --cov-branch \ | |
| --cov-report=term-missing:skip-covered \ | |
| --cov-report=xml:coverage.xml \ | |
| --cov=tesseract_core \ | |
| tests/endtoend_tests \ | |
| -k "not test_examples" | |
| else | |
| uv run --no-sync pytest \ | |
| --always-run-endtoend \ | |
| --timeout=300 \ | |
| --cov-branch \ | |
| --cov-report=term-missing:skip-covered \ | |
| --cov-report=xml:coverage.xml \ | |
| --cov=tesseract_core \ | |
| tests/endtoend_tests/test_examples.py \ | |
| -k "[${{ matrix.unit-tesseract }}]" | |
| fi | |
| - name: Upload coverage reports to Codecov | |
| uses: codecov/codecov-action@v5.5.2 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| slug: pasteurlabs/tesseract-core | |
| files: coverage*.xml | |
| fail_ci_if_error: true | |
| tests-demos: | |
| needs: [get-e2e-matrix] | |
| if: needs.get-e2e-matrix.outputs.demos != '[]' | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest] | |
| # test with oldest supported Python version only (for slow tests) | |
| python-version: ["3.10"] | |
| demo: ${{ fromJson(needs.get-e2e-matrix.outputs.demos) }} | |
| fail-fast: false | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Set up Git repository | |
| uses: actions/checkout@v6 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| with: | |
| enable-cache: true | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Restore UV environment | |
| run: cp production.uv.lock uv.lock | |
| - name: Install dev requirements | |
| run: | | |
| uv sync --extra dev --frozen | |
| - name: Run demos | |
| working-directory: demo/${{matrix.demo}} | |
| run: | | |
| uv pip install jupyter | |
| uv run --no-sync jupyter nbconvert --to notebook --execute demo.ipynb | |
| all-ok: | |
| if: always() | |
| needs: [tests-base, tests-e2e, tests-demos] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check for errors | |
| run: | | |
| if [[ "${{ needs.tests-base.result }}" != "success" && "${{ needs.tests-base.result }}" != "skipped" ]]; then | |
| echo "Base tests failed" | |
| exit 1 | |
| fi | |
| if [[ "${{ needs.tests-e2e.result }}" != "success" && "${{ needs.tests-e2e.result }}" != "skipped" ]]; then | |
| echo "E2E tests failed" | |
| exit 1 | |
| fi | |
| if [[ "${{ needs.tests-demos.result }}" != "success" && "${{ needs.tests-demos.result }}" != "skipped" ]]; then | |
| echo "Demo tests failed" | |
| exit 1 | |
| fi | |
| echo "All tests passed!" |