Skip to content

chore: harden release process (test gate, PyPI verify, single version source)#12

Open
ebowman wants to merge 2 commits into
mainfrom
chore/release-process-hardening
Open

chore: harden release process (test gate, PyPI verify, single version source)#12
ebowman wants to merge 2 commits into
mainfrom
chore/release-process-hardening

Conversation

@ebowman

@ebowman ebowman commented Jun 7, 2026

Copy link
Copy Markdown
Owner

Follow-up to #11. Addresses the release-process weaknesses exposed while shipping v1.4.5 (CI publishing had been silently broken since v1.4.4, which never reached PyPI).

Changes

  1. Test gatepublish.yml now runs pytest tests/unit on macOS, and build/publish depend on it. Tests also run on push/pull_request, so the gate is exercised before any release (previously nothing ran tests in CI).
  2. Post-publish verification — new verify-pypi job polls PyPI for the released version and fails loudly if it never appears. This is the guard that would have caught v1.4.4 silently never publishing.
  3. Single source of version truthpyproject.toml now derives the version dynamically from things_mcp.__version__ (setuptools dynamic + attr). Releases bump only src/things_mcp/__init__.py.
  4. One authoritative release pathCLAUDE.md documents CI as the way releases publish; manual twine upload is now explicitly break-glass only.
  5. Housekeeping — fix placeholder author metadata; mitigate the GitHub Actions Node 20 runtime deprecation.

Also fixes a stale unit test (test_retrieve_completed_todos patched things.logbook, but get_logbook calls things.todos(status='completed')), so the gate is green.

Publish flow after this PR

test → build → publish-to-pypi (release only) → verify-pypi (release only)

Publishing only happens on a published GitHub Release; pushes/PRs stop at test → build.

Note: this does not fix the PyPI-side trusted-publisher misconfiguration (403 OIDC scoped token is not valid for project) — that's an account-side change. Once corrected, this workflow publishes and verifies automatically.

Testing

  • pytest tests/unit → 597 passed locally.
  • Local python -m build confirms the dynamic version resolves to the value in __init__.py.

🤖 Generated with Claude Code

ebowman and others added 2 commits June 7, 2026 23:41
… source)

- publish.yml: add a test gate (pytest tests/unit on macOS) that build/publish
  depend on; run test+build on push/PR so the gate is exercised before release;
  publish only on a published Release; add a verify-pypi job that polls PyPI for
  the released version and fails loudly (would have caught v1.4.4 never shipping).
- pyproject: single source of version truth via setuptools dynamic
  attr=things_mcp.__version__ (stop hand-editing pyproject + __init__); fix
  placeholder author metadata.
- tests: fix stale test_retrieve_completed_todos (patched things.logbook but the
  code calls things.todos(status='completed')); now hermetic and green.
- CLAUDE.md: document CI as the authoritative release path; manual twine upload
  is break-glass only; version bump now touches only __init__.py.
- mitigate GitHub Actions Node 20 runtime deprecation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
get_todos() reads via things.todos(status='incomplete'), not the operation
queue, so the stale queue mock left it hitting the real (empty in CI) database
and asserting on []. Patch things.todos instead.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant