diff --git a/CLAUDE.md b/CLAUDE.md index f57975e..0e91795 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,3 +22,4 @@ The authoritative, self-contained documentation is the OKF knowledge bundle unde - Check **runez** before reimplementing file / system / CLI / logging / version helpers — see [`docs/guides/local-development.md`](docs/guides/local-development.md). - The docs use the OKF format; keep the bundle conformant (`scripts/check_okf.py docs`) when you edit it. +- As changes land, keep a top section in [`docs/changelog.md`](docs/changelog.md) for the upcoming release — `## Unreleased`, or the next version directly once it's known. Maintain it as PRs come in; it's double-checked at release. Don't fuss over marking released-vs-unreleased (small audience, `git tag` says what's out). diff --git a/docs/changelog.md b/docs/changelog.md new file mode 100644 index 0000000..5350440 --- /dev/null +++ b/docs/changelog.md @@ -0,0 +1,13 @@ +--- +type: Changelog +title: Changelog +description: High-level release highlights for portable-python, newest first. +tags: [changelog, releases] +timestamp: 2026-06-23T00:00:00Z +--- + +## v2.0.1 + +- Bumped the bundled components (OpenSSL, SQLite, Tcl/Tk, …) to current versions. +- Refreshed dependencies and modernized CI (now on uv / tox-uv, with updated GitHub Actions). +- Added an OKF documentation bundle under `docs/` (the old top-level docs folded into it). diff --git a/docs/guides/bump-components.md b/docs/guides/bump-components.md new file mode 100644 index 0000000..e5972e8 --- /dev/null +++ b/docs/guides/bump-components.md @@ -0,0 +1,66 @@ +--- +type: Playbook +title: Bump Component Versions +description: >- + How to update the pinned upstream versions of the external C libraries (ModuleBuilder + subclasses) statically linked into CPython. +tags: [playbook, modules, versions, maintenance] +timestamp: 2026-06-23T00:00:00Z +--- + +# Bump Component Versions + +Each [external module](/modules/index.md) pins a default upstream version — the `cfg_version("…")` +in its `version` property. This playbook keeps those current without breaking the build. + +## Steps + +1. **List the components** — the `ModuleBuilder` subclasses under `src/portable_python/external/` + (openssl, zlib, xz, sqlite, … plus sub-modules like ncurses/tcl/tk and the toolchain). The + [external modules reference](/modules/external-modules.md) is the catalog. +2. **Check upstream** for each. Its `version` property carries a comment with the release/EOL links + to check and its bump policy — read that first. +3. **Pick a version** using the rule below. +4. **Update** the `cfg_version("…")` default, and refresh the comment (EOL dates, "stay on LTS", + last-checked). +5. **Confirm it still builds** — [`build-report`](/cli/build-report.md), then a real build (see + [local development](/guides/local-development.md)). + +## Patch vs major/minor + +- **Patch bumps** (e.g. OpenSSL `3.5.6 → 3.5.7`) — almost always OK; stay within the current line + and bump freely. +- **Major / minor bumps** (e.g. OpenSSL `3.6` or `4.0`) — **research them first.** Start from the + official CPython build docs ([devguide: setup & building][cpython-build]) and see which versions + the CPython team recommends. That is often not stated explicitly; when it isn't, do due-diligence + research online before moving. When unsure, stay on the current / LTS line. + - **Be extra wary of a fresh `.0`** (`3.6.0`, `4.0.0`, …) — wait for at least the `.1` before + adopting a new line. Early `.0` releases carry the most bugs and are sometimes withdrawn + (SQLite `3.52.0` was). Move to a `.0` only with a pressing reason. + +[cpython-build]: https://devguide.python.org/getting-started/setup-building/index.html + +There is **no local test matrix that validates component-version choices** — but "does it still +build" is a real check: building CPython runs its own test suite as part of the process (an +`--enable-optimizations` / PGO build exercises much of it), so a wrongly-built component — a broken +openssl, say — shows up as a build failure. The validation rests entirely on CPython's own tests; +portable-python doesn't re-validate CPython itself. Picking *which* version is safe is what the +research above is for. + +## Record the policy in code, not here + +Per-component specifics — which line is LTS, EOL dates, where to check, when it's safe to jump — +belong as a **comment in that module's `version` property**, right next to the value, so they can't +drift from these docs: + +```python +@property +def version(self): + # + # + # Check and + return self.cfg_version("X.Y.Z") +``` + +`Openssl.version` is the live model. When you bump a component whose `version` property lacks such a +comment, add one. diff --git a/docs/guides/index.md b/docs/guides/index.md index 697e7c8..73c8cdd 100644 --- a/docs/guides/index.md +++ b/docs/guides/index.md @@ -4,6 +4,7 @@ Task-oriented playbooks for using and extending portable-python. * [Build a portable python](/guides/build-a-portable-python.md) - Install the tool, build a binary, and use it. * [Add an external module](/guides/add-an-external-module.md) - Add a new C library to the static-link set. +* [Bump component versions](/guides/bump-components.md) - Update the pinned upstream versions of the external C libraries. * [Add a config option](/guides/add-a-config-option.md) - Introduce a new configuration key. * [Fix a portability issue](/guides/fix-a-portability-issue.md) - Diagnose and correct a non-portable build. * [Bump python support](/guides/bump-python-support.md) - Move the supported CPython version window. diff --git a/docs/index.md b/docs/index.md index 8953514..367ce58 100644 --- a/docs/index.md +++ b/docs/index.md @@ -18,6 +18,8 @@ Start with the [Overview](/overview.md), then drill into the area you need. * [External Modules](/modules/index.md) - The C libraries compiled and statically linked into CPython. * [Configuration](/configuration/index.md) - The `portable-python.yml` file, its sections and overrides. * [Guides](/guides/index.md) - Playbooks for common tasks: building, extending, local development. +* [Release process](/release.md) - How to cut a release: changelog highlights, then a version tag. +* [Changelog](/changelog.md) - High-level release highlights, newest first. ## Conventions diff --git a/docs/log.md b/docs/log.md index b650c3d..e421617 100644 --- a/docs/log.md +++ b/docs/log.md @@ -2,6 +2,8 @@ ## 2026-06-23 +* **Creation**: Added the [release process](/release.md) playbook and the [changelog](/changelog.md). +* **Creation**: Added the [bump component versions](/guides/bump-components.md) guide. * **Update**: Pulled two verified facts in from the project wiki — the relativization tools (`patchelf` / `install_name_tool`) and `--prefix` / `--enable-shared` support ([PythonInspector](/architecture/python-inspector.md)), and the `#sha256=` download-checksum URL fragment ([configuration](/configuration/portable-python-yml.md)). Skipped the wiki's `sources:` download-url design — it's an unimplemented draft. * **Update**: Trimmed the CLI pages — dropped the per-command option tables (which mirror `--help`) for purpose + non-obvious gotchas + examples, pointing at `--help` for the full flag list. * **Update**: Reshaped the six architecture `type: Class` pages — dropped the `# Schema` member tables (which mirrored code and risked drift) for a condensed mental-model + "worth knowing" framing; the code stays authoritative for the API. diff --git a/docs/release.md b/docs/release.md new file mode 100644 index 0000000..b11d105 --- /dev/null +++ b/docs/release.md @@ -0,0 +1,52 @@ +--- +type: Playbook +title: Release Process +description: >- + How to cut a release for this repo — refresh the changelog highlights, then tag a new + version from a clean main. +tags: [playbook, release, versioning, changelog] +timestamp: 2026-06-23T00:00:00Z +--- + +# Release Process + +Releasing is opinionated and per-repo; this is portable-python's convention. A release is cut by +pushing a version tag from `main` — that's what triggers the build + PyPI publish (see +[CI/CD](/guides/ci-cd.md)). + +## 1. Refresh the changelog + +Review what changed since the last release: + +```bash +git diff ..main # e.g. git diff v2.0.0..main +``` + +Summarize the **highlights** in [`changelog.md`](/changelog.md) — short and high-level. It should +give a reader a rough idea of the main changes since the last release, not a blow-by-blow; skip the +details. + +- If the changelog is **already up to date** with `main`, go to step 2. +- If it's **not**, update it first — recommend landing that as its own PR before releasing. + +## 2. Tag the release + +Only once `main` is ready: the changelog is up to date, and you're on a **clean checkout of +`main`**. + +Choose the bump — **ask the user; default to patch** — following semver from the last tag: + +| Bump | When | Example | +|------|------|---------| +| patch | fixes, component bumps, docs | `v2.0.0 → v2.0.1` | +| minor | backward-compatible features | `v2.0.0 → v2.1.0` | +| major | breaking changes | `v2.0.0 → v3.0.0` | + +Then **confirm the exact version with the user, and show these two commands before running them:** + +```bash +git tag v2.0.1 +git push origin v2.0.1 +``` + +The tag push is what kicks off the release — there's nothing else to run. diff --git a/src/portable_python/external/xcpython.py b/src/portable_python/external/xcpython.py index 579cdc7..24a5846 100644 --- a/src/portable_python/external/xcpython.py +++ b/src/portable_python/external/xcpython.py @@ -183,8 +183,9 @@ def url(self): @property def version(self): # 3.5 is LTS, supported until Apr 2030 (3.0 EOL Sept 2026) + # Stay on the 3.5 LTS line for now: 3.6 / 4.0 not yet verified for cpython builds # Check https://github.com/openssl/openssl/releases and https://endoflife.date/openssl - return self.cfg_version("3.5.6") + return self.cfg_version("3.5.7") def c_configure_args(self): if config_args := self.cfg_configure(self.deps_lib_dir, self.deps_lib64_dir): @@ -317,8 +318,8 @@ def url(self): @property def version(self): - # Check https://sqlite.org/changes.html (avoid withdrawn releases like 3.52.0) - return self.cfg_version("3.51.3") + # Keep current; check https://sqlite.org/changes.html (avoid withdrawn releases like 3.52.0) + return self.cfg_version("3.53.2") def c_configure_args(self): if config_args := self.cfg_configure(self.deps_lib_dir, self.deps_lib64_dir): diff --git a/src/portable_python/external/xtkinter.py b/src/portable_python/external/xtkinter.py index 31ef27b..8d239d1 100644 --- a/src/portable_python/external/xtkinter.py +++ b/src/portable_python/external/xtkinter.py @@ -121,4 +121,4 @@ def version(self): # This is the Tcl/Tk version used by Tcl, Tk, and Tix sub-modules # Staying on 8.6.x branch (9.0+ is a major rewrite) # Check https://www.tcl-lang.org/software/tcltk/8.6.html - return self.cfg_version("8.6.17") + return self.cfg_version("8.6.18")