From d1fc10425d97b1937d8c32e436777a00e06d095e Mon Sep 17 00:00:00 2001 From: Tim Case Date: Tue, 5 May 2026 08:59:17 -0500 Subject: [PATCH 1/6] Version bumps automatically when VERSION file is bumped --- VERSION | 2 +- bitmath.1 | 6 +++--- pyproject.toml | 6 +++++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index 38f77a6..e9307ca 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.1 +2.0.2 diff --git a/bitmath.1 b/bitmath.1 index 3bbd11f..461069d 100644 --- a/bitmath.1 +++ b/bitmath.1 @@ -2,12 +2,12 @@ .\" Title: bitmath .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 05/04/2026 +.\" Date: 05/05/2026 .\" Manual: python-bitmath -.\" Source: bitmath 2.0.1 +.\" Source: bitmath 2.0.2 .\" Language: English .\" -.TH "BITMATH" "1" "05/04/2026" "bitmath 2\&.0\&.1" "python\-bitmath" +.TH "BITMATH" "1" "05/05/2026" "bitmath 2\&.0\&.2" "python\-bitmath" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml index 2749282..c729a41 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "bitmath" -version = "2.0.1" +dynamic = ["version"] description = "Pythonic module for representing and manipulating file sizes with different prefix notations (file size unit conversion)" readme = "README.rst" requires-python = ">=3.9" @@ -78,6 +78,10 @@ exclude = [ [tool.hatch.build.targets.wheel] packages = ["bitmath"] +[tool.hatch.version] +path = "VERSION" +pattern = '(?P.+)' + [tool.hatch.publish.index] disable = true From c6164dbf5e4bfc9ac77a78e5cd08b479ce8bd716 Mon Sep 17 00:00:00 2001 From: Tim Case Date: Tue, 5 May 2026 09:05:43 -0500 Subject: [PATCH 2/6] Add bandit dynamic analysis workflow https://github.com/marketplace/actions/bandit-by-pycqa --- .github/workflows/bandit.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/bandit.yml diff --git a/.github/workflows/bandit.yml b/.github/workflows/bandit.yml new file mode 100644 index 0000000..b043f03 --- /dev/null +++ b/.github/workflows/bandit.yml @@ -0,0 +1,15 @@ +--- +name: Bandit Dynamic Analysis + +on: + workflow_dispatch: + +jobs: + analyze: + runs-on: ubuntu-latest + permissions: + # required for all workflows + security-events: write + steps: + - name: Perform Bandit Analysis + uses: PyCQA/bandit-action@v1 From 85287946cd46848341b2b942f7be2009e9b14d59 Mon Sep 17 00:00:00 2001 From: Tim Case Date: Tue, 5 May 2026 09:24:39 -0500 Subject: [PATCH 3/6] Rework bandit because their 'minimal complete example workflow' is a lie --- .github/workflows/bandit.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bandit.yml b/.github/workflows/bandit.yml index b043f03..9ab33d1 100644 --- a/.github/workflows/bandit.yml +++ b/.github/workflows/bandit.yml @@ -1,15 +1,25 @@ --- -name: Bandit Dynamic Analysis +name: Bandit Security Scan on: + push: + branches: ["master"] + pull_request: + branches: ["master"] + schedule: + - cron: "0 0 * * 0" workflow_dispatch: jobs: analyze: runs-on: ubuntu-latest permissions: - # required for all workflows security-events: write + env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true steps: + - name: Checkout code + uses: actions/checkout@v6.0.2 + - name: Perform Bandit Analysis uses: PyCQA/bandit-action@v1 From 6f61cdc6c7970d7953a32212c626b54eeef5613a Mon Sep 17 00:00:00 2001 From: Tim Case Date: Tue, 5 May 2026 09:41:45 -0500 Subject: [PATCH 4/6] Wire bandit into make ci, scan tests/ too, update CLAUDE.md Wanted make ci to be the one command that catches everything locally -- same as what the GitHub Action runs. Two things were missing: - bandit wasn't in requirements.txt (so the venv didn't have it) - the GH Action was only scanning bitmath/, skipping tests/ Changes: - Add bandit to requirements.txt - Add ci-bandit target, scanning bitmath/ and tests/ with -r -v - Wire ci-bandit into the ci chain between ci-pylint and ci-unittests - Update GH Action to pass targets: "bitmath/ tests/" - Update CLAUDE.md: versioning section (VERSION is the single source of truth), security scan section --- .github/workflows/bandit.yml | 2 ++ CLAUDE.md | 15 +++++++++++++-- Makefile | 9 ++++++++- requirements.txt | 1 + 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/.github/workflows/bandit.yml b/.github/workflows/bandit.yml index 9ab33d1..58d698c 100644 --- a/.github/workflows/bandit.yml +++ b/.github/workflows/bandit.yml @@ -23,3 +23,5 @@ jobs: - name: Perform Bandit Analysis uses: PyCQA/bandit-action@v1 + with: + targets: "bitmath/ tests/" diff --git a/CLAUDE.md b/CLAUDE.md index 6830ee3..8abd675 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -27,11 +27,14 @@ Phases 1 (maintenance 1.4.0) and 2 (bitmath 2.0.0) are complete. The project: ## Common Commands ```bash -# Run the full test suite with coverage (creates venv, runs pytest + linting) +# Run the full test suite with coverage (creates venv, runs pytest + linting + bandit) make ci +# Run security scan only +make ci-bandit + # Run linting only -ruff check bitmath/ tests/ +make ci-pylint # Build a wheel make build @@ -66,6 +69,14 @@ All unit values are normalized to bits internally; conversion between units happ **Constants:** `NIST`, `SI`, `NIST_PREFIXES`, `SI_PREFIXES`, `ALL_UNIT_TYPES` +## Versioning + +The single source of truth for the version is the `VERSION` file. `pyproject.toml` reads it dynamically via `[tool.hatch.version]` — do not edit the version in `pyproject.toml` directly. The `Makefile` also reads `VERSION` for docs, man pages, and RPM builds. To bump the version, edit `VERSION` only. + +## Security Scanning + +Bandit runs as part of `make ci` via the `ci-bandit` target, scanning both `bitmath/` and `tests/`. It also runs as a GitHub Actions workflow (`.github/workflows/bandit.yml`) on push/PR to master and weekly. No issues were present as of 2.0.2. + ## Testing Notes - Test runner: `pytest` diff --git a/Makefile b/Makefile index 43e53de..698f730 100644 --- a/Makefile +++ b/Makefile @@ -216,5 +216,12 @@ ci-pylint: @echo "#################################################" . $(NAME)env3/bin/activate && pylint bitmath/__init__.py -ci: clean uniquetestnames virtualenv ci-list-deps ci-pycodestyle ci-pylint ci-unittests +ci-bandit: + @echo "" + @echo "#############################################" + @echo "# Running Bandit Security Scan in virtualenv" + @echo "#############################################" + . $(NAME)env3/bin/activate && bandit -r -v bitmath/ tests/ + +ci: clean uniquetestnames virtualenv ci-list-deps ci-pycodestyle ci-pylint ci-bandit ci-unittests : diff --git a/requirements.txt b/requirements.txt index 8e4bceb..e5acdd0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +bandit pycodestyle pylint pytest From a0d1d573f34f3895837b2cdb199903c651d51dda Mon Sep 17 00:00:00 2001 From: Tim Case Date: Tue, 5 May 2026 09:47:28 -0500 Subject: [PATCH 5/6] Add bandit security badge to README --- README.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.rst b/README.rst index 27b2ff6..05fd179 100644 --- a/README.rst +++ b/README.rst @@ -7,6 +7,10 @@ .. image:: https://github.com/timlnx/bitmath/actions/workflows/python.yml/badge.svg :target: https://github.com/timlnx/bitmath/actions/workflows/python.yml +.. image:: https://img.shields.io/badge/security-bandit-yellow.svg + :target: https://github.com/PyCQA/bandit + :alt: Security Status + .. image:: https://img.shields.io/github/issues/timlnx/bitmath?style=flat-square :target: https://github.com/timlnx/bitmath/issues :alt: Open issues From 4655731f5f2d1a8e90953a029f3d23b27e24ec6d Mon Sep 17 00:00:00 2001 From: Tim Case Date: Tue, 5 May 2026 09:51:23 -0500 Subject: [PATCH 6/6] Update badges: bandit workflow, PyPI version, rounded license --- README.rst | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index 05fd179..7053f93 100644 --- a/README.rst +++ b/README.rst @@ -7,9 +7,9 @@ .. image:: https://github.com/timlnx/bitmath/actions/workflows/python.yml/badge.svg :target: https://github.com/timlnx/bitmath/actions/workflows/python.yml -.. image:: https://img.shields.io/badge/security-bandit-yellow.svg - :target: https://github.com/PyCQA/bandit - :alt: Security Status +.. image:: https://github.com/timlnx/bitmath/actions/workflows/bandit.yml/badge.svg + :target: https://github.com/timlnx/bitmath/actions/workflows/bandit.yml + :alt: Bandit Security Scan .. image:: https://img.shields.io/github/issues/timlnx/bitmath?style=flat-square :target: https://github.com/timlnx/bitmath/issues @@ -19,6 +19,10 @@ :target: https://github.com/timlnx/bitmath/pulls :alt: Open pull requests +.. image:: https://img.shields.io/pypi/v/bitmath.svg + :target: https://pypi.org/project/bitmath/ + :alt: Latest Version + .. image:: https://img.shields.io/pypi/dm/bitmath?style=flat-square :target: https://pypistats.org/packages/bitmath :alt: PyPI - Package Downloads @@ -27,9 +31,9 @@ :target: https://pypistats.org/packages/bitmath :alt: GitHub Project Popularity -.. image:: https://img.shields.io/pypi/l/bitmath?style=flat-square - :target: https://opensource.org/licenses/MIT - :alt: PyPI - License +.. image:: https://img.shields.io/badge/license-MIT-blue.svg + :target: https://github.com/timlnx/bitmath/blob/master/LICENSE + :alt: License .. image:: https://img.shields.io/pypi/implementation/bitmath?style=flat-square :alt: PyPI - Implementation