Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
03e8969
Add sweep strategy variants, fix sweeps optimizer state indexing, fix…
emapuljak Apr 27, 2026
2ce254a
Fix docs
emapuljak Apr 27, 2026
1b46d4c
edit docs
emapuljak Apr 28, 2026
ffe3ea5
Change year in license
emapuljak Apr 28, 2026
ba97af8
ruff, mypy, bandit, pytest fixes
emapuljak Apr 28, 2026
02217e5
add ci and pre-merge checks
emapuljak Apr 28, 2026
d79baf8
Fixes in setup
emapuljak Apr 28, 2026
5528d13
Add ruff related rules
emapuljak Apr 28, 2026
60383e4
Add version update in ci/cd
emapuljak Apr 28, 2026
f1deab1
update docs paths, inherit version number
emapuljak Apr 28, 2026
84289ed
add embedding tests
emapuljak Apr 28, 2026
55feb3d
Add new tests
emapuljak Apr 28, 2026
98bde32
Fix sweeping strategy
emapuljak Apr 28, 2026
3e1400e
Fix docs
emapuljak Apr 28, 2026
556f295
mypy, ruff fixes
emapuljak Apr 29, 2026
36127bd
Add matplotlib as dependency
emapuljak Apr 29, 2026
6011775
mypy fixes
emapuljak Apr 29, 2026
4c048da
Fix pytest
emapuljak Apr 29, 2026
88afb4b
Fix jit compilation in model.py
emapuljak May 4, 2026
6fa2efb
Update model.py for better cpu usage
emapuljak May 6, 2026
942ec76
Update published paper
emapuljak Jun 5, 2026
91d5a67
Update tn-tutorial nb
emapuljak Jun 5, 2026
63a6088
Update ci pipeline with ntbs
emapuljak Jun 5, 2026
01d58fa
Update images in examples
emapuljak Jun 8, 2026
2d33293
Add check badges in readme
emapuljak Jun 8, 2026
872004f
Add pre-commit
emapuljak Jun 8, 2026
10a0cae
examples updated
emapuljak Jun 8, 2026
04bc853
Remove placeholder badges
emapuljak Jun 8, 2026
497baf2
Update smpo, fix mypy, ruff
emapuljak Jun 9, 2026
9540370
Update gitignore
emapuljak Jun 9, 2026
c825127
Update model.save
emapuljak Jun 9, 2026
7202e18
Small fix in syntax, save to tmp
emapuljak Jun 9, 2026
7c009d4
Update ntbs, fix tests
emapuljak Jun 9, 2026
1739f3a
rename test to tests
emapuljak Jun 9, 2026
7f59aa4
Rename test to tests
emapuljak Jun 9, 2026
aaa8485
update mypy tools
emapuljak Jun 9, 2026
d8dacf1
add mypy and ruff checks on all code
emapuljak Jun 9, 2026
bb3dd5e
Remove python below 3.10, mypy, ruff fixes
emapuljak Jun 9, 2026
465e274
mypy fix
emapuljak Jun 9, 2026
839a590
pytest fix
emapuljak Jun 9, 2026
e63dc37
pytest fixes
emapuljak Jun 9, 2026
d944cf7
Fix smpo
emapuljak Jun 10, 2026
60f3ff4
Update timeout in CI
emapuljak Jun 10, 2026
757a838
Add extra dependencies
emapuljak Jun 10, 2026
3fcd822
Update notebooks
emapuljak Jun 10, 2026
2e32eff
Update batching func in model.py
emapuljak Jun 10, 2026
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
134 changes: 134 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
name: CI

on:
push:
branches: ["main", "master", "develop"]
pull_request: # runs on every PR regardless of target branch

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

jobs:
# ──────────────────────────────────────────────
# 1. Ruff – fast linting and import sorting
# ──────────────────────────────────────────────
ruff:
name: "Lint · ruff"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install ruff
run: pip install ruff
- name: Run ruff check
run: ruff check .
- name: Run ruff format check
run: ruff format --check .

