mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
4d0c4cd058
## Why `openai-codex` needs a beta release lifecycle without requiring beta releases of its pinned runtime package. Previously, SDK staging rewrote its runtime dependency to the SDK version, which made an SDK-only beta impossible. ## What changed - Set the initial SDK beta version to `0.1.0b1` and pin it to published stable `openai-codex-cli-bin==0.132.0`. - Decoupled SDK release staging from runtime versioning so it preserves the reviewed exact runtime pin. - Added a `python-v*` tag workflow that builds and publishes only `openai-codex` through PyPI trusted publishing. - Removed the Beta classifier from runtime package metadata for future runtime publications. - Regenerated protocol-derived SDK models from the selected stable runtime package. `0.132.0` is the newest stable runtime admitted by the checked-in dependency date fence and retains the Linux wheel family currently used by SDK CI. ## Release setup Before pushing `python-v0.1.0b1`, configure PyPI trusted publishing for the `openai-codex` project with workflow `python-sdk-release.yml`, environment `pypi`, and job `publish-python-sdk`. ## Validation - `uv run --frozen --extra dev ruff check src/openai_codex scripts examples tests` - Parsed `.github/workflows/python-sdk-release.yml` with PyYAML. - Built staged release artifacts locally: `openai_codex-0.1.0b1-py3-none-any.whl` and `openai_codex-0.1.0b1.tar.gz`. - Verified wheel metadata pins `openai-codex-cli-bin==0.132.0`. - Tests are deferred to online CI for this PR.
58 lines
1.9 KiB
Python
58 lines
1.9 KiB
Python
from __future__ import annotations
|
|
|
|
import importlib.metadata
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
GENERATED_TARGETS = [
|
|
Path("src/openai_codex/generated/notification_registry.py"),
|
|
Path("src/openai_codex/generated/v2_all.py"),
|
|
Path("src/openai_codex/api.py"),
|
|
]
|
|
|
|
|
|
def _snapshot_target(root: Path, rel_path: Path) -> dict[str, bytes] | bytes | None:
|
|
"""Capture one generated artifact so regeneration drift is easy to compare."""
|
|
target = root / rel_path
|
|
if not target.exists():
|
|
return None
|
|
if target.is_file():
|
|
return target.read_bytes()
|
|
|
|
snapshot: dict[str, bytes] = {}
|
|
for path in sorted(target.rglob("*")):
|
|
if path.is_file() and "__pycache__" not in path.parts:
|
|
snapshot[str(path.relative_to(target))] = path.read_bytes()
|
|
return snapshot
|
|
|
|
|
|
def _snapshot_targets(root: Path) -> dict[str, dict[str, bytes] | bytes | None]:
|
|
"""Capture all checked-in generated artifacts before and after regeneration."""
|
|
return {str(rel_path): _snapshot_target(root, rel_path) for rel_path in GENERATED_TARGETS}
|
|
|
|
|
|
def test_generated_files_are_up_to_date():
|
|
"""Regenerating from the pinned runtime package should leave artifacts unchanged."""
|
|
before = _snapshot_targets(ROOT)
|
|
|
|
# Regenerate contract artifacts via the pinned runtime package, not a local
|
|
# app-server binary from the checkout or CI environment.
|
|
assert importlib.metadata.version("openai-codex-cli-bin") == "0.132.0"
|
|
env = os.environ.copy()
|
|
env.pop("CODEX_EXEC_PATH", None)
|
|
python_bin = str(Path(sys.executable).parent)
|
|
env["PATH"] = f"{python_bin}{os.pathsep}{env.get('PATH', '')}"
|
|
|
|
subprocess.run(
|
|
[sys.executable, "scripts/update_sdk_artifacts.py", "generate-types"],
|
|
cwd=ROOT,
|
|
check=True,
|
|
env=env,
|
|
)
|
|
|
|
after = _snapshot_targets(ROOT)
|
|
assert before == after, "Generated files drifted after regeneration"
|