Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,2 +1,22 @@
[flake8]
max-line-length = 120
max-line-length = 120

# Black owns formatting. E203/W503 disagree with it outright, and E501 covers the
# lines it cannot split (long string literals, URLs, embedded markup).
extend-ignore = E203, E501, W503

per-file-ignores =
# re-exports are the point of this module
trustee/__init__.py:F401,F403
# sys.path has to be patched before `import trustee`
docs/conf.py:E402
# these bindings pair with deliberately commented-out ax.bar_label() calls
trustee/utils/plot.py:F841

exclude =
.git,
__pycache__,
build,
dist,
docs/auto_examples,
.venv
119 changes: 119 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
name: Release

on:
release:
types: [published]
workflow_dispatch:
inputs:
target:
description: "Where to publish"
required: true
default: testpypi
type: choice
options: [testpypi, pypi]

concurrency:
group: release
cancel-in-progress: false

env:
POETRY_VERSION: "2.1.1"

jobs:
build:
name: Build and verify
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v7

- uses: actions/setup-python@v7
with:
python-version: "3.12"

- name: Install Graphviz
run: sudo apt-get update && sudo apt-get install -y graphviz

- name: Install Poetry
run: pipx install poetry==${{ env.POETRY_VERSION }}

- name: Resolve and cross-check the version
id: version
run: |
pyproject_version="$(poetry version --short)"
module_version="$(python -c 'import re,pathlib; print(re.search(r"\"(.+)\"", pathlib.Path("trustee/_version.py").read_text()).group(1))')"

if [ "$pyproject_version" != "$module_version" ]; then
echo "::error::pyproject.toml ($pyproject_version) and trustee/_version.py ($module_version) disagree"
exit 1
fi

# A tagged release must match the version in the tree, or we would
# publish something other than what the tag claims.
if [ "${{ github.event_name }}" = "release" ]; then
tag_version="${GITHUB_REF_NAME#v}"
if [ "$pyproject_version" != "$tag_version" ]; then
echo "::error::tag $GITHUB_REF_NAME does not match version $pyproject_version"
exit 1
fi
fi

echo "version=$pyproject_version" >> "$GITHUB_OUTPUT"
echo "Releasing $pyproject_version"

- name: Install project
run: poetry install --with dev

# Never publish a build whose tests did not pass.
- name: Run tests
run: poetry run pytest -q

- name: Build
run: poetry build

