mirror of
https://github.com/openai/codex.git
synced 2026-05-23 04:24:21 +00:00
## Why Release packaging should be a staging step once release binaries have already been built and signed. The Windows release job was downloading and signing `codex-command-runner.exe` and `codex-windows-sandbox-setup.exe`, but `scripts/build_codex_package.py` still rebuilt those helpers while creating the package archives. That makes the package step slower and, more importantly, risks putting helper binaries in the archive that were produced after the signing step. Linux had the same shape for package resources: `bwrap` could be rebuilt by the package builder instead of being passed in as a prebuilt release artifact. This builds on #23752, which fixes `.tar.zst` creation when Windows runners rely on the repository DotSlash `zstd` wrapper. ## What changed - Add explicit prebuilt resource inputs to the Codex package builder: - `--bwrap-bin` - `--codex-command-runner-bin` - `--codex-windows-sandbox-setup-bin` - Make `.github/scripts/build-codex-package-archive.sh` pass resource binaries from the release output directory when they are already present. - Build Linux `bwrap` for app-server release jobs too, so app-server package creation does not invoke Cargo just to supply the package resource. - Keep macOS package creation as a no-Cargo path when `--entrypoint-bin` is provided, since macOS packages have no resource binaries. - Add unit coverage showing prebuilt macOS, Linux, and Windows package inputs result in no source-built binaries. ## Verification - `python3 -m unittest discover -s scripts/codex_package -p 'test_*.py'` - `python3 -m py_compile scripts/codex_package/*.py` - `bash -n .github/scripts/build-codex-package-archive.sh` - Dry-ran Linux and Windows package builds with fake prebuilt resources and a nonexistent Cargo path to verify the package builder did not invoke Cargo. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/23759). * #23760 * __->__ #23759
170 lines
4.9 KiB
Python
170 lines
4.9 KiB
Python
"""Cargo builds for source-built Codex package artifacts."""
|
|
|
|
import os
|
|
import subprocess
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
|
|
from .targets import REPO_ROOT
|
|
from .targets import PackageVariant
|
|
from .targets import TargetSpec
|
|
|
|
|
|
CODEX_RS_ROOT = REPO_ROOT / "codex-rs"
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class SourceBuildOutputs:
|
|
entrypoint_bin: Path
|
|
bwrap_bin: Path | None
|
|
codex_command_runner_bin: Path | None
|
|
codex_windows_sandbox_setup_bin: Path | None
|
|
|
|
|
|
def build_source_binaries(
|
|
spec: TargetSpec,
|
|
variant: PackageVariant,
|
|
*,
|
|
cargo: str,
|
|
profile: str,
|
|
entrypoint_bin: Path | None,
|
|
bwrap_bin: Path | None,
|
|
codex_command_runner_bin: Path | None,
|
|
codex_windows_sandbox_setup_bin: Path | None,
|
|
) -> SourceBuildOutputs:
|
|
validate_prebuilt_resource_inputs(
|
|
spec,
|
|
bwrap_bin=bwrap_bin,
|
|
codex_command_runner_bin=codex_command_runner_bin,
|
|
codex_windows_sandbox_setup_bin=codex_windows_sandbox_setup_bin,
|
|
)
|
|
binaries = source_binaries_for_target(
|
|
spec,
|
|
variant,
|
|
build_entrypoint=entrypoint_bin is None,
|
|
build_bwrap=spec.is_linux and bwrap_bin is None,
|
|
build_codex_command_runner=spec.is_windows
|
|
and codex_command_runner_bin is None,
|
|
build_codex_windows_sandbox_setup=spec.is_windows
|
|
and codex_windows_sandbox_setup_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)
|
|
|
|
output_dir = cargo_profile_output_dir(spec, profile)
|
|
outputs = SourceBuildOutputs(
|
|
entrypoint_bin=resolve_output_path(
|
|
entrypoint_bin,
|
|
output_dir / variant.entrypoint_name(spec),
|
|
),
|
|
bwrap_bin=resolve_output_path(
|
|
bwrap_bin,
|
|
output_dir / "bwrap" if spec.is_linux else None,
|
|
),
|
|
codex_command_runner_bin=resolve_output_path(
|
|
codex_command_runner_bin,
|
|
output_dir / "codex-command-runner.exe" if spec.is_windows else None,
|
|
),
|
|
codex_windows_sandbox_setup_bin=resolve_output_path(
|
|
codex_windows_sandbox_setup_bin,
|
|
output_dir / "codex-windows-sandbox-setup.exe" if spec.is_windows else None,
|
|
),
|
|
)
|
|
validate_source_outputs(outputs)
|
|
return outputs
|
|
|
|
|
|
def source_binaries_for_target(
|
|
spec: TargetSpec,
|
|
variant: PackageVariant,
|
|
*,
|
|
build_entrypoint: bool,
|
|
build_bwrap: bool,
|
|
build_codex_command_runner: bool,
|
|
build_codex_windows_sandbox_setup: bool,
|
|
) -> list[str]:
|
|
binaries = []
|
|
if build_entrypoint:
|
|
binaries.append(variant.cargo_bin)
|
|
if build_bwrap:
|
|
binaries.append("bwrap")
|
|
if build_codex_command_runner:
|
|
binaries.append("codex-command-runner")
|
|
if build_codex_windows_sandbox_setup:
|
|
binaries.append("codex-windows-sandbox-setup")
|
|
return binaries
|
|
|
|
|
|
def validate_prebuilt_resource_inputs(
|
|
spec: TargetSpec,
|
|
*,
|
|
bwrap_bin: Path | None,
|
|
codex_command_runner_bin: Path | None,
|
|
codex_windows_sandbox_setup_bin: Path | None,
|
|
) -> None:
|
|
if bwrap_bin is not None and not spec.is_linux:
|
|
raise RuntimeError("--bwrap-bin is only supported for Linux targets.")
|
|
if codex_command_runner_bin is not None and not spec.is_windows:
|
|
raise RuntimeError(
|
|
"--codex-command-runner-bin is only supported for Windows targets."
|
|
)
|
|
if codex_windows_sandbox_setup_bin is not None and not spec.is_windows:
|
|
raise RuntimeError(
|
|
"--codex-windows-sandbox-setup-bin is only supported for Windows targets."
|
|
)
|
|
|
|
|
|
def resolve_output_path(explicit_path: Path | None, default_path: Path | None) -> Path | None:
|
|
if explicit_path is not None:
|
|
return explicit_path.resolve()
|
|
|
|
return default_path
|
|
|
|
|
|
def cargo_profile_output_dir(spec: TargetSpec, profile: str) -> Path:
|
|
target_dir = cargo_target_dir()
|
|
return target_dir / spec.target / cargo_profile_dirname(profile)
|
|
|
|
|
|
def cargo_target_dir() -> Path:
|
|
target_dir = os.environ.get("CARGO_TARGET_DIR")
|
|
if target_dir is None:
|
|
return CODEX_RS_ROOT / "target"
|
|
|
|
path = Path(target_dir)
|
|
if path.is_absolute():
|
|
return path
|
|
|
|
return CODEX_RS_ROOT / path
|
|
|
|
|
|
def cargo_profile_dirname(profile: str) -> str:
|
|
if profile == "dev":
|
|
return "debug"
|
|
if profile == "release":
|
|
return "release"
|
|
return profile
|
|
|
|
|
|
def validate_source_outputs(outputs: SourceBuildOutputs) -> None:
|
|
for path in [
|
|
outputs.entrypoint_bin,
|
|
outputs.bwrap_bin,
|
|
outputs.codex_command_runner_bin,
|
|
outputs.codex_windows_sandbox_setup_bin,
|
|
]:
|
|
if path is not None and not path.is_file():
|
|
raise RuntimeError(f"cargo build did not produce expected binary: {path}")
|