From a701d67a4bd1a960f85924addcd08dcc53ceafec Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Sun, 14 Jun 2026 12:46:30 -0700 Subject: [PATCH 1/2] Add manifest.json as the runtime source of truth manifest.json now drives the CI build matrix (the setup job reads [.pythons[].full_version] from it) and is published as a release asset with the release date injected, so serious_python and flet consume a single consistent version set (CPython + pyodide + dart_bridge) keyed by release date instead of hand-mirroring versions. --- .github/workflows/build-python.yml | 30 ++++++++++++-- README.md | 66 +++++++++++++++++++++++++++++- manifest.json | 27 ++++++++++++ 3 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 manifest.json diff --git a/.github/workflows/build-python.yml b/.github/workflows/build-python.yml index 28a156a..4369bfc 100644 --- a/.github/workflows/build-python.yml +++ b/.github/workflows/build-python.yml @@ -21,15 +21,28 @@ concurrency: cancel-in-progress: true jobs: + setup: + name: Read build matrix from manifest + runs-on: ubuntu-latest + outputs: + versions: ${{ steps.read.outputs.versions }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Extract Python versions from manifest.json + id: read + # manifest.json is the single source of truth: it both selects which + # CPython versions are built here and is published as a release asset + # (see publish-release) for serious_python / flet to consume. + run: echo "versions=$(jq -c '[.pythons[].full_version]' manifest.json)" >> "$GITHUB_OUTPUT" + build-matrix: name: Build Python ${{ matrix.python_version }} + needs: setup strategy: fail-fast: false matrix: - python_version: - - 3.12.13 - - 3.13.14 - - 3.14.6 + python_version: ${{ fromJSON(needs.setup.outputs.versions) }} uses: ./.github/workflows/build-python-version.yml with: python_version: ${{ matrix.python_version }} @@ -44,10 +57,14 @@ jobs: # not touch GitHub releases. if: github.event_name == 'workflow_dispatch' && inputs.release_date != '' needs: + - setup - build-matrix permissions: contents: write steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Download all build artifacts uses: actions/download-artifact@v8 with: @@ -55,6 +72,11 @@ jobs: path: release-artifacts merge-multiple: true + - name: Add runtime manifest (with release date) to the release + # Publish the same manifest.json that drove this build, with the release + # date injected, so consumers can fetch a consistent version set by date. + run: jq '.release = "${{ inputs.release_date }}"' manifest.json > release-artifacts/manifest.json + - name: Publish all artifacts to release uses: softprops/action-gh-release@v3 with: diff --git a/README.md b/README.md index ec7f0c6..a2193fc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,66 @@ # python-build -Building Python for Android and iOS + +Builds the embedded CPython runtimes (Android, iOS, macOS, Linux, Windows) that +[serious_python](https://github.com/flet-dev/serious-python) and +[flet](https://github.com/flet-dev/flet) bundle into apps. + +## `manifest.json` — the runtime source of truth + +[`manifest.json`](manifest.json) is the single source of truth for a runtime +release. It is used **both** ways: + +- **Drives the build.** CI reads it to decide which CPython versions to build + (the build matrix), so what gets built is exactly what the manifest lists. +- **Is published.** Each release uploads the same `manifest.json` as a release + asset (with the `release` date injected), so downstream tools fetch a single, + consistent version set by date instead of hand-mirroring versions. + +Schema: + +```json +{ + "release": "20260611", // injected at publish (= release tag) + "default_python_version": "3.14", + "dart_bridge_version": "1.2.3", + "pythons": { + "3.14": { + "full_version": "3.14.6", + "standalone_release_date": "20260610", + "pyodide_version": "314.0.0", + "pyodide_platform_tag": "pyemscripten-2026.0-wasm32", + "prerelease": false + } + } +} +``` + +The committed file omits `release`; the publish step injects it. + +### Adding or bumping a Python / Pyodide / dart_bridge version + +Edit [`manifest.json`](manifest.json) and open a PR. The CI matrix updates +automatically from it; per-version build specifics (ABIs, the 3.12 vs 3.13+ build +method) live in the platform build scripts. + +## Releases + +Releases are date-keyed (`YYYYMMDD`) and cut manually: + +1. Run the **Build Python Packages** workflow via `workflow_dispatch` with a + `release_date` of `YYYYMMDD`. +2. CI builds every Python in the manifest matrix, then publishes all per-platform + tarballs **and** `manifest.json` (with `release` set) to a GitHub release tagged + with that date. + +A push without a `release_date` still exercises the full matrix but publishes no +release (per-job artifacts only). + +## Consumers + +- **serious_python** pins a release date, fetches that release's `manifest.json`, + and generates committed per-platform version tables from it. +- **flet** fetches the manifest by date for commands that run without serious_python + (e.g. `flet publish`). + +See platform-specific notes under [`android/`](android/README.md), +[`darwin/`](darwin/README.rst), `linux/`, and `windows/`. diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..4b2117b --- /dev/null +++ b/manifest.json @@ -0,0 +1,27 @@ +{ + "default_python_version": "3.14", + "dart_bridge_version": "1.2.3", + "pythons": { + "3.12": { + "full_version": "3.12.13", + "standalone_release_date": "20260610", + "pyodide_version": "0.27.7", + "pyodide_platform_tag": "pyodide-2024.0-wasm32", + "prerelease": false + }, + "3.13": { + "full_version": "3.13.14", + "standalone_release_date": "20260610", + "pyodide_version": "0.29.4", + "pyodide_platform_tag": "pyemscripten-2025.0-wasm32", + "prerelease": false + }, + "3.14": { + "full_version": "3.14.6", + "standalone_release_date": "20260610", + "pyodide_version": "314.0.0", + "pyodide_platform_tag": "pyemscripten-2026.0-wasm32", + "prerelease": false + } + } +} From 1cdde7796731f13acf8f73754cf830e2a4bed68e Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Sun, 14 Jun 2026 13:05:04 -0700 Subject: [PATCH 2/2] Bump actions/checkout to v6 in workflows Update .github/workflows/build-python.yml to use actions/checkout@v6 instead of v4 in both jobs. This brings the workflow up to the newer checkout action version to pick up improvements and fixes. --- .github/workflows/build-python.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-python.yml b/.github/workflows/build-python.yml index 4369bfc..40a43ac 100644 --- a/.github/workflows/build-python.yml +++ b/.github/workflows/build-python.yml @@ -28,7 +28,7 @@ jobs: versions: ${{ steps.read.outputs.versions }} steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Extract Python versions from manifest.json id: read # manifest.json is the single source of truth: it both selects which @@ -63,7 +63,7 @@ jobs: contents: write steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Download all build artifacts uses: actions/download-artifact@v8