diff --git a/.github/workflows/rhiza_benchmark.yml b/.github/workflows/rhiza_benchmark.yml index a828854c..234a8386 100644 --- a/.github/workflows/rhiza_benchmark.yml +++ b/.github/workflows/rhiza_benchmark.yml @@ -20,5 +20,5 @@ on: jobs: benchmark: - uses: jebel-quant/rhiza/.github/workflows/rhiza_benchmark.yml@v1.2.2 + uses: jebel-quant/rhiza/.github/workflows/rhiza_benchmark.yml@v1.2.5 secrets: inherit diff --git a/.github/workflows/rhiza_book.yml b/.github/workflows/rhiza_book.yml index 73c3f40c..8002ff5b 100644 --- a/.github/workflows/rhiza_book.yml +++ b/.github/workflows/rhiza_book.yml @@ -29,7 +29,7 @@ on: jobs: book: - uses: jebel-quant/rhiza/.github/workflows/rhiza_book.yml@v1.2.2 + uses: jebel-quant/rhiza/.github/workflows/rhiza_book.yml@v1.2.5 secrets: inherit permissions: contents: read diff --git a/.github/workflows/rhiza_ci.yml b/.github/workflows/rhiza_ci.yml index b98e8956..e38fb3b5 100644 --- a/.github/workflows/rhiza_ci.yml +++ b/.github/workflows/rhiza_ci.yml @@ -26,5 +26,5 @@ on: jobs: ci: - uses: jebel-quant/rhiza/.github/workflows/rhiza_ci.yml@v1.2.2 + uses: jebel-quant/rhiza/.github/workflows/rhiza_ci.yml@v1.2.5 secrets: inherit diff --git a/.github/workflows/rhiza_codeql.yml b/.github/workflows/rhiza_codeql.yml index a444a1f6..4f4dcc6a 100644 --- a/.github/workflows/rhiza_codeql.yml +++ b/.github/workflows/rhiza_codeql.yml @@ -39,7 +39,7 @@ on: jobs: codeql: - uses: jebel-quant/rhiza/.github/workflows/rhiza_codeql.yml@v1.2.2 + uses: jebel-quant/rhiza/.github/workflows/rhiza_codeql.yml@v1.2.5 secrets: inherit permissions: security-events: write # Upload CodeQL results to code scanning diff --git a/.github/workflows/rhiza_marimo.yml b/.github/workflows/rhiza_marimo.yml index 34e8dc22..5c1d661b 100644 --- a/.github/workflows/rhiza_marimo.yml +++ b/.github/workflows/rhiza_marimo.yml @@ -28,5 +28,5 @@ on: jobs: marimo: - uses: jebel-quant/rhiza/.github/workflows/rhiza_marimo.yml@v1.2.2 + uses: jebel-quant/rhiza/.github/workflows/rhiza_marimo.yml@v1.2.5 secrets: inherit diff --git a/.github/workflows/rhiza_mutation.yml b/.github/workflows/rhiza_mutation.yml index 66cbd162..dacfd1f2 100644 --- a/.github/workflows/rhiza_mutation.yml +++ b/.github/workflows/rhiza_mutation.yml @@ -42,7 +42,7 @@ jobs: # this repo sets the `MUTATION_ENABLED` variable to 'true'. Gating here in # the caller keeps it optional regardless of the pinned reusable workflow. if: ${{ vars.MUTATION_ENABLED == 'true' }} - uses: jebel-quant/rhiza/.github/workflows/rhiza_mutation.yml@v1.2.2 + uses: jebel-quant/rhiza/.github/workflows/rhiza_mutation.yml@v1.2.5 secrets: inherit permissions: contents: read diff --git a/.github/workflows/rhiza_paper.yml b/.github/workflows/rhiza_paper.yml index 4b33a3a6..8f87be3c 100644 --- a/.github/workflows/rhiza_paper.yml +++ b/.github/workflows/rhiza_paper.yml @@ -28,7 +28,7 @@ on: jobs: paper: - uses: jebel-quant/rhiza/.github/workflows/rhiza_paper.yml@v1.2.2 + uses: jebel-quant/rhiza/.github/workflows/rhiza_paper.yml@v1.2.5 secrets: inherit permissions: contents: write diff --git a/.github/workflows/rhiza_release.yml b/.github/workflows/rhiza_release.yml index d386d3cb..6a2b2a39 100644 --- a/.github/workflows/rhiza_release.yml +++ b/.github/workflows/rhiza_release.yml @@ -222,7 +222,7 @@ jobs: version: "0.11.16" - name: Configure git auth for private packages - uses: jebel-quant/rhiza/.github/actions/configure-git-auth@v1.2.2 + uses: jebel-quant/actions/configure-git-auth@6d52725ca371d609489c5b50236965ad70bbe528 # v1 with: token: ${{ secrets.GH_PAT }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 230df574..133da54c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: pass_filenames: false - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.15.21' + rev: 'v0.16.0' hooks: - id: ruff args: [ --fix, --exit-non-zero-on-fix, --unsafe-fixes ] @@ -71,12 +71,12 @@ repos: args: ["--ini", ".bandit", "--exclude", ".venv,tests,.rhiza/tests,.git,.pytest_cache"] - repo: https://github.com/betterleaks/betterleaks - rev: v1.6.1 + rev: v1.7.2 hooks: - id: betterleaks - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.11.28 + rev: 0.12.0 hooks: - id: uv-lock diff --git a/.rhiza/.cfg.toml b/.rhiza/.cfg.toml index 525dc9b5..856b363c 100644 --- a/.rhiza/.cfg.toml +++ b/.rhiza/.cfg.toml @@ -28,10 +28,22 @@ values = [ "prod" ] +# Anchored to the [project] table on purpose. `search`/`replace` are applied to +# EVERY occurrence in the file, so the obvious `version = "{current_version}"` +# also rewrites any [tool.*] table that happens to share the current number. +# Dependency pins (httpx>=1.2.0, rich==1.2.0) are never at risk either way — +# they are not line-anchored `version = ` assignments — but a second table is. [[tool.bumpversion.files]] filename = "pyproject.toml" -search = 'version = "{current_version}"' -replace = 'version = "{new_version}"' +regex = true +search = '(?ms)^\[project\]((?:(?!^\[)[\s\S])*?)^version = "{current_version}"' +replace = '[project]\1version = "{new_version}"' + +# NOTE for downstream projects: do NOT add a glob over your own +# .github/workflows/*.yml here. Those stubs pin jebel-quant/rhiza's version +# (the template you sync from), not your project's, so rewriting them with your +# version would point them at a rhiza tag that does not exist. The template ref +# is managed by /rhiza:update via .rhiza/template.yml instead. # Keep the reusable-workflow stubs in the bundles pinned to the current release. # These stubs are synced into downstream repos and must reference an existing tag. diff --git a/.rhiza/make.d/releasing.mk b/.rhiza/make.d/releasing.mk deleted file mode 100644 index 05248384..00000000 --- a/.rhiza/make.d/releasing.mk +++ /dev/null @@ -1,27 +0,0 @@ -## .rhiza/make.d/releasing.mk - Releasing and Versioning -# This file provides changelog and release-status helpers. -# -# Version bumping and release tagging are NOT make targets. Releasing is driven -# by the rhiza-claude `/release` command, which derives the next version, bumps -# pyproject.toml, regenerates CHANGELOG.md, and creates the tag locally. Pushing -# that tag triggers the release workflow (rhiza_release.yml). -# See https://github.com/Jebel-Quant/rhiza-claude. - -# Declare phony targets (they don't produce files) -.PHONY: release-status changelog - -##@ Releasing and Versioning -release-status: ## show release workflow status and latest release information -ifeq ($(FORGE_TYPE),github) - @{ $(MAKE) --no-print-directory workflow-status; printf "\n"; $(MAKE) --no-print-directory latest-release; } 2>&1 | $${PAGER:-less -R} -else ifeq ($(FORGE_TYPE),gitlab) - @printf "${YELLOW}[WARN] GitLab detected — release-status is not yet supported for GitLab repositories.${RESET}\n" - @printf "${BLUE}[INFO] Please check your pipeline status in the GitLab UI.${RESET}\n" -else - @printf "${RED}[ERROR] Could not detect forge type (.github/workflows/ or .gitlab-ci.yml not found)${RESET}\n" -endif - -changelog: install-uv ## generate/update CHANGELOG.md from git history using git-cliff (config: cliff.toml) - @printf "${BLUE}[INFO] Generating CHANGELOG.md with git-cliff...${RESET}\n" - @${UVX_BIN} git-cliff --output CHANGELOG.md - @printf "${GREEN}[OK] CHANGELOG.md updated.${RESET}\n" diff --git a/.rhiza/template.lock b/.rhiza/template.lock index c0c3e757..26eaf961 100644 --- a/.rhiza/template.lock +++ b/.rhiza/template.lock @@ -1,7 +1,7 @@ -sha: e0fe02300840e39fe75d19db2741e9a790f87794 +sha: e5d7005e2d9fc3d5a23b96d13b203b4f2afe3cce repo: jebel-quant/rhiza host: github -ref: v1.2.1 +ref: v1.2.5 include: [] exclude: - bundles/github/.github/workflows/rhiza_fuzzing.yml @@ -57,7 +57,6 @@ files: - .rhiza/make.d/marimo.mk - .rhiza/make.d/paper.mk - .rhiza/make.d/quality.mk -- .rhiza/make.d/releasing.mk - .rhiza/make.d/test.mk - .rhiza/rhiza.mk - .rhiza/semgrep.yml @@ -77,5 +76,5 @@ files: - docs/mkdocs-base.yml - pytest.ini - ruff.toml -synced_at: '2026-07-17T12:57:28Z' +synced_at: '2026-07-30T04:16:36Z' strategy: merge diff --git a/.rhiza/template.yml b/.rhiza/template.yml index 9b71c8fb..b1c3ba5d 100644 --- a/.rhiza/template.yml +++ b/.rhiza/template.yml @@ -1,5 +1,5 @@ repository: "jebel-quant/rhiza" -ref: "v1.2.1" +ref: "v1.2.5" profiles: - github-project diff --git a/.rhiza/tests/test_pyproject.py b/.rhiza/tests/test_pyproject.py index 3b6bbcc3..af0d2492 100644 --- a/.rhiza/tests/test_pyproject.py +++ b/.rhiza/tests/test_pyproject.py @@ -140,7 +140,7 @@ def test_repository_configured(self, urls: dict) -> None: class TestProjectClassifiers: - """Tests for [project].classifiers — Python version and licence entries.""" + """Tests for [project].classifiers — Python version entries.""" @pytest.fixture def classifiers(self, project: dict) -> list[str]: @@ -157,10 +157,17 @@ def test_python_version_classifier_present(self, classifiers: list[str]) -> None "classifiers must include at least one 'Programming Language :: Python :: 3.X' entry" ) - def test_license_classifier_present(self, classifiers: list[str]) -> None: - """At least one 'License :: ' classifier must be present.""" + def test_no_license_classifier(self, project: dict) -> None: + """No deprecated 'License :: ' classifier may be present. + + PyPI has deprecated the ``License ::`` trove classifiers in favor of the SPDX + ``license`` expression field, so the shipped pyproject must not declare one. + """ + classifiers = project.get("classifiers", []) license_classifiers = [c for c in classifiers if c.startswith("License ::")] - assert len(license_classifiers) >= 1, "classifiers must include at least one 'License :: ' entry" + assert not license_classifiers, ( + f"classifiers must not include any deprecated 'License :: ' entry; found {license_classifiers}" + ) class TestDependencyGroups: diff --git a/ruff.toml b/ruff.toml index fad67572..be3823bf 100644 --- a/ruff.toml +++ b/ruff.toml @@ -3,8 +3,7 @@ # # Maximum line length for the entire project line-length = 120 -# Target Python version -target-version = "py311" +# Target Python version is inferred from project.requires-python. # Exclude directories with Jinja template variables in their names exclude = ["**/[{][{]*/", "**/*[}][}]*/"]