# ──────────────────────────────────────────────
# 2. Mypy – static type checking
# ──────────────────────────────────────────────
mypy:
name: "Types · mypy"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install package + type stubs
run: |
pip install --upgrade pip
pip install -e ".[test]"
pip install mypy types-setuptools numpy
- name: Run mypy
run: mypy .

# ──────────────────────────────────────────────
# 3. Bandit – security vulnerability scanner
# ──────────────────────────────────────────────
bandit:
name: "Security · bandit"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install bandit
run: pip install bandit[toml]
- name: Run bandit
run: bandit -r tn4ml/ -ll -x tn4ml/scipy/

# ──────────────────────────────────────────────
# 4. Pytest – unit tests
# ──────────────────────────────────────────────
pytest:
name: "Tests · pytest (${{ matrix.python-version }})"
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install --upgrade pip
pip install -e ".[test]"
pip install pytest
- name: Run pytest
run: pytest tests/ -v --tb=short

# ──────────────────────────────────────────────
# 5. Coverage – measure test coverage
# ──────────────────────────────────────────────
coverage:
name: "Coverage · pytest-cov"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
pip install --upgrade pip
pip install -e ".[test]"
pip install pytest pytest-cov
- name: Run tests with coverage
run: |
pytest tests/ --cov=tn4ml --cov-report=xml --cov-report=term-missing --cov-fail-under=50
- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage.xml

# ──────────────────────────────────────────────
# 6. Nbmake – validate example notebooks
# ──────────────────────────────────────────────
nbmake:
name: "Notebooks · nbmake"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
pip install --upgrade pip
pip install -e ".[test,examples]"
pip install pytest nbmake ipykernel
- name: Run notebooks
run: |
pytest --nbmake docs/source/examples/ \
--nbmake-timeout=900 \
-v
105 changes: 105 additions & 0 deletions .github/workflows/pre-merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Pre-merge checks

# Lightweight fast checks that run on every push to feature branches
# (i.e. anything that is NOT a protected branch). This gives quick
# feedback before a PR is even opened.

on:
push:
branches-ignore:
- main
- master
- develop

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

jobs:
# ──────────────────────────────────────────────
# 1. Ruff – linting (fast, <10 s)
# ──────────────────────────────────────────────
ruff:
name: "Lint · ruff"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- run: pip install ruff
- run: ruff check .
- run: ruff format --check .

# ──────────────────────────────────────────────
# 2. Mypy – type check (catches obvious breakage)
# ──────────────────────────────────────────────
mypy:
name: "Types · mypy"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
pip install --upgrade pip
pip install -e ".[test]"
pip install mypy types-setuptools numpy
- run: mypy .

# ──────────────────────────────────────────────
# 3. Bandit – security scan
# ──────────────────────────────────────────────
bandit:
name: "Security · bandit"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- run: pip install bandit[toml]
- run: bandit -r tn4ml/ -ll -x tn4ml/scipy/

# ──────────────────────────────────────────────
# 4. Pytest – unit tests only (no coverage overhead)
# ──────────────────────────────────────────────
pytest:
name: "Tests · pytest (${{ matrix.python-version }})"
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install --upgrade pip
pip install -e ".[test]"
pip install pytest
- name: Run tests
run: pytest tests/ -v --tb=short

