mirror of
https://github.com/openai/codex.git
synced 2026-08-23 13:09:46 +00:00
Allow overriding Codex package versions (#39298)
## What changed - Add `--package-version` to set the version written to `codex-package.json`, while retaining the workspace package version as the default. - Reject values that are not runtime-compatible semantic versions, including overflowing numeric components and numeric prerelease identifiers with leading zeroes. - Document the new option. ## Testing - Add unit coverage for valid release, prerelease, and build versions, plus malformed and out-of-range values. GitOrigin-RevId: cee996a6721e3fac9bd88f0bc0302a7ec7d2b2fb
This commit is contained in:
committed by
copyberry
parent
87070a7792
commit
45528c5132
@@ -31,8 +31,9 @@ artifacts; pass a GNU Linux target explicitly for native glibc local builds. If
|
||||
prints its path after the package is built.
|
||||
|
||||
The `--variant` flag selects the package entrypoint. Supported variants are
|
||||
`codex` and `codex-app-server`. The `version` field in `codex-package.json` is
|
||||
read from `[workspace.package].version` in `codex-rs/Cargo.toml`.
|
||||
`codex` and `codex-app-server`. The `--package-version` flag sets the version in
|
||||
`codex-package.json`; it defaults to `[workspace.package].version` in
|
||||
`codex-rs/Cargo.toml`.
|
||||
|
||||
## Source-built artifacts
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""Command-line interface for building Codex package directories."""
|
||||
|
||||
import argparse
|
||||
import re
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
@@ -19,6 +20,30 @@ from .zsh import resolve_zsh_bin
|
||||
from .version import read_workspace_version
|
||||
|
||||
|
||||
# Release pipelines run this builder with system Python, so avoid new dependencies.
|
||||
SEMVER_PATTERN = re.compile(
|
||||
r"(?P<major>0|[1-9][0-9]*)\."
|
||||
r"(?P<minor>0|[1-9][0-9]*)\."
|
||||
r"(?P<patch>0|[1-9][0-9]*)"
|
||||
r"(?:-(?P<prerelease>[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?"
|
||||
r"(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?"
|
||||
)
|
||||
|
||||
|
||||
def parse_package_version(value: str) -> str:
|
||||
match = SEMVER_PATTERN.fullmatch(value)
|
||||
if match is not None:
|
||||
components = (match.group(name) for name in ("major", "minor", "patch"))
|
||||
prerelease = match.group("prerelease") or ""
|
||||
if all(int(component) <= 2**64 - 1 for component in components) and all(
|
||||
not (part.isdigit() and len(part) > 1 and part.startswith("0"))
|
||||
for part in prerelease.split(".")
|
||||
):
|
||||
return value
|
||||
|
||||
raise argparse.ArgumentTypeError(f"invalid semantic version: {value!r}")
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Build a canonical Codex package directory and optional archive.",
|
||||
@@ -39,6 +64,12 @@ def parse_args() -> argparse.Namespace:
|
||||
default="codex",
|
||||
help="Package variant to build.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--package-version",
|
||||
type=parse_package_version,
|
||||
default=read_workspace_version(),
|
||||
help="Semantic version to record in codex-package.json.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--package-dir",
|
||||
type=Path,
|
||||
@@ -183,7 +214,6 @@ def main() -> int:
|
||||
"--codex-windows-sandbox-setup-bin",
|
||||
),
|
||||
)
|
||||
version = read_workspace_version()
|
||||
inputs = PackageInputs(
|
||||
entrypoint_bin=source_outputs.entrypoint_bin,
|
||||
code_mode_host_bin=source_outputs.code_mode_host_bin,
|
||||
@@ -194,7 +224,7 @@ def main() -> int:
|
||||
codex_windows_sandbox_setup_bin=source_outputs.codex_windows_sandbox_setup_bin,
|
||||
)
|
||||
prepare_package_dir(package_dir, force=args.force)
|
||||
build_package_dir(package_dir, version, variant, spec, inputs)
|
||||
build_package_dir(package_dir, args.package_version, variant, spec, inputs)
|
||||
validate_package_dir(
|
||||
package_dir, variant, spec, include_zsh=inputs.zsh_bin is not None
|
||||
)
|
||||
|
||||
48
scripts/codex_package/test_cli.py
Normal file
48
scripts/codex_package/test_cli.py
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
||||
|
||||
from codex_package.cli import parse_package_version
|
||||
|
||||
|
||||
class PackageVersionTest(unittest.TestCase):
|
||||
def test_accepts_release_prerelease_and_build_versions(self) -> None:
|
||||
for version in (
|
||||
"0.0.0",
|
||||
"1.2.3",
|
||||
"0.0.0-internal.deadbeef",
|
||||
"1.2.3-alpha.1+build.01",
|
||||
"18446744073709551615.0.0",
|
||||
):
|
||||
with self.subTest(version=version):
|
||||
self.assertEqual(parse_package_version(version), version)
|
||||
|
||||
def test_rejects_versions_the_runtime_cannot_parse(self) -> None:
|
||||
for version in (
|
||||
"",
|
||||
"1",
|
||||
"1.2",
|
||||
"1.2.3.4",
|
||||
"v1.2.3",
|
||||
"01.2.3",
|
||||
"1.02.3",
|
||||
"1.2.03",
|
||||
"1.2.3-",
|
||||
"1.2.3-alpha..1",
|
||||
"1.2.3-01",
|
||||
"1.2.3+",
|
||||
"1.2.3+build..1",
|
||||
"18446744073709551616.0.0",
|
||||
):
|
||||
with self.subTest(version=version):
|
||||
with self.assertRaises(argparse.ArgumentTypeError):
|
||||
parse_package_version(version)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user