build: package prebuilt Codex entrypoints (#23586)

## Why

The package builder should describe the binaries it is actually
packaging, not require callers to restate release metadata out of band.
A caller-provided `--version` flag can drift from the workspace version,
but running the target entrypoint to discover its version breaks
cross-target packages when the produced binary cannot execute on the
build host.

This PR keeps package metadata tied to the repository source of truth by
reading `[workspace.package].version` from `codex-rs/Cargo.toml`. It
also prepares the package layout for `codex-app-server` packages: the
same package structure can now represent either the CLI entrypoint or
the app-server entrypoint while keeping shared sidecars such as `rg`,
`bwrap`, and Windows sandbox helpers in the existing package
directories.

## What changed

- Removes the `--version` CLI flag from
`scripts/build_codex_package.py`.
- Adds Cargo.toml version discovery for `codex-package.json.version` via
`codex-rs/Cargo.toml`.
- Adds `--entrypoint-bin` so callers can package a prebuilt entrypoint
instead of rebuilding it with Cargo.
- Makes `--variant` an explicit choice between `codex` and
`codex-app-server`, and uses it to select the cargo binary and packaged
`bin/` entrypoint name.
- Updates `scripts/codex_package/README.md` to document variants,
prebuilt entrypoints, and Cargo.toml version detection.

## Verification

- Compiled `scripts/build_codex_package.py` and
`scripts/codex_package/*.py` with `PYTHONDONTWRITEBYTECODE=1`.
- Ran `scripts/build_codex_package.py --help` and verified `--version`
is gone while `--variant` and `--entrypoint-bin` are present.
- Verified the package builder reads version `0.0.0` from
`codex-rs/Cargo.toml`.
- Built a fake cross-target `codex-app-server` package using a
non-executable `--entrypoint-bin`; verified metadata records version
`0.0.0`, variant `codex-app-server`, and `bin/codex-app-server` as the
entrypoint.
This commit is contained in:
Michael Bolin
2026-05-19 22:10:03 -07:00
committed by GitHub
Unverified
parent dc255b0d8a
commit 343a74076f
6 changed files with 147 additions and 43 deletions
+37 -18
View File
@@ -6,6 +6,7 @@ from dataclasses import dataclass
from pathlib import Path
from .targets import REPO_ROOT
from .targets import PackageVariant
from .targets import TargetSpec
@@ -14,7 +15,7 @@ CODEX_RS_ROOT = REPO_ROOT / "codex-rs"
@dataclass(frozen=True)
class SourceBuildOutputs:
codex_bin: Path
entrypoint_bin: Path
bwrap_bin: Path | None
codex_command_runner_bin: Path | None
codex_windows_sandbox_setup_bin: Path | None
@@ -22,28 +23,39 @@ class SourceBuildOutputs:
def build_source_binaries(
spec: TargetSpec,
variant: PackageVariant,
*,
cargo: str,
profile: str,
entrypoint_bin: Path | None,
) -> SourceBuildOutputs:
binaries = source_binaries_for_target(spec)
cmd = [
cargo,
"build",
"--target",
spec.target,
"--profile",
profile,
]
for binary in binaries:
cmd.extend(["--bin", binary])
binaries = source_binaries_for_target(
spec,
variant,
build_entrypoint=entrypoint_bin is None,
)
if binaries:
cmd = [
cargo,
"build",
"--target",
spec.target,
"--profile",
profile,
]
for binary in binaries:
cmd.extend(["--bin", binary])
print("+", " ".join(cmd))
subprocess.run(cmd, cwd=CODEX_RS_ROOT, check=True)
print("+", " ".join(cmd))
subprocess.run(cmd, cwd=CODEX_RS_ROOT, check=True)
output_dir = cargo_profile_output_dir(spec, profile)
outputs = SourceBuildOutputs(
codex_bin=output_dir / spec.codex_name,
entrypoint_bin=(
entrypoint_bin.resolve()
if entrypoint_bin is not None
else output_dir / variant.entrypoint_name(spec)
),
bwrap_bin=output_dir / "bwrap" if spec.is_linux else None,
codex_command_runner_bin=(
output_dir / "codex-command-runner.exe" if spec.is_windows else None
@@ -56,8 +68,15 @@ def build_source_binaries(
return outputs
def source_binaries_for_target(spec: TargetSpec) -> list[str]:
binaries = ["codex"]
def source_binaries_for_target(
spec: TargetSpec,
variant: PackageVariant,
*,
build_entrypoint: bool,
) -> list[str]:
binaries = []
if build_entrypoint:
binaries.append(variant.cargo_bin)
if spec.is_linux:
binaries.append("bwrap")
if spec.is_windows:
@@ -97,7 +116,7 @@ def cargo_profile_dirname(profile: str) -> str:
def validate_source_outputs(outputs: SourceBuildOutputs) -> None:
for path in [
outputs.codex_bin,
outputs.entrypoint_bin,
outputs.bwrap_bin,
outputs.codex_command_runner_bin,
outputs.codex_windows_sandbox_setup_bin,