From fc9d36a188e6c6c4c4927fff9f8f36faa00112ff Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Wed, 20 May 2026 10:19:55 +0530 Subject: [PATCH 01/10] Accept `published_at` field for `CrossBuildEnvReleaseSpec` --- pyodide_build/xbuildenv_releases.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyodide_build/xbuildenv_releases.py b/pyodide_build/xbuildenv_releases.py index d5d13fbd..2b3131ef 100644 --- a/pyodide_build/xbuildenv_releases.py +++ b/pyodide_build/xbuildenv_releases.py @@ -23,6 +23,8 @@ class CrossBuildEnvReleaseSpec(BaseModel): python_version: str # The version of the Emscripten SDK emscripten_version: str + # The UTC timestamp when the release was published on GitHub (ISO 8601) + published_at: str | None = None # Minimum and maximum pyodide-build versions that are compatible with this release min_pyodide_build_version: str | None = None max_pyodide_build_version: str | None = None From 7c5b254ab82303b4ad82f8810e945983245e9e5a Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Wed, 20 May 2026 10:20:00 +0530 Subject: [PATCH 02/10] Add a test --- .../tests/test_xbuildenv_releases.py | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pyodide_build/tests/test_xbuildenv_releases.py b/pyodide_build/tests/test_xbuildenv_releases.py index b6295798..269d4462 100644 --- a/pyodide_build/tests/test_xbuildenv_releases.py +++ b/pyodide_build/tests/test_xbuildenv_releases.py @@ -243,6 +243,31 @@ def test_is_compatible_full(): ) +def test_published_at(): + release = CrossBuildEnvReleaseSpec( + version="0.1.0", + url="https://example.com/0.1.0.tar.gz", + sha256="1234567890abcdef", + python_version="3.8.0", + emscripten_version="1.39.8", + published_at="2024-01-18T21:52:25Z", + ) + assert release.published_at == "2024-01-18T21:52:25Z" + + release_no_date = CrossBuildEnvReleaseSpec( + version="0.1.0", + url="https://example.com/0.1.0.tar.gz", + sha256="1234567890abcdef", + python_version="3.8.0", + emscripten_version="1.39.8", + ) + assert release_no_date.published_at is None + + metadata = CrossBuildEnvMetaSpec(**FAKE_METADATA) + for release in metadata.releases.values(): + assert release.published_at is None + + def test_is_compatible_without_pyodide_build_range(): release = CrossBuildEnvReleaseSpec( version="0.1.0", From e3e83ae1c1a9ce6e0fdcab61cb8770db6a0a935a Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Wed, 20 May 2026 10:32:40 +0530 Subject: [PATCH 03/10] Add "Published" and "published_at" for views --- pyodide_build/cli/xbuildenv.py | 1 + pyodide_build/tests/test_cli_xbuildenv.py | 4 +++- pyodide_build/views.py | 7 ++++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/pyodide_build/cli/xbuildenv.py b/pyodide_build/cli/xbuildenv.py index 3b267727..ebd0564b 100644 --- a/pyodide_build/cli/xbuildenv.py +++ b/pyodide_build/cli/xbuildenv.py @@ -237,6 +237,7 @@ def _search( "min": release.min_pyodide_build_version, "max": release.max_pyodide_build_version, }, + published_at=release.published_at, compatible=release.is_compatible( python_version=local["python"], pyodide_build_version=local["pyodide-build"], diff --git a/pyodide_build/tests/test_cli_xbuildenv.py b/pyodide_build/tests/test_cli_xbuildenv.py index 52bb1d40..eda434e9 100644 --- a/pyodide_build/tests/test_cli_xbuildenv.py +++ b/pyodide_build/tests/test_cli_xbuildenv.py @@ -352,11 +352,12 @@ def test_xbuildenv_search( "Python", "Emscripten", "pyodide-build", + "Published", "Compatible", ] row1 = lines[3].strip().split("│")[1:-1] - assert [col.strip() for col in row1] == ["0.1.0", "4.5.6", "1.39.8", "-", "No"] + assert [col.strip() for col in row1] == ["0.1.0", "4.5.6", "1.39.8", "-", "", "No"] def test_xbuildenv_search_json(tmp_path, fake_xbuildenv_releases_compatible): @@ -390,6 +391,7 @@ def test_xbuildenv_search_json(tmp_path, fake_xbuildenv_releases_compatible): "python", "emscripten", "pyodide_build", + "published_at", "compatible", }, f"Environment {environment} has unexpected keys: {environment.keys()}" diff --git a/pyodide_build/views.py b/pyodide_build/views.py index eabe42fb..ca378bfd 100644 --- a/pyodide_build/views.py +++ b/pyodide_build/views.py @@ -13,6 +13,7 @@ class MetadataView: emscripten: str pyodide_build: dict[str, str | None] compatible: bool + published_at: str | None = None @classmethod def to_table(cls, views: list["MetadataView"]) -> str: @@ -21,6 +22,7 @@ def to_table(cls, views: list["MetadataView"]) -> str: ("Python", 10), ("Emscripten", 10), ("pyodide-build", 25), + ("Published", 10), ("Compatible", 10), ] @@ -59,12 +61,14 @@ def to_table(cls, views: list["MetadataView"]) -> str: pyodide_build_range = ( f"{view.pyodide_build['min'] or ''} - {view.pyodide_build['max'] or ''}" ) + published = (view.published_at or "")[:10] row = [ f"{view.version:<{columns[0][1]}}", f"{view.python:<{columns[1][1]}}", f"{view.emscripten:<{columns[2][1]}}", f"{pyodide_build_range:<{columns[3][1]}}", - f"{'Yes' if view.compatible else 'No':<{columns[4][1]}}", + f"{published:<{columns[4][1]}}", + f"{'Yes' if view.compatible else 'No':<{columns[5][1]}}", ] table.append( vertical + vertical.join(f" {cell} " for cell in row) + vertical @@ -82,6 +86,7 @@ def to_json(cls, views: list["MetadataView"]) -> str: "python": view.python, "emscripten": view.emscripten, "pyodide_build": view.pyodide_build, + "published_at": view.published_at, "compatible": view.compatible, } for view in views From 58201e01bc87bb9639ffb09daeda5dc1bd3faa23 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Wed, 20 May 2026 10:41:23 +0530 Subject: [PATCH 04/10] Add a CHANGELOG entry for #349 --- CHANGELOG.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7aebe66..3cf9d47b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [0.34.5] - 2026/05/20 + +### Added + +- `CrossBuildEnvReleaseSpec` now has a `published_at` field containing the UTC timestamp + when the release was published on GitHub (ISO 8601 format). This is exposed in + `pyodide xbuildenv search --all` and `pyodide xbuildenv search --all --json`. + [#349](https://github.com/pyodide/pyodide-build/pull/349) ## [0.34.4] - 2026/05/15 From 5ab72ae9ad50a5e2a29cf729f70494d77386559d Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Wed, 20 May 2026 15:36:13 +0530 Subject: [PATCH 05/10] Loosen the `CrossBuildEnvReleasesSpec` requirement --- pyodide_build/xbuildenv_releases.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyodide_build/xbuildenv_releases.py b/pyodide_build/xbuildenv_releases.py index 2b3131ef..c7acf808 100644 --- a/pyodide_build/xbuildenv_releases.py +++ b/pyodide_build/xbuildenv_releases.py @@ -28,7 +28,7 @@ class CrossBuildEnvReleaseSpec(BaseModel): # Minimum and maximum pyodide-build versions that are compatible with this release min_pyodide_build_version: str | None = None max_pyodide_build_version: str | None = None - model_config = ConfigDict(extra="forbid", title="CrossBuildEnvReleasesSpec") + model_config = ConfigDict(extra="ignore", title="CrossBuildEnvReleasesSpec") @property def python_version_tuple(self) -> tuple[int, int, int]: From f15d1c9787c7d55d8fcf235e1260efa43bf92980 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Wed, 20 May 2026 15:36:30 +0530 Subject: [PATCH 06/10] Update xbuildenv URL to v2 --- pyodide_build/xbuildenv_releases.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyodide_build/xbuildenv_releases.py b/pyodide_build/xbuildenv_releases.py index c7acf808..06602dde 100644 --- a/pyodide_build/xbuildenv_releases.py +++ b/pyodide_build/xbuildenv_releases.py @@ -7,7 +7,7 @@ from pydantic import BaseModel, ConfigDict DEFAULT_CROSS_BUILD_ENV_METADATA_URL = ( - "https://pyodide.github.io/pyodide/api/pyodide-cross-build-environments.json" + "https://pyodide.github.io/pyodide/api/v2/pyodide-cross-build-environments.json" ) CROSS_BUILD_ENV_METADATA_URL_ENV_VAR = "PYODIDE_CROSS_BUILD_ENV_METADATA_URL" From 14500af6d188a690293c34ad942f3851627aac2d Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Wed, 20 May 2026 16:33:10 +0530 Subject: [PATCH 07/10] Temporarily revert "Update xbuildenv URL to v2" This reverts commit f15d1c9787c7d55d8fcf235e1260efa43bf92980. --- pyodide_build/xbuildenv_releases.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyodide_build/xbuildenv_releases.py b/pyodide_build/xbuildenv_releases.py index 06602dde..c7acf808 100644 --- a/pyodide_build/xbuildenv_releases.py +++ b/pyodide_build/xbuildenv_releases.py @@ -7,7 +7,7 @@ from pydantic import BaseModel, ConfigDict DEFAULT_CROSS_BUILD_ENV_METADATA_URL = ( - "https://pyodide.github.io/pyodide/api/v2/pyodide-cross-build-environments.json" + "https://pyodide.github.io/pyodide/api/pyodide-cross-build-environments.json" ) CROSS_BUILD_ENV_METADATA_URL_ENV_VAR = "PYODIDE_CROSS_BUILD_ENV_METADATA_URL" From 826f23fd0a1e64f8bcd9733ab3cd441b7467e7c6 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Thu, 21 May 2026 14:54:33 +0530 Subject: [PATCH 08/10] Reapply "Update xbuildenv URL to v2" This reapplies commit 14500af6d188a690293c34ad942f3851627aac2d. --- pyodide_build/xbuildenv_releases.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyodide_build/xbuildenv_releases.py b/pyodide_build/xbuildenv_releases.py index c7acf808..06602dde 100644 --- a/pyodide_build/xbuildenv_releases.py +++ b/pyodide_build/xbuildenv_releases.py @@ -7,7 +7,7 @@ from pydantic import BaseModel, ConfigDict DEFAULT_CROSS_BUILD_ENV_METADATA_URL = ( - "https://pyodide.github.io/pyodide/api/pyodide-cross-build-environments.json" + "https://pyodide.github.io/pyodide/api/v2/pyodide-cross-build-environments.json" ) CROSS_BUILD_ENV_METADATA_URL_ENV_VAR = "PYODIDE_CROSS_BUILD_ENV_METADATA_URL" From 36d0edc273d2727f7ac7180f3f8774ea0603028c Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Thu, 21 May 2026 15:00:39 +0530 Subject: [PATCH 09/10] Default `published_at` to empty string Co-Authored-By: Gyeongjae Choi --- pyodide_build/views.py | 4 ++-- pyodide_build/xbuildenv_releases.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyodide_build/views.py b/pyodide_build/views.py index ca378bfd..3968a9e8 100644 --- a/pyodide_build/views.py +++ b/pyodide_build/views.py @@ -13,7 +13,7 @@ class MetadataView: emscripten: str pyodide_build: dict[str, str | None] compatible: bool - published_at: str | None = None + published_at: str = "" @classmethod def to_table(cls, views: list["MetadataView"]) -> str: @@ -61,7 +61,7 @@ def to_table(cls, views: list["MetadataView"]) -> str: pyodide_build_range = ( f"{view.pyodide_build['min'] or ''} - {view.pyodide_build['max'] or ''}" ) - published = (view.published_at or "")[:10] + published = view.published_at[:10] row = [ f"{view.version:<{columns[0][1]}}", f"{view.python:<{columns[1][1]}}", diff --git a/pyodide_build/xbuildenv_releases.py b/pyodide_build/xbuildenv_releases.py index 06602dde..1f6814e4 100644 --- a/pyodide_build/xbuildenv_releases.py +++ b/pyodide_build/xbuildenv_releases.py @@ -24,7 +24,7 @@ class CrossBuildEnvReleaseSpec(BaseModel): # The version of the Emscripten SDK emscripten_version: str # The UTC timestamp when the release was published on GitHub (ISO 8601) - published_at: str | None = None + published_at: str = "" # Minimum and maximum pyodide-build versions that are compatible with this release min_pyodide_build_version: str | None = None max_pyodide_build_version: str | None = None From e9a322206335308f9743ff68149b7b3fb3c47507 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Thu, 21 May 2026 15:05:44 +0530 Subject: [PATCH 10/10] Fix --- pyodide_build/tests/test_xbuildenv_releases.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyodide_build/tests/test_xbuildenv_releases.py b/pyodide_build/tests/test_xbuildenv_releases.py index 269d4462..b20d147a 100644 --- a/pyodide_build/tests/test_xbuildenv_releases.py +++ b/pyodide_build/tests/test_xbuildenv_releases.py @@ -261,11 +261,11 @@ def test_published_at(): python_version="3.8.0", emscripten_version="1.39.8", ) - assert release_no_date.published_at is None + assert release_no_date.published_at == "" metadata = CrossBuildEnvMetaSpec(**FAKE_METADATA) for release in metadata.releases.values(): - assert release.published_at is None + assert release.published_at == "" def test_is_compatible_without_pyodide_build_range():