Repository navigation
Dev/backend unification #413
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
| # This workflow is autogenerated by xcookie. | |
| # File kind: tests | |
| # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions | |
| # Based on ~/code/xcookie/xcookie/builders/github_actions.py | |
| # See: https://github.com/Erotemic/xcookie | |
| name: PurePyCI | |
| on: | |
| push: | |
| # Restricting push triggers to the default branch avoids running | |
| # the whole pipeline twice (push + pull_request events) for every | |
| # push to a PR branch. Feature branches are covered by the | |
| # pull_request trigger; release branches and tags are handled by | |
| # release.yml. | |
| branches: [ main ] | |
| pull_request: | |
| branches: [ main ] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| # Superseded runs on the same ref are cancelled; deploy-bearing refs | |
| # never trigger this workflow (release.yml owns them). | |
| cancel-in-progress: true | |
| jobs: | |
| lint_job: | |
| ## | |
| # Run quick linting and typing checks. | |
| # To disable all linting add "linter=false" to the xcookie config. | |
| # To disable type checks add "notypes" to the xcookie tags. | |
| ## | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout source | |
| uses: actions/checkout@v6.0.2 | |
| - name: Set up Python 3.14 for linting | |
| uses: actions/setup-python@v6.2.0 | |
| with: | |
| python-version: '3.14' | |
| - name: Install dependencies | |
| run: |- | |
| python -m pip install pip uv -U | |
| python -m uv pip install flake8 | |
| - name: Lint with flake8 | |
| run: |- | |
| # stop the build if there are Python syntax errors or undefined names | |
| flake8 ./infer_stack --count --select=E9,F63,F7,F82 --show-source --statistics | |
| - name: Typecheck | |
| run: |- | |
| python -m pip install ty | |
| pip install --prefer-binary -e ".[tests]" | |
| ty check ./infer_stack | |
| build_and_test_sdist: | |
| ## | |
| # Build the pure python package from source and test it in the | |
| # same environment. | |
| ## | |
| name: Build sdist | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout source | |
| uses: actions/checkout@v6.0.2 | |
| - name: Set up Python 3.14 | |
| uses: actions/setup-python@v6.2.0 | |
| with: | |
| python-version: '3.14' | |
| - name: Upgrade pip | |
| run: |- | |
| python -m pip install pip uv -U | |
| python -m pip install --prefer-binary -e ".[tests]" | |
| - name: Build sdist | |
| shell: bash | |
| run: |- | |
| python -m pip install pip uv -U | |
| python -m uv pip install setuptools>=77 wheel build twine | |
| python -m build --sdist --outdir wheelhouse | |
| python -m twine check ./wheelhouse/infer_stack*.tar.gz | |
| - name: Install sdist | |
| run: |- | |
| ls -al wheelhouse | |
| python -m pip install --prefer-binary wheelhouse/infer_stack*.tar.gz -v | |
| - name: Test minimal loose sdist | |
| env: {} | |
| run: |- | |
| pwd | |
| ls -al | |
| # Run in a sandboxed directory | |
| WORKSPACE_DNAME="testsrcdir_minimal_${CI_PYTHON_VERSION}_${GITHUB_RUN_ID}_${RUNNER_OS}" | |
| mkdir -p $WORKSPACE_DNAME | |
| cd $WORKSPACE_DNAME | |
| # Run the tests | |
| # Get path to installed package | |
| MOD_DPATH=$(python -c "import infer_stack, os; print(os.path.dirname(infer_stack.__file__))") | |
| echo "MOD_DPATH = $MOD_DPATH" | |
| MOD_NAME=infer_stack | |
| python -m pytest --verbose --cov=infer_stack $MOD_DPATH ../tests | |
| cd .. | |
| - name: Test full loose sdist | |
| env: {} | |
| run: |- | |
| pwd | |
| ls -al | |
| true | |
| # Run in a sandboxed directory | |
| WORKSPACE_DNAME="testsrcdir_full_${CI_PYTHON_VERSION}_${GITHUB_RUN_ID}_${RUNNER_OS}" | |
| mkdir -p $WORKSPACE_DNAME | |
| cd $WORKSPACE_DNAME | |
| # Run the tests | |
| # Get path to installed package | |
| MOD_DPATH=$(python -c "import infer_stack, os; print(os.path.dirname(infer_stack.__file__))") | |
| echo "MOD_DPATH = $MOD_DPATH" | |
| MOD_NAME=infer_stack | |
| python -m pytest --verbose --cov=infer_stack $MOD_DPATH ../tests | |
| cd .. | |
| - uses: actions/upload-artifact@v6.0.0 | |
| name: Upload sdist artifact | |
| with: | |
| name: sdist_wheels | |
| path: ./wheelhouse/infer_stack*.tar.gz | |
| build_purepy_wheels: | |
| ## | |
| # Build the pure-python wheels independently on a per-platform basis. | |
| # These will be tested later in the test_purepy_wheels step. | |
| ## | |
| name: Build wheel ${{ matrix.python-version }} on ${{ matrix.os }}, arch=${{ matrix.arch }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-latest | |
| python-version: | |
| - '3.14' | |
| arch: | |
| - auto | |
| steps: | |
| - name: Checkout source | |
| uses: actions/checkout@v6.0.2 | |
| - name: Setup Python | |
| uses: actions/setup-python@v6.2.0 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Build pure wheel | |
| shell: bash | |
| run: |- | |
| python -m pip install pip uv -U | |
| python -m uv pip install setuptools>=77 wheel build twine | |
| python -m build --wheel --outdir wheelhouse | |
| python -m twine check ./wheelhouse/infer_stack*.whl | |
| - name: Show built files | |
| shell: bash | |
| run: ls -la wheelhouse | |
| - uses: actions/upload-artifact@v6.0.0 | |
| name: Upload wheels artifact | |
| with: | |
| name: wheels-${{ matrix.os }}-${{ matrix.arch }} | |
| path: ./wheelhouse/infer_stack*.whl | |
| test_purepy_wheels: | |
| ## | |
| # Download and test the pure-python wheels that were built in the | |
| # build_purepy_wheels step in this independent environment. | |
| ## | |
| name: ${{ matrix.python-version }} on ${{ matrix.os }}, arch=${{ matrix.arch }} with ${{ matrix.install-extras }} | |
| runs-on: ${{ matrix.os }} | |
| needs: | |
| - build_purepy_wheels | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # Xcookie generates an explicit list of environments that will be used | |
| # for testing instead of using the more concise matrix notation. | |
| include: | |
| - python-version: '3.10' | |
| install-extras: tests | |
| os: ubuntu-latest | |
| arch: auto | |
| allow-prereleases: 'false' | |
| check-latest: 'false' | |
| use-lockfile: 'true' | |
| lock-requirements: requirements/locks/tests.txt | |
| - python-version: '3.14' | |
| install-extras: tests | |
| os: ubuntu-latest | |
| arch: auto | |
| allow-prereleases: 'false' | |
| check-latest: 'false' | |
| use-lockfile: 'true' | |
| lock-requirements: requirements/locks/tests.txt | |
| - python-version: '3.10' | |
| install-extras: tests | |
| os: ubuntu-latest | |
| arch: auto | |
| allow-prereleases: 'false' | |
| check-latest: 'false' | |
| use-lockfile: 'false' | |
| - python-version: '3.11' | |
| install-extras: tests | |
| os: ubuntu-latest | |
| arch: auto | |
| allow-prereleases: 'false' | |
| check-latest: 'false' | |
| use-lockfile: 'false' | |
| - python-version: '3.12' | |
| install-extras: tests | |
| os: ubuntu-latest | |
| arch: auto | |
| allow-prereleases: 'false' | |
| check-latest: 'false' | |
| use-lockfile: 'false' | |
| - python-version: '3.13' | |
| install-extras: tests | |
| os: ubuntu-latest | |
| arch: auto | |
| allow-prereleases: 'false' | |
| check-latest: 'false' | |
| use-lockfile: 'false' | |
| - python-version: '3.14' | |
| install-extras: tests | |
| os: ubuntu-latest | |
| arch: auto | |
| allow-prereleases: 'false' | |
| check-latest: 'false' | |
| use-lockfile: 'false' | |
| - python-version: '3.15' | |
| install-extras: tests | |
| os: ubuntu-latest | |
| arch: auto | |
| allow-prereleases: 'true' | |
| check-latest: 'true' | |
| experimental: true | |
| use-lockfile: 'false' | |
| steps: | |
| - name: Checkout source | |
| uses: actions/checkout@v6.0.2 | |
| - name: Setup Python | |
| uses: actions/setup-python@v6.2.0 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| allow-prereleases: ${{ matrix.allow-prereleases }} | |
| check-latest: ${{ matrix.check-latest }} | |
| id: setup_python | |
| continue-on-error: ${{ matrix.experimental || false }} | |
| - uses: actions/download-artifact@v7.0.0 | |
| name: Download wheels | |
| with: | |
| pattern: wheels-* | |
| merge-multiple: true | |
| path: wheelhouse | |
| - name: Install wheel ${{ matrix.install-extras }} | |
| id: install_wheel | |
| if: steps.setup_python.outcome == 'success' | |
| continue-on-error: ${{ matrix.experimental || false }} | |
| shell: bash | |
| env: | |
| INSTALL_EXTRAS: ${{ matrix.install-extras }} | |
| USE_UV_LOCK: ${{ matrix.use-lockfile }} | |
| LOCK_REQUIREMENTS: ${{ matrix.lock-requirements }} | |
| run: |- | |
| echo "Finding the path to the wheel" | |
| ls wheelhouse || echo "wheelhouse does not exist" | |
| echo "Installing helpers: update pip" | |
| python -m pip install pip uv -U | |
| echo "Installing helpers: setuptools" | |
| python -m uv pip install --resolution=highest setuptools>=77 setuptools_scm wheel build -U | |
| echo "Installing helpers: tomli and pkginfo" | |
| python -m uv pip install --resolution=highest tomli pkginfo packaging | |
| export WHEEL_FPATH=$(python -c "if 1: | |
| import pathlib | |
| from packaging import tags | |
| from packaging.utils import parse_wheel_filename | |
| dist_dpath = pathlib.Path('wheelhouse') | |
| wheels = sorted(dist_dpath.glob('infer_stack*.whl')) | |
| if wheels: | |
| sys_tags = set(tags.sys_tags()) | |
| matching = [] | |
| for w in wheels: | |
| try: | |
| _, _, _, wheel_tags = parse_wheel_filename(w.name) | |
| except Exception: | |
| continue | |
| if any(t in sys_tags for t in wheel_tags): | |
| matching.append(w) | |
| fpath = sorted(matching or wheels)[-1] | |
| else: | |
| sdists = sorted(dist_dpath.glob('infer_stack*.tar.gz')) | |
| if not sdists: | |
| raise SystemExit('No wheel artifacts found in wheelhouse') | |
| fpath = sdists[-1] | |
| print(str(fpath).replace(chr(92), chr(47))) | |
| ") | |
| echo "WHEEL_FPATH=$WHEEL_FPATH" | |
| echo "INSTALL_EXTRAS=$INSTALL_EXTRAS" | |
| echo "USE_UV_LOCK=$USE_UV_LOCK" | |
| echo "LOCK_REQUIREMENTS=$LOCK_REQUIREMENTS" | |
| if [[ -n "${INSTALL_EXTRAS:-}" ]]; then | |
| INSTALL_TARGET="${WHEEL_FPATH}[${INSTALL_EXTRAS}]" | |
| else | |
| INSTALL_TARGET="${WHEEL_FPATH}" | |
| fi | |
| echo "INSTALL_TARGET=$INSTALL_TARGET" | |
| LOCK_ARGS=() | |
| if [[ "${USE_UV_LOCK:-false}" == "true" ]]; then | |
| if [[ -z "${LOCK_REQUIREMENTS:-}" ]]; then | |
| echo "USE_UV_LOCK=true but LOCK_REQUIREMENTS is empty" | |
| exit 1 | |
| fi | |
| if [[ ! -f "$LOCK_REQUIREMENTS" ]]; then | |
| echo "Missing checked-in lock requirements: $LOCK_REQUIREMENTS" | |
| exit 1 | |
| fi | |
| echo "Using checked-in lock requirements: $LOCK_REQUIREMENTS" | |
| cat "$LOCK_REQUIREMENTS" | |
| LOCK_ARGS=(--constraint "$LOCK_REQUIREMENTS") | |
| fi | |
| python -m uv pip install --prerelease=allow "${LOCK_ARGS[@]}" "${INSTALL_TARGET}" | |
| echo "Install finished." | |
| - name: Test wheel ${{ matrix.install-extras }} | |
| id: test_wheel | |
| if: steps.install_wheel.outcome == 'success' | |
| continue-on-error: ${{ matrix.experimental || false }} | |
| shell: bash | |
| env: | |
| CI_PYTHON_VERSION: py${{ matrix.python-version }} | |
| run: |- | |
| echo "Creating test sandbox directory" | |
| export WORKSPACE_DNAME="testdir_${CI_PYTHON_VERSION}_${GITHUB_RUN_ID}_${RUNNER_OS}" | |
| echo "WORKSPACE_DNAME=$WORKSPACE_DNAME" | |
| mkdir -p $WORKSPACE_DNAME | |
| echo "cd-ing into the workspace" | |
| cd $WORKSPACE_DNAME | |
| pwd | |
| ls -altr | |
| # Get the path to the installed package and run the tests | |
| export MOD_DPATH=$(python -c "import infer_stack, os; print(os.path.dirname(infer_stack.__file__))") | |
| export MOD_NAME=infer_stack | |
| echo " | |
| --- | |
| MOD_DPATH = $MOD_DPATH | |
| --- | |
| running the pytest command inside the workspace | |
| --- | |
| " | |
| python -m pytest --verbose --xdoctest --cov-config ../pyproject.toml --cov-report term --durations=100 --cov="$MOD_NAME" "$MOD_DPATH" ../tests | |
| echo "pytest command finished, moving the coverage file to the repo root" | |
| ls -al | |
| # Move coverage file to a new name | |
| mv .coverage "../.coverage.$WORKSPACE_DNAME" | |
| echo "changing directory back to th repo root" | |
| cd .. | |
| ls -al | |
| - name: Combine coverage Linux | |
| if: runner.os == 'Linux' && steps.test_wheel.outcome == 'success' | |
| run: |- | |
| echo '############ PWD' | |
| pwd | |
| cp .wheelhouse/.coverage* . || true | |
| ls -al | |
| uv pip install coverage[toml] | pip install coverage[toml] | |
| echo '############ combine' | |
| coverage combine . || true | |
| echo '############ XML' | |
| coverage xml -o ./coverage.xml || true | |
| echo '### The cwd should now have a coverage.xml' | |
| ls -altr | |
| pwd | |
| - uses: codecov/codecov-action@v5.5.2 | |
| name: Codecov Upload | |
| with: | |
| file: ./coverage.xml | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| if: steps.test_wheel.outcome == 'success' | |
| - name: Report experimental failure | |
| if: matrix.experimental && (steps.setup_python.outcome == 'failure' || steps.install_wheel.outcome == 'failure' || steps.test_wheel.outcome == 'failure') | |
| shell: bash | |
| run: |- | |
| message="Experimental matrix entry failed; see logs above." | |
| echo "::warning title=Experimental CI failure::$message" | |
| echo "### Experimental CI failure" >> "$GITHUB_STEP_SUMMARY" | |
| echo "$message" >> "$GITHUB_STEP_SUMMARY" | |