From 9297f42661407c81ceb5cbe37fc4149a3b75b188 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 18 Jul 2026 11:43:21 +0000 Subject: [PATCH 1/3] Set up PyPI publishing via trusted publishing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - .github/workflows/release.yml: on v* tag push, verify the tag matches the package version, uv build, uv publish with OIDC trusted publishing (environment: pypi). One-time PyPI-side setup documented in the workflow header and README. - Exclude node_modules from sdist and wheel — the wheel was silently 66 MB / 14k files before; it is now 2 MB with the built viewer bundle and frontend sources intact. - README: release procedure; .copier-answers.yml: publish_to_pypi true. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01LLg5cbBcfNyyrRGJVPfsA6 --- .copier-answers.yml | 2 +- .github/workflows/release.yml | 47 +++++++++++++++++++++++++++++++++++ README.md | 13 ++++++++++ pyproject.toml | 6 +++++ 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/release.yml diff --git a/.copier-answers.yml b/.copier-answers.yml index 6022076..f40af08 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -9,6 +9,6 @@ license: Proprietary project_description: Dataset quality scanner for AI evaluation datasets project_kind: library project_name: inspect-dataset -publish_to_pypi: false +publish_to_pypi: true python_version: '3.12' use_coverage_gate: false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..184261f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,47 @@ +name: Release + +# Publishes to PyPI via trusted publishing (OIDC) when a version tag is pushed. +# One-time PyPI setup: add a Trusted Publisher for this repository +# (owner: Generality-Labs, repository: inspect_dataset, workflow: release.yml, +# environment: pypi) at https://pypi.org/manage/account/publishing/. +# +# Release flow: +# 1. bump `version` in pyproject.toml (and src/inspect_dataset/__init__.py if present) +# 2. tag: git tag vX.Y.Z && git push origin vX.Y.Z + +on: + push: + tags: + - "v*" + +permissions: + contents: read + +jobs: + publish: + runs-on: ubuntu-latest + environment: pypi + permissions: + contents: read + id-token: write # OIDC token for PyPI trusted publishing + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 + + - name: Check tag matches package version + run: | + pkg_version=$(uv version --short) + tag_version="${GITHUB_REF_NAME#v}" + if [ "$pkg_version" != "$tag_version" ]; then + echo "Tag $GITHUB_REF_NAME does not match pyproject version $pkg_version" >&2 + exit 1 + fi + + - name: Build sdist and wheel + run: uv build + + - name: Publish to PyPI + run: uv publish --trusted-publishing always diff --git a/README.md b/README.md index 343f479..6704415 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,19 @@ Each finding includes the scanner name, severity, category, explanation, sample inspect-scout tracks which samples models consistently fail or succeed on. inspect-dataset provides a complementary static pass before running evals. A future release will accept inspect-scout results directly to produce eval-informed findings and a `clean_ids.txt` export for quality-adjusted benchmark scores. +## Releasing + +Releases publish to PyPI via [trusted publishing](https://docs.pypi.org/trusted-publishers/) — no API tokens. One-time setup: add a Trusted Publisher on PyPI for `Generality-Labs/inspect_dataset`, workflow `release.yml`, environment `pypi`. + +```bash +uv version --bump minor # or: patch / major — updates pyproject.toml +git commit -am "Release $(uv version --short)" +git tag "v$(uv version --short)" +git push origin main "v$(uv version --short)" +``` + +The tag push triggers `.github/workflows/release.yml`, which checks the tag against the package version, builds with `uv build`, and publishes. + ## Development ```bash diff --git a/pyproject.toml b/pyproject.toml index ee15920..559b43f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,12 @@ inspect = [ requires = ["uv_build>=0.8.17,<0.9.0"] build-backend = "uv_build" +[tool.uv.build-backend] +# The viewer frontend ships only as its built bundle (_view/www/dist); +# node_modules must never reach the sdist or wheel. +source-exclude = ["**/node_modules/**"] +wheel-exclude = ["**/node_modules/**"] + [tool.ruff] line-length = 100 src = ["src"] From 7ccb1f5d55a47efe9a54649cf061ca2e1d9edeb3 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 18 Jul 2026 21:52:15 +0000 Subject: [PATCH 2/3] License under MIT LICENSE file plus PEP 639 metadata (license = "MIT", license-files); the wheel now carries License-Expression: MIT and bundles the license text. Copier answers updated to match. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01LLg5cbBcfNyyrRGJVPfsA6 --- .copier-answers.yml | 2 +- LICENSE | 21 +++++++++++++++++++++ pyproject.toml | 2 ++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 LICENSE diff --git a/.copier-answers.yml b/.copier-answers.yml index f40af08..8f08d54 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -5,7 +5,7 @@ _src_path: gh:MattFisher/python-project-template author_email: m@ttfisher.com author_name: Matt Fisher github_owner: Generality-Labs -license: Proprietary +license: MIT project_description: Dataset quality scanner for AI evaluation datasets project_kind: library project_name: inspect-dataset diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..963cbc8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Matt Fisher + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/pyproject.toml b/pyproject.toml index 559b43f..a704bd6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,6 +3,8 @@ name = "inspect-dataset" version = "0.3.4" description = "Dataset quality scanner for AI evaluation datasets" readme = "README.md" +license = "MIT" +license-files = ["LICENSE"] authors = [ { name = "Matt Fisher", email = "m@ttfisher.com" } ] From 938076e4fb6444a59f9e9809ce2bffd4d6df8d20 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 18 Jul 2026 21:53:12 +0000 Subject: [PATCH 3/3] Harden release workflow per zizmor Add workflow concurrency (one release at a time, no cancel-in-progress), name the publish job, and disable setup-uv cache restore in the publish job so a poisoned cache cannot tamper with what gets uploaded to PyPI. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01LLg5cbBcfNyyrRGJVPfsA6 --- .github/workflows/release.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 184261f..96a06f2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,8 +17,14 @@ on: permissions: contents: read +# One release at a time; never cancel a publish in flight. +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false + jobs: publish: + name: Publish to PyPI runs-on: ubuntu-latest environment: pypi permissions: @@ -30,6 +36,10 @@ jobs: persist-credentials: false - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 + with: + # No cache restore in the publish job — a poisoned cache could + # tamper with what gets uploaded to PyPI (zizmor: cache-poisoning). + enable-cache: false - name: Check tag matches package version run: |