From 555f73a66a3ce8d176d0867098244540991d315d Mon Sep 17 00:00:00 2001 From: "Aaron K. Clark" Date: Tue, 27 Oct 2026 02:27:07 -0500 Subject: [PATCH] chore: drop PyPI publishing pipeline (#267) omind is an MCP server installed from source with `uv tool`, not a library distributed on PyPI, so the trusted-publishing release pipeline was never needed. The project owner has no PyPI account and does not want a public package, so #267 is closed won't-do. Removes `.github/workflows/publish.yml` (every release since v9.7.3 failed closed on `invalid-publisher`, uploading nothing) and the PyPI references in CONTRIBUTING.md (Releasing), AGENTS.md, docs/self-update.md, and BACKLOG.md (open item + "PyPI Publish Setup" section). The test.yml wheel job stays with its stale publish.yml comment fixed. Releases remain GitHub releases on `v` tags that the fleet installs from git. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_0124qGFyZJsujDwvAPf9au5m --- .github/workflows/publish.yml | 82 ----------------------------------- .github/workflows/test.yml | 2 +- AGENTS.md | 5 +-- BACKLOG.md | 42 ------------------ CHANGELOG.md | 6 +++ CONTRIBUTING.md | 21 ++------- docs/self-update.md | 8 ++-- 7 files changed, 15 insertions(+), 151 deletions(-) delete mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 51421d4..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: publish -# First PyPI publish of omind (#267), and every release after it. -# -# Trusted publishing (OIDC): PyPI trusts THIS workflow in THIS repo, so there is -# no API token to mint, store, leak or rotate. One-time setup on pypi.org, by -# the account that will own the project (see BACKLOG.md "PyPI Publish Setup"): -# Publishing -> Add a pending publisher -> GitHub -# owner: CryptoJones repository: omind -# workflow: publish.yml environment: pypi -# Until that exists the publish step fails closed with "invalid-publisher"; -# nothing is uploaded and nothing else in the repo is affected. -on: - release: - types: [published] - workflow_dispatch: - inputs: - dry_run: - description: Build and verify only; do not upload - type: boolean - default: true - -# Least privilege: the default is read-only; only the publish job can mint an -# OIDC token, and only inside the `pypi` environment. -permissions: - contents: read - -concurrency: - group: publish-${{ github.ref }} - cancel-in-progress: false - -jobs: - build: - name: Build sdist + wheel - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0 - with: - python-version: '3.12' - - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 - - name: A release tag must match the packaged version - if: github.event_name == 'release' - env: - TAG: ${{ github.event.release.tag_name }} - run: | - version="$(python - <<'PY' - import tomllib - print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"]) - PY - )" - if [ "v$version" != "$TAG" ]; then - echo "::error::release tag $TAG does not match pyproject version $version" - exit 1 - fi - # uv build: the same command test.yml's wheel job runs on every PR, so - # the build path that publishes is the one CI exercises. - - run: uv build - - name: Metadata renders on PyPI - run: uvx twine check --strict dist/* - - name: Hand the artifacts to the publish job - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 - with: - name: dist - path: dist/ - if-no-files-found: error - - publish: - name: Upload to PyPI - needs: build - if: github.event_name == 'release' || inputs.dry_run == false - runs-on: ubuntu-latest - environment: - name: pypi - url: https://pypi.org/project/omind/ - permissions: - id-token: write # the OIDC token PyPI exchanges for an upload credential - steps: - - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 - with: - name: dist - path: dist/ - - uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bc9ba24..724ca19 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -74,7 +74,7 @@ jobs: - uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0 with: python-version: '3.12' - # Same build path as publish.yml, so every PR exercises what gets uploaded. + # Build the real wheel the way an install does, so packaging breaks surface here. - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 - name: Build the wheel run: uv build --wheel diff --git a/AGENTS.md b/AGENTS.md index 844cd00..a8101af 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -65,7 +65,7 @@ Trust **BACKLOG.md + CHANGELOG.md** (10.1.1–10.2.11) for detail. The sweep closed #393 #392 #391 #394 #414 #402 #403 #406 #416 #377 #380 #417 #419 #420 #423 #425 via PRs #405, #407–#413, #415, #418, #421, #422, #424 and #426. -The only open item is **#267**: the owner must register the PyPI trusted publisher. +Every item from that sweep is closed. Lessons for the next agent: @@ -132,8 +132,7 @@ found 35 issues; all are fixed in the working tree. The classes worth rememberin The feature roadmap (agent identity/attribution, a usefulness feedback loop, sleep-time consolidation, write-time dedup, scoped writes) is Part 2 of the review -report — none of it is started. `omind` is still not on PyPI (#267 needs the -user's PyPI account/credentials). +report — none of it is started. --- diff --git a/BACKLOG.md b/BACKLOG.md index ed67ddc..9d55317 100644 --- a/BACKLOG.md +++ b/BACKLOG.md @@ -17,15 +17,6 @@ the exact order of operations._ never judge it. Verify the tool names against live payloads first. - [ ] **README: link Flatline Roundtable and conveyor in the first lines** ([#436](https://github.com/CryptoJones/omind/issues/436)) — _docs_ — prerequisites: #429 (merged) and #428 (conveyor deployed on dl380 2026-10-02). Also adds the Nebraska banner and drops the stale Codeberg badge. -- [ ] **[Priority 7 / P3] First PyPI publish of omind package** ([#267](https://github.com/CryptoJones/omind/issues/267)) — _chore_ — - the CI half is done: `.github/workflows/publish.yml` builds with `uv build` and uploads by - trusted publishing, with no token. Every release from v9.7.3 through v10.0.2 reached the upload and - stopped at `invalid-publisher`; 10.1.0 through 10.2.11 were never released. What remains is two - operator steps: (1) on pypi.org, open *Publishing* and add a pending trusted publisher (owner - `CryptoJones`, repo `omind`, workflow `publish.yml`, environment `pypi`); (2) publish a GitHub - release (`gh release create vX.Y.Z`); pushing a tag alone does not trigger the upload. See - [PyPI Publish Setup](#pypi-publish-setup-2026-08-24-267) below. - ## Not planned _Closed as not planned or rejected. Kept for the record; nothing here is pending, so these items have no checkbox._ @@ -958,37 +949,4 @@ _Added 2026-10-02 so every closed issue has a line here. Details live on each is - [x] verifier: credit guard-demanded note reads; stop scoring vault writes as consults; log judgement context on off-topic denials ([#148](https://github.com/CryptoJones/omind/issues/148)) - [x] omind guard locked on new repos with no remotes because pulls / fetches are not possible ([#149](https://github.com/CryptoJones/omind/issues/149)) ---- - -## PyPI Publish Setup (2026-08-24) ([#267](https://github.com/CryptoJones/omind/issues/267)) - -- **Status: `omind` is not on PyPI yet. The first publish is pending** (tracked as the open #267 item above). The package has never - been uploaded (HTTP 404 on the simple index, re-checked 2026-10-02). Everything that - does not need a PyPI account is done: - - [x] **Publish workflow:** `.github/workflows/publish.yml`. It uses trusted publishing over - OIDC, so there is **no API token** to mint, store or rotate. It builds sdist + wheel with - `uv build`, refuses a release whose tag is not `v` + the `pyproject` version, and runs - `twine check --strict`. The upload runs from a separate job in the `pypi` environment, and - only that job holds `id-token: write`. Actions are pinned by commit SHA, like the rest of CI. - - [x] **GitHub `pypi` environment:** exists. It has no protection rules; if you want a manual - gate on every upload, add yourself as a required reviewer under Settings → Environments - (optional). - - [x] **The pipeline is proven up to PyPI:** the release runs for v9.7.3, v9.7.5, v10.0.0, - v10.0.1 and v10.0.2 all built, minted an OIDC token, and were refused with - `invalid-publisher` (no matching publisher). That is the expected fail-closed result: - nothing is uploaded. Versions 10.1.0 through 10.2.11 were never released (no GitHub - release was cut for them), so the workflow never ran for them. - - **What is left. The operator does both steps; there are no credentials anywhere, by design:** - 1. Log in to https://pypi.org/ with the account that will own the project. Go to - *Your account → Publishing → Add a new pending publisher → GitHub* and enter owner - `CryptoJones`, repository `omind`, workflow `publish.yml`, environment `pypi`. - A pending publisher does not need the project to exist, but it does **not** reserve the - name. The name is yours only after the first successful upload, so do step 2 promptly. - 2. Publish a GitHub release (`gh release create vX.Y.Z`) whose tag is `v` (see CONTRIBUTING.md → *Releasing*). The workflow fires only on - `release: published`; pushing a tag on its own does nothing. You can instead run the - workflow by hand (*Actions → publish → Run workflow*) with `dry_run` unchecked. - After the upload succeeds, tick #267 here and close the issue. - *Proudly Made in Nebraska. Go Big Red! 🌽 * diff --git a/CHANGELOG.md b/CHANGELOG.md index e3da57a..4f4c2ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Removed +- **PyPI publishing (`publish.yml`) and the `#267` publish blocker.** omind is an MCP + server installed from source with `uv tool`, not a library distributed on PyPI, so the + trusted-publishing pipeline was dropped. Releases stay GitHub releases on `v` + tags that the fleet installs from git; nothing uploads to a package index. + ## [10.3.3] - 2026-10-26 ### Fixed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d40eca6..5c76085 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -124,7 +124,9 @@ The version is declared in three places that must stay in lockstep — `pyprojec ## Releasing A release is a **GitHub release** on a `v` tag that points at merged `main`. -Publishing it is what ships the package to PyPI. +It is what the fleet installs from: nodes run `uv tool install` / `uv tool upgrade` +against the GitHub source, so cutting the release is what ships the new version. omind +is an MCP server installed from source, not a library distributed on a package index. 1. Merge the PR that bumped the version (`pyproject.toml`, `src/omind/__init__.py`, `uv.lock`, and its `CHANGELOG.md` heading) to `main`. @@ -134,23 +136,6 @@ Publishing it is what ships the package to PyPI. ```sh gh release create v --target main --title "omind " --generate-notes ``` -3. `.github/workflows/publish.yml` fires on `release: published`. It builds the sdist and - wheel with `uv build`, **fails if the tag does not match the packaged version**, runs - `twine check --strict`, and uploads to PyPI by **trusted publishing**: an OIDC token - from the `pypi` environment, with no API token stored anywhere. - -To check a build without uploading, run the workflow by hand -(*Actions → publish → Run workflow*). The `dry_run` box is checked by default. To -re-publish a release whose upload failed, run the workflow by hand from that tag with -`dry_run` unchecked; PyPI never accepts the same version twice. A manual run skips the -tag-vs-version check (that check only runs on `release: published`), so it uploads -whatever version the chosen ref holds: always pick the release tag as the ref, and run -it once with `dry_run` checked before the real upload. - -PyPI trusts this exact workflow file name and environment name. If you rename -`publish.yml` or the `pypi` environment, update the trusted publisher on pypi.org at the -same time, or the upload fails with `invalid-publisher`. The one-time pypi.org setup is -in BACKLOG.md → *PyPI Publish Setup*. ## Pull requests diff --git a/docs/self-update.md b/docs/self-update.md index b2ffcf6..b0688c3 100644 --- a/docs/self-update.md +++ b/docs/self-update.md @@ -79,11 +79,9 @@ updater already gutted (see [troubleshooting](troubleshooting.md)). The check and the install pull from **GitHub** (public, no auth for read) — the channel the request named. Codeberg stays the canonical push target; this is a -read-only consumer. There is no PyPI package yet. The trusted-publishing workflow -(`.github/workflows/publish.yml`) exists but is still waiting on the one-time pypi.org -registration tracked in [#267](https://github.com/CryptoJones/omind/issues/267), so the -git ref is the install source. If omind is later published to an index, `uv tool upgrade` -becomes the native path and `update_command` gains that branch. +read-only consumer. omind is not distributed on a package index; the GitHub git ref +is the install source, and `uv tool install` / `uv tool upgrade` against it is the +native update path. ## Not (yet) done