- name: Check metadata
run: |
pipx install twine
twine check dist/*

- uses: actions/upload-artifact@v7
with:
name: dist
path: dist/

testpypi:
name: Publish to TestPyPI
needs: build
if: github.event_name == 'workflow_dispatch' && inputs.target == 'testpypi'
runs-on: ubuntu-latest
environment:
name: testpypi
url: https://test.pypi.org/p/trustee
permissions:
id-token: write # required for Trusted Publishing
steps:
- uses: actions/download-artifact@v8
with:
name: dist
path: dist/
- uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/

pypi:
name: Publish to PyPI
needs: build
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.target == 'pypi')
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/trustee
permissions:
id-token: write # required for Trusted Publishing
steps:
- uses: actions/download-artifact@v8
with:
name: dist
path: dist/
- uses: pypa/gh-action-pypi-publish@release/v1
44 changes: 36 additions & 8 deletions .github/workflows/sphinx.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,52 @@
name: Sphinx build
name: Docs

on:
push:
branches:
- master
branches: [master]
pull_request:
workflow_dispatch:

concurrency:
group: docs-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build docs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v7

- uses: actions/setup-python@v7
with:
python-version: "3.12"
cache: pip
cache-dependency-path: docs/requirements.txt

# sphinx-gallery executes examples/, which render trees through `dot`.
- name: Install Graphviz
run: sudo apt-get update && sudo apt-get install -y graphviz

- name: Install documentation dependencies
run: |
python -m pip install --upgrade pip
pip install -r docs/requirements.txt

- name: Build HTML
uses: ammaraskar/sphinx-action@master
- name: Upload artifacts
uses: actions/upload-artifact@v3
# -W turns warnings into errors so broken references fail the build.
env:
MPLBACKEND: Agg
run: python -m sphinx -b html -W --keep-going docs docs/build/html

- uses: actions/upload-artifact@v7
with:
name: html-docs
path: docs/build/html/

- name: Deploy
uses: peaceiris/actions-gh-pages@v3
# Only publish from master, never from a pull request.
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: peaceiris/actions-gh-pages@v4
with:
deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
external_repository: TrusteeML/trusteeml.github.io
Expand Down
142 changes: 142 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
name: Test

on:
push:
branches: [master]
pull_request:
workflow_dispatch:

concurrency:
group: test-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
POETRY_VERSION: "2.1.1"

jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.12"
- name: Install Poetry
run: pipx install poetry==${{ env.POETRY_VERSION }}
- name: Check pyproject and lock file are consistent
run: poetry check --lock
- name: Install dev dependencies
run: poetry install --only dev --no-root
- name: black
run: poetry run black --check --diff trustee/ examples/ tests/ docs/conf.py
- name: flake8
run: poetry run flake8 trustee/ examples/ tests/ docs/conf.py

test:
name: Test (Python ${{ matrix.python-version }}, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ["3.11", "3.12", "3.13", "3.14"]
include:
# Spot-check the other platforms on a single interpreter.
- os: macos-latest
python-version: "3.12"
- os: windows-latest
python-version: "3.12"
steps:
- uses: actions/checkout@v7

- uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}

# The TrustReport tests render decision trees through the `dot` binary.
# Without it those tests skip themselves rather than fail.
- name: Install Graphviz (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y graphviz
- name: Install Graphviz (macOS)
if: runner.os == 'macOS'
run: brew install graphviz
- name: Install Graphviz (Windows)
if: runner.os == 'Windows'
run: choco install graphviz --no-progress -y

- name: Install Poetry
run: pipx install poetry==${{ env.POETRY_VERSION }}

- name: Install project
run: poetry install --with dev

- name: Run tests
run: poetry run pytest -v

examples:
name: Examples
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.12"
- name: Install Graphviz
run: sudo apt-get update && sudo apt-get install -y graphviz
- name: Install Poetry
run: pipx install poetry==${{ env.POETRY_VERSION }}
- name: Install project
run: poetry install
- name: Run the shipped examples
# These are rendered into the docs by sphinx-gallery, so a failure here
# means the published documentation is broken too.
env:
MPLBACKEND: Agg
run: |
# Invoke the venv interpreter directly: `poetry run` would reset the
# working directory, and these examples write their output into cwd.
venv_python="$(poetry env info --executable)"
mkdir -p /tmp/examples && cd /tmp/examples
for example in "$GITHUB_WORKSPACE"/examples/*.py; do
echo "::group::$(basename "$example")"
"$venv_python" "$example"
echo "::endgroup::"
done

build:
name: Build distributions
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.12"
- name: Install Poetry
run: pipx install poetry==${{ env.POETRY_VERSION }}
- name: Verify the version is declared consistently
run: |
pyproject_version="$(poetry version --short)"
module_version="$(python -c 'import re,pathlib; print(re.search(r"\"(.+)\"", pathlib.Path("trustee/_version.py").read_text()).group(1))')"
echo "pyproject.toml: $pyproject_version"
echo "_version.py: $module_version"
if [ "$pyproject_version" != "$module_version" ]; then
echo "::error::pyproject.toml ($pyproject_version) and trustee/_version.py ($module_version) disagree"
exit 1
fi
- name: Build
run: poetry build
- name: Check metadata
run: |
pipx install twine
twine check dist/*
- name: Verify the wheel imports on its own
run: |
python -m venv /tmp/wheeltest
/tmp/wheeltest/bin/pip install --quiet dist/*.whl
/tmp/wheeltest/bin/python -c "import trustee; print('trustee', trustee.__version__)"
- uses: actions/upload-artifact@v7
with:
name: dist
path: dist/
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,10 @@ dmypy.json
dataset/
*.pdf
dt_*

# Output written by the scripts in examples/ when run from the repo root
/out/
/dt_explanation
/dt_explanation.pdf
/pruned_dt_explation
/pruned_dt_explation.pdf
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ This section contains basic information and instructions to get started with Tru

### Python Version

Trustee supports `Python >=3.7`.
Trustee supports `Python >=3.11`.

### Install Trustee

Expand Down
Loading
Loading