diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..c97f2732 --- /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 11c8c8e4..13be0639 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,9 @@ +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) --------------------------- * 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 f45b1a58..2439f8a7 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 531df7a3..b7c9e413 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 a5b2998f..d74ffd43 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" },