mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[codex] Add independent beta release for the Python SDK (#24828)
## 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.
This commit is contained in:
committed by
GitHub
Unverified
parent
304d15cab0
commit
4d0c4cd058
@@ -216,25 +216,8 @@ def _rewrite_project_name(pyproject_text: str, name: str) -> str:
|
||||
return updated
|
||||
|
||||
|
||||
def _rewrite_sdk_runtime_dependency(pyproject_text: str, runtime_version: str) -> str:
|
||||
match = re.search(r"^dependencies = \[(.*?)\]$", pyproject_text, flags=re.MULTILINE)
|
||||
if match is None:
|
||||
raise RuntimeError("Could not find dependencies array in sdk/python/pyproject.toml")
|
||||
|
||||
raw_items = [item.strip() for item in match.group(1).split(",") if item.strip()]
|
||||
raw_items = [
|
||||
item
|
||||
for item in raw_items
|
||||
if RUNTIME_DISTRIBUTION_NAME.removeprefix("openai-") not in item
|
||||
and RUNTIME_DISTRIBUTION_NAME not in item
|
||||
]
|
||||
raw_items.append(f'"{RUNTIME_DISTRIBUTION_NAME}=={runtime_version}"')
|
||||
replacement = "dependencies = [\n " + ",\n ".join(raw_items) + ",\n]"
|
||||
return pyproject_text[: match.start()] + replacement + pyproject_text[match.end() :]
|
||||
|
||||
|
||||
def stage_python_sdk_package(staging_dir: Path, codex_version: str) -> Path:
|
||||
package_version = normalize_codex_version(codex_version)
|
||||
def stage_python_sdk_package(staging_dir: Path, sdk_version: str) -> Path:
|
||||
package_version = normalize_codex_version(sdk_version)
|
||||
_copy_package_tree(sdk_root(), staging_dir)
|
||||
sdk_bin_dir = staging_dir / "src" / "openai_codex" / "bin"
|
||||
if sdk_bin_dir.exists():
|
||||
@@ -244,7 +227,6 @@ def stage_python_sdk_package(staging_dir: Path, codex_version: str) -> Path:
|
||||
pyproject_text = pyproject_path.read_text()
|
||||
pyproject_text = _rewrite_project_name(pyproject_text, SDK_DISTRIBUTION_NAME)
|
||||
pyproject_text = _rewrite_project_version(pyproject_text, package_version)
|
||||
pyproject_text = _rewrite_sdk_runtime_dependency(pyproject_text, package_version)
|
||||
pyproject_path.write_text(pyproject_text)
|
||||
return staging_dir
|
||||
|
||||
@@ -1229,28 +1211,20 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
|
||||
stage_sdk_parser = subparsers.add_parser(
|
||||
"stage-sdk",
|
||||
help="Stage a releasable SDK package pinned to a runtime version",
|
||||
help="Stage a releasable SDK package while preserving its reviewed runtime pin",
|
||||
)
|
||||
stage_sdk_parser.add_argument(
|
||||
"staging_dir",
|
||||
type=Path,
|
||||
help="Output directory for the staged SDK package",
|
||||
)
|
||||
stage_sdk_parser.add_argument(
|
||||
"--codex-version",
|
||||
help=(
|
||||
"Codex release version to write into the staged SDK package and exact "
|
||||
f"{RUNTIME_DISTRIBUTION_NAME} dependency. Accepts PEP 440 versions "
|
||||
"or release tags such as rust-v0.116.0-alpha.1."
|
||||
),
|
||||
)
|
||||
stage_sdk_parser.add_argument(
|
||||
"--runtime-version",
|
||||
help=argparse.SUPPRESS,
|
||||
)
|
||||
stage_sdk_parser.add_argument(
|
||||
"--sdk-version",
|
||||
help=argparse.SUPPRESS,
|
||||
required=True,
|
||||
help=(
|
||||
"Python SDK release version to write into the staged package. "
|
||||
"Accepts PEP 440 versions such as 0.1.0b1."
|
||||
),
|
||||
)
|
||||
|
||||
stage_runtime_parser = subparsers.add_parser(
|
||||
@@ -1269,15 +1243,12 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
)
|
||||
stage_runtime_parser.add_argument(
|
||||
"--codex-version",
|
||||
required=True,
|
||||
help=(
|
||||
"Codex release version to write into the staged runtime package. "
|
||||
"Accepts PEP 440 versions or release tags such as rust-v0.116.0-alpha.1."
|
||||
),
|
||||
)
|
||||
stage_runtime_parser.add_argument(
|
||||
"--runtime-version",
|
||||
help=argparse.SUPPRESS,
|
||||
)
|
||||
stage_runtime_parser.add_argument(
|
||||
"--platform-tag",
|
||||
help=(
|
||||
@@ -1301,40 +1272,19 @@ def default_cli_ops() -> CliOps:
|
||||
)
|
||||
|
||||
|
||||
def _resolve_codex_version(args: argparse.Namespace) -> str:
|
||||
versions = [
|
||||
value
|
||||
for value in (
|
||||
getattr(args, "codex_version", None),
|
||||
getattr(args, "runtime_version", None),
|
||||
getattr(args, "sdk_version", None),
|
||||
)
|
||||
if value is not None
|
||||
]
|
||||
if not versions:
|
||||
raise RuntimeError("Pass --codex-version to stage Python release artifacts")
|
||||
|
||||
normalized_versions = [normalize_codex_version(version) for version in versions]
|
||||
if len(set(normalized_versions)) != 1:
|
||||
raise RuntimeError("SDK and runtime package versions must match; pass one --codex-version")
|
||||
return normalized_versions[0]
|
||||
|
||||
|
||||
def run_command(args: argparse.Namespace, ops: CliOps) -> None:
|
||||
if args.command == "generate-types":
|
||||
ops.generate_types()
|
||||
elif args.command == "stage-sdk":
|
||||
codex_version = _resolve_codex_version(args)
|
||||
ops.generate_types()
|
||||
ops.stage_python_sdk_package(
|
||||
args.staging_dir,
|
||||
codex_version,
|
||||
normalize_codex_version(args.sdk_version),
|
||||
)
|
||||
elif args.command == "stage-runtime":
|
||||
codex_version = _resolve_codex_version(args)
|
||||
ops.stage_python_runtime_package(
|
||||
args.staging_dir,
|
||||
codex_version,
|
||||
normalize_codex_version(args.codex_version),
|
||||
args.package_archive.resolve(),
|
||||
args.platform_tag,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user