# ──────────────────────────────────────────────
# Summary gate job – required status check target
# ──────────────────────────────────────────────
pre-merge-ok:
name: "Pre-merge · all checks passed"
runs-on: ubuntu-latest
needs: [ruff, mypy, bandit, pytest]
if: always()
steps:
- name: Check all jobs succeeded
run: |
if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" || \
"${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then
echo "One or more pre-merge checks failed."
exit 1
fi
echo "All pre-merge checks passed."
87 changes: 87 additions & 0 deletions .github/workflows/version-bump.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: Version bump

# Runs when a PR is merged into main/master.
# Add one of these labels to the PR to control the bump:
# bump:patch → 1.0.5 → 1.0.6
# bump:minor → 1.0.5 → 1.1.0
# bump:major → 1.0.5 → 2.0.0
# No label → no version change.

on:
pull_request:
types: [closed]
branches: [main, master]

jobs:
bump:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
permissions:
contents: write

steps:
- uses: actions/checkout@v4
with:
# Use a PAT so the commit can trigger downstream CI.
# Falls back to GITHUB_TOKEN (commit won't re-trigger CI).
token: ${{ secrets.BUMP_TOKEN || secrets.GITHUB_TOKEN }}
ref: ${{ github.event.pull_request.base.ref }}

- name: Determine bump type from PR labels
id: bump
run: |
LABELS='${{ toJson(github.event.pull_request.labels.*.name) }}'
if echo "$LABELS" | grep -q '"bump:major"'; then
echo "type=major" >> $GITHUB_OUTPUT
elif echo "$LABELS" | grep -q '"bump:minor"'; then
echo "type=minor" >> $GITHUB_OUTPUT
elif echo "$LABELS" | grep -q '"bump:patch"'; then
echo "type=patch" >> $GITHUB_OUTPUT
else
echo "type=none" >> $GITHUB_OUTPUT
fi

- name: Bump version in setup.py
if: steps.bump.outputs.type != 'none'
id: version
run: |
python - <<'EOF'
import re, os

bump = os.environ["BUMP_TYPE"]

with open("setup.py") as f:
content = f.read()

m = re.search(r'version="(\d+)\.(\d+)\.(\d+)"', content)
major, minor, patch = int(m.group(1)), int(m.group(2)), int(m.group(3))

if bump == "major":
major, minor, patch = major + 1, 0, 0
elif bump == "minor":
major, minor, patch = major, minor + 1, 0
else:
patch += 1

new_version = f"{major}.{minor}.{patch}"
new_content = re.sub(r'version="\d+\.\d+\.\d+"', f'version="{new_version}"', content)

with open("setup.py", "w") as f:
f.write(new_content)

with open(os.environ["GITHUB_OUTPUT"], "a") as out:
out.write(f"new_version={new_version}\n")

print(f"Bumped to {new_version}")
EOF
env:
BUMP_TYPE: ${{ steps.bump.outputs.type }}

- name: Commit and push
if: steps.bump.outputs.type != 'none'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add setup.py
git commit -m "chore: bump version to ${{ steps.version.outputs.new_version }}"
git push
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ venv.bak/
.dmypy.json
dmypy.json

# ruff
.ruff_cache/

# Pyre type checker
.pyre/

Expand Down Expand Up @@ -299,4 +302,4 @@ $RECYCLE.BIN/
/docs/source/examples/supervised/results
/docs/source/examples/unsupervised/results
/docs/source/examples/supervised/results_*
/docs/source/examples/supervised/plots
/docs/source/examples/supervised/plots
44 changes: 44 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-added-large-files
- id: check-merge-conflict
- id: check-toml
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace

- repo: https://github.com/kynan/nbstripout
rev: 0.9.1
hooks:
- id: nbstripout
args:
- "--keep-output"
- "--keep-count"
- "--extra-keys=metadata.kernelspec metadata.language_info"

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.14
hooks:
- id: ruff-check
args: ["--fix"]
- id: ruff-format

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v2.1.0
hooks:
- id: mypy
args: ["."]
pass_filenames: false
additional_dependencies:
- numpy
- types-setuptools

- repo: https://github.com/PyCQA/bandit
rev: 1.9.0
hooks:
- id: bandit
args: ["-ll"]
files: ^tn4ml/
exclude: ^tn4ml/scipy/
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 BSC - Quantic
Copyright (c) 2026 BSC - Quantic

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
Loading
Loading