From 688bfc63f00933250e141faf0e3dff640ca83f40 Mon Sep 17 00:00:00 2001 From: Damien Riehl Date: Wed, 30 Sep 2026 14:04:12 -0500 Subject: [PATCH 1/2] =?UTF-8?q?release:=20v0.4.1=20=E2=80=94=20bounded=20s?= =?UTF-8?q?earch=20caches?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ships #20. Bumps pyproject.toml, folio/__init__.py and the lockfile to 0.4.1 and adds the dated changelog entry. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01FqnG3GCkvna3C3ikkcjU2T --- CHANGES.md | 5 +++++ folio/__init__.py | 2 +- pyproject.toml | 2 +- uv.lock | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 11c8c8e..474c3ce 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,8 @@ +Version 0.4.1 (2026-09-30) +--------------------------- +* Fixed: query-result caches are now bounded, so a long-running process no longer retains every unique search forever (#20). `search_by_prefix()` (both case-sensitive and case-insensitive paths) evicts its oldest entry once `DEFAULT_SEARCH_CACHE_SIZE` (128) results are cached, and the memoized `_basic_search` helper behind the fuzzy label and definition searches uses `lru_cache(maxsize=128)` in place of an unbounded `cache` +* No public API changes; full test suite (80 tests) passes + Version 0.4.0 (2026-08-17) --------------------------- * Changed: `FOLIO.generate_iri()` now mints `R` + base62 of 127 random bits (e.g. `R1cNH7TLMiSlSbIbdFsynUk`), matching the scheme used by 11,427 of the 18,325 published FOLIO concepts, instead of a base64url-derived token with no `R` prefix. Newly minted IRIs are now indistinguishable from their published siblings. No existing IRI changes; `generate_iri()` only mints new ones diff --git a/folio/__init__.py b/folio/__init__.py index f45b1a5..2439f8a 100644 --- a/folio/__init__.py +++ b/folio/__init__.py @@ -5,7 +5,7 @@ # SPDX-License-Identifier: MIT # (c) 2024 ALEA Institute. -__version__ = "0.4.0" +__version__ = "0.4.1" __author__ = "ALEA Institute" __license__ = "MIT" __description__ = ( diff --git a/pyproject.toml b/pyproject.toml index 531df7a..b7c9e41 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "folio-python" -version = "0.4.0" +version = "0.4.1" description = "Python library for FOLIO, the Federated Open Legal Information Ontology" authors = [{ name = "ALEA Institute", email = "hello@aleainstitute.ai" }] requires-python = ">=3.10,<4.0.0" diff --git a/uv.lock b/uv.lock index a5b2998..d74ffd4 100644 --- a/uv.lock +++ b/uv.lock @@ -389,7 +389,7 @@ wheels = [ [[package]] name = "folio-python" -version = "0.4.0" +version = "0.4.1" source = { editable = "." } dependencies = [ { name = "httpx" }, From 96269e53d962e24a435f68cc1491e778dbad09f2 Mon Sep 17 00:00:00 2001 From: Damien Riehl Date: Wed, 30 Sep 2026 14:07:04 -0500 Subject: [PATCH 2/2] ci: publish to PyPI via Trusted Publishing on release Adds publish.yml: on a published GitHub release, check the tag matches the package version, build with uv, and upload with pypa/gh-action-pypi-publish through the pypi environment using OIDC. All actions are pinned to release commit SHAs; no token is stored. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01FqnG3GCkvna3C3ikkcjU2T --- .github/workflows/publish.yml | 53 +++++++++++++++++++++++++++++++++++ CHANGES.md | 1 + 2 files changed, 54 insertions(+) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..c97f273 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,53 @@ +name: Publish to PyPI + +# Uploads only when a GitHub release is published. Authentication uses PyPI +# Trusted Publishing (OIDC); no API token is stored in this repository. +# PyPI Trusted Publisher fields: owner alea-institute, repository folio-python, +# workflow publish.yml, environment pypi. + +on: + release: + types: [published] + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 + - name: Check release tag matches package version + env: + TAG: ${{ github.event.release.tag_name }} + run: | + version=$(sed -n 's/^version = "\(.*\)"$/\1/p' pyproject.toml | head -1) + if [ "${TAG#v}" != "$version" ]; then + echo "Release tag $TAG does not match pyproject version $version" >&2 + exit 1 + fi + - name: Build sdist and wheel + run: uv build + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: dist + path: dist/ + if-no-files-found: error + + publish: + needs: build + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/folio-python + permissions: + id-token: write + steps: + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: dist + path: dist/ + - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2 diff --git a/CHANGES.md b/CHANGES.md index 474c3ce..13be063 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ Version 0.4.1 (2026-09-30) --------------------------- * Fixed: query-result caches are now bounded, so a long-running process no longer retains every unique search forever (#20). `search_by_prefix()` (both case-sensitive and case-insensitive paths) evicts its oldest entry once `DEFAULT_SEARCH_CACHE_SIZE` (128) results are cached, and the memoized `_basic_search` helper behind the fuzzy label and definition searches uses `lru_cache(maxsize=128)` in place of an unbounded `cache` * No public API changes; full test suite (80 tests) passes +* Added: `.github/workflows/publish.yml` — publishing a GitHub release builds with `uv build` and uploads to PyPI via Trusted Publishing (OIDC, `pypi` environment); no API token is stored. Replaces the manual `twine upload` step once the Trusted Publisher is registered on PyPI Version 0.4.0 (2026-08-17) ---------------------------