Skip to content

Commit 8be1788

Browse files
authored
Modernize package (#306)
* Modernize package * Apply ruff formatting * Ignore typing * Additional updates * Move to hatchling! * Use pypi OIDC * Fix failing github actions * Update changelog
1 parent 442d9ab commit 8be1788

28 files changed

Lines changed: 1891 additions & 218 deletions

.github/workflows/ci.yml

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,19 @@ on:
1010
branches: [ main ]
1111

1212
jobs:
13+
build_smoke:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
- name: Set up Python 3.14
18+
uses: actions/setup-python@v5
19+
with:
20+
python-version: '3.14'
21+
- name: Set up uv
22+
uses: astral-sh/setup-uv@v6
23+
- name: Build package
24+
run: uv build
25+
1326
build_multi_os:
1427
runs-on: ${{ matrix.os }}
1528
strategy:
@@ -23,16 +36,16 @@ jobs:
2336
uses: actions/setup-python@v5
2437
with:
2538
python-version: ${{ matrix.python-version }}
39+
- name: Set up uv
40+
uses: astral-sh/setup-uv@v6
2641
- name: Install dependencies
27-
run: |
28-
python -m pip install -r requirements.txt
29-
python -m pip install -r requirements_dev.txt
42+
run: uv sync --locked --group dev
3043
- name: Run pytest
3144
run: |
32-
pytest
33-
codecov
45+
uv run pytest
46+
uv run codecov
3447
# run benchmark tests
35-
pytest -c "." --benchmark-storage=.benchmarks/${{ runner.os == 'macOS' && 'Darwin' || runner.os }}-CPython-${{ matrix.python-version }}-64bit/ --benchmark-compare=0001 --benchmark-compare-fail=mean:10% --benchmark-columns='mean,median,stddev,iqr' tests/benchmarks.py
48+
uv run pytest -c "." --benchmark-storage=.benchmarks/${{ runner.os == 'macOS' && 'Darwin' || runner.os }}-CPython-${{ matrix.python-version }}-64bit/ --benchmark-compare=0001 --benchmark-compare-fail=mean:15% --benchmark-columns='mean,median,stddev,iqr' tests/benchmarks.py
3649
3750
build_multi_py_versions:
3851
runs-on: ${{ matrix.os }}
@@ -47,11 +60,11 @@ jobs:
4760
uses: actions/setup-python@v5
4861
with:
4962
python-version: ${{ matrix.python-version }}
63+
- name: Set up uv
64+
uses: astral-sh/setup-uv@v6
5065
- name: Install dependencies
51-
run: |
52-
python -m pip install -r requirements.txt
53-
python -m pip install -r requirements_dev.txt
66+
run: uv sync --locked --group dev
5467
- name: Run pytest
5568
run: |
56-
pytest
57-
codecov
69+
uv run pytest
70+
uv run codecov

.github/workflows/lint.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ jobs:
1818
uses: actions/setup-python@v5
1919
with:
2020
python-version: '3.14'
21+
- name: Set up uv
22+
uses: astral-sh/setup-uv@v6
2123
- name: Install dependencies
22-
run: |
23-
python -m pip install -r requirements.txt
24-
python -m pip install -r requirements_dev.txt
24+
run: uv sync --locked --group dev
2525
- name: Lint
2626
env:
2727
CONTEXT: ci
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
# This workflow will upload a Python Package using Twine when a release is created
2-
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
1+
# This workflow will upload a Python Package to PyPI when a release is created
2+
# Uses PyPI trusted publishing (OIDC) — no secrets required.
3+
# Configure at: https://pypi.org/manage/project/ioc-finder/settings/publishing/
34

45
name: Upload Python Package to PyPi
56

@@ -13,6 +14,10 @@ jobs:
1314

1415
runs-on: ubuntu-latest
1516

17+
permissions:
18+
id-token: write # required for OIDC trusted publishing
19+
contents: read
20+
1621
steps:
1722
- uses: actions/checkout@v4
1823
with:
@@ -25,14 +30,9 @@ jobs:
2530
uses: actions/setup-python@v5
2631
with:
2732
python-version: '3.x'
28-
- name: Install dependencies
29-
run: |
30-
python -m pip install --upgrade pip
31-
pip install setuptools wheel twine
32-
- name: Build and publish
33-
env:
34-
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
35-
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
36-
run: |
37-
python setup.py sdist bdist_wheel
38-
twine upload dist/*
33+
- name: Set up uv
34+
uses: astral-sh/setup-uv@v6
35+
- name: Build
36+
run: uv build
37+
- name: Publish to PyPI
38+
uses: pypa/gh-action-pypi-publish@release/v1

.github/workflows/windows-benchmark-baseline.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,16 @@ jobs:
3131
with:
3232
python-version: ${{ env.PYTHON_VERSION }}
3333

34+
- name: Set up uv
35+
uses: astral-sh/setup-uv@v6
36+
3437
- name: Install dependencies
35-
run: |
36-
python -m pip install -r requirements.txt
37-
python -m pip install -r requirements_dev.txt
38+
run: uv sync --locked --group dev
3839

3940
- name: Generate benchmark baseline
4041
shell: pwsh
4142
run: |
42-
pytest -c "." --benchmark-storage=.benchmarks/ --benchmark-save=benchmark tests/benchmarks.py
43+
uv run pytest -c "." --benchmark-storage=.benchmarks/ --benchmark-save=benchmark tests/benchmarks.py
4344
4445
$benchDir = ".benchmarks/Windows-CPython-${{ env.PYTHON_VERSION }}-64bit"
4546
if (-not (Test-Path $benchDir)) {

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ __pycache__/
99
# Distribution / packaging
1010
.Python
1111
env/
12+
.venv/
1213
build/
1314
develop-eggs/
1415
dist/
@@ -65,3 +66,5 @@ target/
6566
travis_pypi_setup.py
6667
Pipfile
6768
Pipfile.lock
69+
70+
.DS_Store

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ which are unliklely to be found in the wild
3030
### Removed
3131

3232
- Formal support for Python < 3.10
33+
- `setup.py`, `setup.cfg`, and `mypy.ini` (configuration consolidated into `pyproject.toml`)
34+
35+
### Changed
36+
37+
- Migrated from pip/setuptools to uv for dependency management and packaging
38+
- Switched build backend from setuptools to hatchling
39+
- Replaced flake8, black, isort, and pylint with ruff for linting and formatting
40+
- Switched PyPI publishing to trusted publishing (OIDC) — no more username/password secrets
41+
- Updated Dockerfile base image from `python:3.10.2-buster` to `python:3.14-slim-bookworm`
42+
- Updated CI, Docker, Makefile, and docs to use uv throughout
43+
- Relaxed benchmark regression threshold from 10% to 15% to reduce flaky CI failures
3344

3445
## [7.3.0] - 2022.12.22
3546

CONTRIBUTING.rst

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,25 +64,21 @@ Ready to contribute? Here's how to set up `ioc_finder` for local development.
6464

6565
$ git clone [email protected]:<your_github_username_here>/ioc_finder.git
6666

67-
3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development::
67+
3. Install your local copy. Install `uv <https://docs.astral.sh/uv/>`_ then set up your fork for local development::
6868

69-
$ mkvirtualenv ioc_finder
7069
$ cd ioc_finder/
71-
$ python setup.py develop
70+
$ uv sync --locked --group dev
7271

7372
4. Create a branch for local development::
7473

7574
$ git checkout -b name-of-your-bugfix-or-feature
7675

7776
Now you can make your changes locally.
7877

79-
5. When you're done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox::
78+
5. When you're done making changes, check that your changes pass linting and the tests::
8079

81-
$ flake8 ioc_finder tests
82-
$ python setup.py test or py.test
83-
$ tox
84-
85-
To get flake8 and tox, just pip install them into your virtualenv.
80+
$ uv run ruff check ioc_finder tests
81+
$ uv run pytest
8682

8783
6. Commit your changes and push your branch to GitHub::
8884

@@ -101,8 +97,7 @@ Before you submit a pull request, check that it meets these guidelines:
10197
2. If the pull request adds functionality, the docs should be updated. Put
10298
your new functionality into a function with a docstring, and add the
10399
feature to the list in README.md.
104-
3. The pull request should work for Python 2.6, 2.7, 3.3, 3.4 and 3.5, and for PyPy. Check
105-
https://travis-ci.org/fhightower/ioc-finder/pull_requests
100+
3. The pull request should work for Python 3.10+. Check the GitHub Actions CI
106101
and make sure that the tests pass for all supported Python versions.
107102

108103
Tips
@@ -111,4 +106,3 @@ Tips
111106
To run a subset of tests::
112107

113108
$ py.test tests.test_ioc_finder
114-

Dockerfile

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
FROM python:3.10.2-buster
1+
FROM python:3.14-slim-bookworm
22

3-
ENV PIP_NO_CACHE_DIR "true"
3+
ENV UV_LINK_MODE=copy
44

5-
COPY ./requirements*.txt /code/
5+
COPY --from=ghcr.io/astral-sh/uv:0.9.28 /uv /uvx /bin/
66

77
WORKDIR /code
88

9-
RUN pip install -r requirements.txt -r requirements_dev.txt
9+
COPY . /code
10+
11+
RUN uv sync --locked --group dev

Makefile

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: clean clean-test clean-pyc clean-build docs help
1+
.PHONY: clean clean-test clean-pyc clean-build docs help init install lint test test-all coverage dist pypi export-requirements
22
.DEFAULT_GOAL := help
33
define BROWSER_PYSCRIPT
44
import os, webbrowser, sys
@@ -26,6 +26,8 @@ BROWSER := python -c "$$BROWSER_PYSCRIPT"
2626
help:
2727
@python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST)
2828

29+
UV := uv
30+
2931
clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts
3032

3133

@@ -47,21 +49,22 @@ clean-test: ## remove test and coverage artifacts
4749
rm -f .coverage
4850
rm -fr htmlcov/
4951

50-
lint: ## check style with flake8
51-
flake8 ioc_finder tests
52+
lint: ## check style with ruff and mypy
53+
$(UV) run ruff check ioc_finder tests
54+
$(UV) run mypy ioc_finder tests
5255

5356
test: ## run tests quickly with the default Python
54-
py.test
57+
$(UV) run pytest
5558

5659

5760
test-all: ## run tests on every Python version with tox
58-
tox
61+
$(UV) run pytest
5962

6063
coverage: ## check code coverage quickly with the default Python
61-
coverage run --source ioc_finder -m pytest
64+
$(UV) run coverage run --source ioc_finder -m pytest
6265

63-
coverage report -m
64-
coverage html
66+
$(UV) run coverage report -m
67+
$(UV) run coverage html
6568
$(BROWSER) htmlcov/index.html
6669

6770
docs: ## generate Sphinx HTML documentation, including API docs
@@ -76,26 +79,26 @@ servedocs: docs ## compile the docs watching for changes
7679
watchmedo shell-command -p '*.rst' -c '$(MAKE) -C docs html' -R -D .
7780

7881
release: clean ## package and upload a release
79-
python setup.py sdist upload
80-
python setup.py bdist_wheel upload
82+
$(UV) build
83+
$(UV) publish
8184

8285
dist: clean ## builds source and wheel package
83-
python setup.py sdist
84-
python setup.py bdist_wheel
86+
$(UV) build
8587
ls -l dist
8688

8789
install: clean ## install the package to the active Python's site-packages
88-
python setup.py install
90+
$(UV) sync --locked --group dev
8991

9092
upstream: ## set the upstream for the repository
9193
git remote set-upstream https://github.com/fhightower/ioc-finder.git
9294

93-
init: ## install the development requirements with pip (related to python2.x)
94-
pip install -r requirements_dev.txt
95+
init: ## install the project and development requirements with uv
96+
$(UV) sync --locked --group dev
9597

96-
init3: ## install the development requirements with pip3 (related to python3.x)
97-
pip3 install -r requirements_dev.txt
98+
export-requirements: ## regenerate compatibility requirements files from pyproject.toml
99+
$(UV) export --frozen --no-hashes --no-emit-project --format requirements-txt --no-dev -o requirements.txt
100+
$(UV) export --frozen --no-hashes --no-emit-project --format requirements-txt --all-groups -o requirements_dev.txt
98101

99102
pypi: clean ## upload the code to pypi
100-
python3 setup.py sdist bdist_wheel
101-
python3 -m twine upload dist/*
103+
$(UV) build
104+
$(UV) publish

docker-compose.yml

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,41 +12,28 @@ services:
1212

1313
dev:
1414
<<: *base
15-
command: ipython
15+
command: uv run ipython
1616

1717
mkdocs:
1818
<<: *base
19-
entrypoint: "mkdocs"
2019
ports:
2120
- "8000:8000"
22-
command: ["serve", "--dev-addr=0.0.0.0:8000"]
23-
24-
bump-patch:
25-
<<: *base
26-
command: bumpversion patch
27-
28-
bump-minor:
29-
<<: *base
30-
command: bumpversion minor
31-
32-
bump-major:
33-
<<: *base
34-
command: bumpversion major
21+
command: ["uv", "run", "mkdocs", "serve", "--dev-addr=0.0.0.0:8000"]
3522

3623
test:
3724
<<: *base
38-
command: pytest
25+
command: uv run pytest
3926

4027
test-benchmarks:
4128
<<: *base
4229
# the `-c "."` prevents pytest from using the config specified in the pyproject.toml (which we don't want to use for benchmarks)
43-
command: pytest -c "." --benchmark-storage=.benchmarks/Linux-CPython-3.10-64bit/ --benchmark-compare=0001 --benchmark-compare-fail=mean:10% --benchmark-columns='mean,median,stddev,iqr' tests/benchmarks.py
30+
command: uv run pytest -c "." --benchmark-storage=.benchmarks/Linux-CPython-3.10-64bit/ --benchmark-compare=0001 --benchmark-compare-fail=mean:15% --benchmark-columns='mean,median,stddev,iqr' tests/benchmarks.py
4431

4532
update-benchmarks:
4633
<<: *base
4734
command: >
4835
bash -c "
49-
pytest -c '.' --benchmark-storage=.benchmarks/ --benchmark-save=benchmark tests/benchmarks.py &&
36+
uv run pytest -c '.' --benchmark-storage=.benchmarks/ --benchmark-save=benchmark tests/benchmarks.py &&
5037
mv .benchmarks/Linux-CPython-3.10-64bit/0002_benchmark.json .benchmarks/Linux-CPython-3.10-64bit/0001_benchmark.json"
5138
5239
lint:

0 commit comments

Comments
 (0)