From b796e3864457edfb85e4107b5897736c67afb14c Mon Sep 17 00:00:00 2001 From: Krivoblotsky Date: Wed, 16 Sep 2026 14:29:46 +0300 Subject: [PATCH] docs: Homebrew install, Python 3.14 in CI, RELEASING runbook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - README: `brew install macpaw/taps/portable-memory` next to `pip install` in "Try it in 60 seconds" and a Homebrew paragraph in "Install". - Python 3.14 added to the CI matrix and the classifiers; the suite passes on 3.14.6 (Homebrew's python@3.14, which the formula builds on). - RELEASING.md: the release runbook — version bump, changelog, tag = version, GitHub release → PyPI Trusted Publishing, verification, Homebrew bump, Swift SDK mirror. - CHANGELOG: Unreleased entries. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Krivoblotsky --- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 10 +++++++ README.md | 8 +++++- RELEASING.md | 57 ++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 1 + 5 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 RELEASING.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06ae948..cfbdd91 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] - python-version: ["3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 diff --git a/CHANGELOG.md b/CHANGELOG.md index 007cc0f..2b808a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,16 @@ independent of the on-disk **format** version (`format` in the manifest). ## [Unreleased] +### Added + +- **Homebrew** — `brew install macpaw/taps/portable-memory` installs the `mem` command from + [MacPaw's Homebrew tap](https://github.com/MacPaw/homebrew-taps); the formula tracks PyPI + releases (bump step in `RELEASING.md`). +- **Python 3.14** in the CI matrix and the package classifiers (the Homebrew formula builds on + `python@3.14`). +- **`RELEASING.md`** — the release runbook: version bump, changelog, tag = version, GitHub + release → PyPI Trusted Publishing, verification, Homebrew bump, Swift SDK mirror. + ## [0.3.0] - 2026-09-14 Format **1.1.0**: the manifest now says what the archive covers, in which scopes, and diff --git a/README.md b/README.md index 2c79dc4..4cd5b2c 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Your AI memory is already portable enough to *paste*: every assistant now hands ![mem paste → validate → render: the pasted memory text becomes a verifiable .mem bundle and back](docs/demo.gif) ```bash -pip install portable-memory +pip install portable-memory # or: brew install macpaw/taps/portable-memory # 1. Run the standard memory-export prompt in ChatGPT (or Claude, Gemini, Grok…) and save the # code block it returns as export.txt. Then: @@ -154,6 +154,12 @@ What a source doesn't model rides in via `ext` (fields) and passthrough (kinds); pip install portable-memory ``` +On macOS or Linux, Homebrew installs the `mem` command from [MacPaw's tap](https://github.com/MacPaw/homebrew-taps) (the formula tracks PyPI releases): + +```bash +brew install macpaw/taps/portable-memory +``` + Signing (detached Ed25519 signatures over the manifest, plus signed tombstones) is optional — it lazily imports [`cryptography`](https://pypi.org/project/cryptography/) only when you actually sign or verify: ```bash diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 0000000..384b378 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,57 @@ +# Releasing `portable-memory` + +The SDK version is independent of the on-disk **format** version (`format` in the manifest, spec +§9): bump the SDK version for every release; bump the format version only when the spec changes +what a bundle contains. + +Releases are tagged `X.Y.Z` (no `v` prefix). The [Swift SDK](https://github.com/MacPaw/portable-memory-swift) +is released with the same version on the same day, so `Spec/`, `Schemas/` and `Conformance/` stay +byte-identical across both repositories. + +## 1. Prepare the release PR + +1. `pyproject.toml` → `version = "X.Y.Z"` **and** `portable_memory/__init__.py` → `__version__ = "X.Y.Z"` + (`tests/test_version.py` fails when they disagree). +2. `CHANGELOG.md`: rename **Unreleased** to `## [X.Y.Z] - YYYY-MM-DD`, add a fresh empty + **Unreleased** above it, and update the compare links at the bottom. +3. If `Spec/`, `Schemas/` or `Conformance/` changed, they must still match the Swift repository + (`diff -r -x __pycache__ Spec ../portable-memory-swift/Spec`, likewise for the other two) — + sync the Swift repository in the same release. +4. `pytest -q`, then open the PR from `release/X.Y.Z`. `main` is protected: it needs an approving review. + +## 2. Tag and publish to PyPI + +1. After the merge: `git checkout main && git pull --ff-only && git tag X.Y.Z && git push origin X.Y.Z`. +2. GitHub → **Releases** → *Draft a new release* for tag `X.Y.Z`, paste the changelog section, **Publish**. +3. Publishing the release runs [`publish.yml`](.github/workflows/publish.yml): it builds the sdist and + wheel, runs `twine check`, **refuses to continue when the tag differs from the `pyproject` version**, + smoke-installs the wheel, and uploads through PyPI **Trusted Publishing** (OIDC, the `pypi` + environment). No API token exists anywhere. +4. Verify from a clean environment — the PyPI simple index can lag the JSON API by a minute: + + ```bash + python3 -m venv /tmp/pm && /tmp/pm/bin/pip install -q "portable-memory==X.Y.Z" && /tmp/pm/bin/mem --version + ``` + +## 3. Homebrew + +The formula lives in [`MacPaw/homebrew-taps`](https://github.com/MacPaw/homebrew-taps) +(`Formula/portable-memory.rb`) and points at the PyPI **sdist**. Once PyPI serves the new version +(`brew livecheck macpaw/taps/portable-memory` reports it), open the bump PR: + +```bash +export HOMEBREW_GITHUB_API_TOKEN="$(gh auth token)" +brew bump-formula-pr --version=X.Y.Z macpaw/taps/portable-memory +``` + +This resolves the new sdist URL and `sha256` from PyPI, audits the formula, and opens a PR against the +tap from your fork. To do it by hand instead: take the sdist `url` and `digests.sha256` from +`https://pypi.org/pypi/portable-memory/X.Y.Z/json`, edit the formula, and run +`brew install --build-from-source`, `brew test`, `brew audit --strict --online` and `brew style` on +the tap before opening the PR. + +## 4. Swift SDK + +Mirror the release in `MacPaw/portable-memory-swift`: same changelog shape, tag `X.Y.Z`, GitHub +release. The [Swift Package Index](https://swiftpackageindex.com/MacPaw/portable-memory-swift) picks +the tag up on its own. diff --git a/pyproject.toml b/pyproject.toml index e86f3b0..b1e5230 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Software Development :: Libraries", ]