mirror of
https://github.com/openai/codex.git
synced 2026-08-23 13:09:46 +00:00
[codex] bundle code mode host in release packages (#30202)
## Summary - build, strip, sign, and publish `codex-code-mode-host` with the primary Codex release binaries on Linux, macOS, and Windows - place the host beside `codex[.exe]` in canonical package archives, macOS DMGs, and the legacy Linux bundle so the runtime's sibling lookup succeeds - preserve and validate the host through standalone installers and Python runtime wheel staging - add package-builder coverage for source selection and the resulting package layout ## Why The process-owned code-mode client launches `codex-code-mode-host` as a sibling of the running Codex executable. Release artifacts currently build and bundle `codex` without that host, so code mode cannot start from installed packages.
This commit is contained in:
12
.github/scripts/build-codex-package-archive.sh
vendored
12
.github/scripts/build-codex-package-archive.sh
vendored
@@ -9,6 +9,7 @@ Usage: build-codex-package-archive.sh \
|
||||
--entrypoint-dir <dir> \
|
||||
--archive-dir <dir> \
|
||||
[--bwrap-bin <path>] \
|
||||
[--code-mode-host-bin <path>] \
|
||||
[--zsh-manifest <path>] \
|
||||
[--codex-command-runner-bin <path>] \
|
||||
[--codex-windows-sandbox-setup-bin <path>] \
|
||||
@@ -23,6 +24,7 @@ archive_dir=""
|
||||
target_suffixed_entrypoint="false"
|
||||
resource_args=()
|
||||
bwrap_bin_provided="false"
|
||||
code_mode_host_bin_provided="false"
|
||||
command_runner_bin_provided="false"
|
||||
sandbox_setup_bin_provided="false"
|
||||
|
||||
@@ -49,6 +51,11 @@ while [[ $# -gt 0 ]]; do
|
||||
bwrap_bin_provided="true"
|
||||
shift 2
|
||||
;;
|
||||
--code-mode-host-bin)
|
||||
resource_args+=(--code-mode-host-bin "${2:?--code-mode-host-bin requires a value}")
|
||||
code_mode_host_bin_provided="true"
|
||||
shift 2
|
||||
;;
|
||||
--zsh-manifest)
|
||||
resource_args+=(--zsh-manifest "${2:?--zsh-manifest requires a value}")
|
||||
shift 2
|
||||
@@ -114,6 +121,11 @@ case "$target" in
|
||||
;;
|
||||
esac
|
||||
|
||||
code_mode_host_bin="${entrypoint_dir%/}/codex-code-mode-host${exe_suffix}"
|
||||
if [[ "$code_mode_host_bin_provided" == "false" && -f "$code_mode_host_bin" ]]; then
|
||||
resource_args+=(--code-mode-host-bin "$code_mode_host_bin")
|
||||
fi
|
||||
|
||||
entrypoint_name="$entrypoint"
|
||||
if [[ "$target_suffixed_entrypoint" == "true" ]]; then
|
||||
entrypoint_name="${entrypoint_name}-${target}"
|
||||
|
||||
10
.github/workflows/rust-release-windows.yml
vendored
10
.github/workflows/rust-release-windows.yml
vendored
@@ -7,7 +7,7 @@ on:
|
||||
# nested submodules. Prefer the system git CLI across every Cargo invocation.
|
||||
env:
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
|
||||
WINDOWS_BINARIES: "codex codex-responses-api-proxy codex-windows-sandbox-setup codex-command-runner codex-app-server"
|
||||
WINDOWS_BINARIES: "codex codex-code-mode-host codex-responses-api-proxy codex-windows-sandbox-setup codex-command-runner codex-app-server"
|
||||
|
||||
jobs:
|
||||
build-windows-binaries:
|
||||
@@ -28,14 +28,14 @@ jobs:
|
||||
- runner: windows-x64
|
||||
target: x86_64-pc-windows-msvc
|
||||
bundle: primary
|
||||
binaries: "codex codex-responses-api-proxy"
|
||||
binaries: "codex codex-code-mode-host codex-responses-api-proxy"
|
||||
runs_on:
|
||||
group: ${{ github.event.repository.name }}-runners
|
||||
labels: ${{ github.event.repository.name }}-windows-x64
|
||||
- runner: windows-arm64
|
||||
target: aarch64-pc-windows-msvc
|
||||
bundle: primary
|
||||
binaries: "codex codex-responses-api-proxy"
|
||||
binaries: "codex codex-code-mode-host codex-responses-api-proxy"
|
||||
runs_on:
|
||||
group: ${{ github.event.repository.name }}-runners
|
||||
labels: ${{ github.event.repository.name }}-windows-arm64
|
||||
@@ -56,14 +56,14 @@ jobs:
|
||||
- runner: windows-x64
|
||||
target: x86_64-pc-windows-msvc
|
||||
bundle: app-server
|
||||
binaries: "codex-app-server"
|
||||
binaries: "codex-app-server codex-code-mode-host"
|
||||
runs_on:
|
||||
group: ${{ github.event.repository.name }}-runners
|
||||
labels: ${{ github.event.repository.name }}-windows-x64
|
||||
- runner: windows-arm64
|
||||
target: aarch64-pc-windows-msvc
|
||||
bundle: app-server
|
||||
binaries: "codex-app-server"
|
||||
binaries: "codex-app-server codex-code-mode-host"
|
||||
runs_on:
|
||||
group: ${{ github.event.repository.name }}-runners
|
||||
labels: ${{ github.event.repository.name }}-windows-arm64
|
||||
|
||||
65
.github/workflows/rust-release.yml
vendored
65
.github/workflows/rust-release.yml
vendored
@@ -83,50 +83,50 @@ jobs:
|
||||
target: aarch64-apple-darwin
|
||||
bundle: primary
|
||||
artifact_name: aarch64-apple-darwin
|
||||
binaries: "codex codex-responses-api-proxy"
|
||||
binaries: "codex codex-code-mode-host codex-responses-api-proxy"
|
||||
build_dmg: "true"
|
||||
- runner: macos-15-xlarge
|
||||
target: aarch64-apple-darwin
|
||||
bundle: app-server
|
||||
artifact_name: aarch64-apple-darwin-app-server
|
||||
binaries: "codex-app-server"
|
||||
binaries: "codex-app-server codex-code-mode-host"
|
||||
build_dmg: "false"
|
||||
- runner: macos-15-xlarge
|
||||
target: x86_64-apple-darwin
|
||||
bundle: primary
|
||||
artifact_name: x86_64-apple-darwin
|
||||
binaries: "codex codex-responses-api-proxy"
|
||||
binaries: "codex codex-code-mode-host codex-responses-api-proxy"
|
||||
build_dmg: "true"
|
||||
- runner: macos-15-xlarge
|
||||
target: x86_64-apple-darwin
|
||||
bundle: app-server
|
||||
artifact_name: x86_64-apple-darwin-app-server
|
||||
binaries: "codex-app-server"
|
||||
binaries: "codex-app-server codex-code-mode-host"
|
||||
build_dmg: "false"
|
||||
# Release artifacts intentionally ship MUSL-linked Linux binaries.
|
||||
- runner: ${{ github.event.repository.name }}-linux-x64-xl
|
||||
target: x86_64-unknown-linux-musl
|
||||
bundle: primary
|
||||
artifact_name: x86_64-unknown-linux-musl
|
||||
binaries: "codex codex-responses-api-proxy bwrap"
|
||||
binaries: "codex codex-code-mode-host codex-responses-api-proxy bwrap"
|
||||
build_dmg: "false"
|
||||
- runner: ${{ github.event.repository.name }}-linux-x64-xl
|
||||
target: x86_64-unknown-linux-musl
|
||||
bundle: app-server
|
||||
artifact_name: x86_64-unknown-linux-musl-app-server
|
||||
binaries: "codex-app-server"
|
||||
binaries: "codex-app-server codex-code-mode-host"
|
||||
build_dmg: "false"
|
||||
- runner: ${{ github.event.repository.name }}-linux-arm64
|
||||
target: aarch64-unknown-linux-musl
|
||||
bundle: primary
|
||||
artifact_name: aarch64-unknown-linux-musl
|
||||
binaries: "codex codex-responses-api-proxy bwrap"
|
||||
binaries: "codex codex-code-mode-host codex-responses-api-proxy bwrap"
|
||||
build_dmg: "false"
|
||||
- runner: ${{ github.event.repository.name }}-linux-arm64
|
||||
target: aarch64-unknown-linux-musl
|
||||
bundle: app-server
|
||||
artifact_name: aarch64-unknown-linux-musl-app-server
|
||||
binaries: "codex-app-server"
|
||||
binaries: "codex-app-server codex-code-mode-host"
|
||||
build_dmg: "false"
|
||||
|
||||
steps:
|
||||
@@ -335,6 +335,11 @@ jobs:
|
||||
mkdir -p "$dest"
|
||||
|
||||
for binary in ${{ matrix.binaries }}; do
|
||||
# Both variants package the host, but only the primary bundle publishes
|
||||
# standalone binary archives to avoid duplicate release asset names.
|
||||
if [[ "${{ matrix.bundle }}" == "app-server" && "$binary" == "codex-code-mode-host" ]]; then
|
||||
continue
|
||||
fi
|
||||
cp "target/${{ matrix.target }}/release/${binary}" "$dest/${binary}-${{ matrix.target }}"
|
||||
if [[ "${{ matrix.target }}" == *linux* ]]; then
|
||||
cp "target/${{ matrix.target }}/release/${binary}.sigstore" \
|
||||
@@ -347,9 +352,13 @@ jobs:
|
||||
rm -rf "$bundle_root"
|
||||
mkdir -p "$bundle_root/codex-resources"
|
||||
cp "$dest/codex-${{ matrix.target }}" "$bundle_root/codex"
|
||||
cp "$dest/codex-code-mode-host-${{ matrix.target }}" "$bundle_root/codex-code-mode-host"
|
||||
cp "$dest/bwrap-${{ matrix.target }}" "$bundle_root/codex-resources/bwrap"
|
||||
chmod 0755 "$bundle_root/codex" "$bundle_root/codex-resources/bwrap"
|
||||
tar -C "$bundle_root" -cf - codex codex-resources/bwrap |
|
||||
chmod 0755 \
|
||||
"$bundle_root/codex" \
|
||||
"$bundle_root/codex-code-mode-host" \
|
||||
"$bundle_root/codex-resources/bwrap"
|
||||
tar -C "$bundle_root" -cf - codex codex-code-mode-host codex-resources/bwrap |
|
||||
zstd -T0 -19 -o "$dest/codex-${{ matrix.target }}-bundle.tar.zst"
|
||||
fi
|
||||
|
||||
@@ -497,19 +506,19 @@ jobs:
|
||||
- target: aarch64-apple-darwin
|
||||
bundle: primary
|
||||
artifact_name: aarch64-apple-darwin
|
||||
binaries: "codex codex-responses-api-proxy"
|
||||
binaries: "codex codex-code-mode-host codex-responses-api-proxy"
|
||||
- target: aarch64-apple-darwin
|
||||
bundle: app-server
|
||||
artifact_name: aarch64-apple-darwin-app-server
|
||||
binaries: "codex-app-server"
|
||||
binaries: "codex-app-server codex-code-mode-host"
|
||||
- target: x86_64-apple-darwin
|
||||
bundle: primary
|
||||
artifact_name: x86_64-apple-darwin
|
||||
binaries: "codex codex-responses-api-proxy"
|
||||
binaries: "codex codex-code-mode-host codex-responses-api-proxy"
|
||||
- target: x86_64-apple-darwin
|
||||
bundle: app-server
|
||||
artifact_name: x86_64-apple-darwin-app-server
|
||||
binaries: "codex-app-server"
|
||||
binaries: "codex-app-server codex-code-mode-host"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
@@ -615,22 +624,22 @@ jobs:
|
||||
- target: aarch64-apple-darwin
|
||||
bundle: primary
|
||||
artifact_name: aarch64-apple-darwin
|
||||
binaries: "codex codex-responses-api-proxy"
|
||||
binaries: "codex codex-code-mode-host codex-responses-api-proxy"
|
||||
build_dmg: "true"
|
||||
- target: aarch64-apple-darwin
|
||||
bundle: app-server
|
||||
artifact_name: aarch64-apple-darwin-app-server
|
||||
binaries: "codex-app-server"
|
||||
binaries: "codex-app-server codex-code-mode-host"
|
||||
build_dmg: "false"
|
||||
- target: x86_64-apple-darwin
|
||||
bundle: primary
|
||||
artifact_name: x86_64-apple-darwin
|
||||
binaries: "codex codex-responses-api-proxy"
|
||||
binaries: "codex codex-code-mode-host codex-responses-api-proxy"
|
||||
build_dmg: "true"
|
||||
- target: x86_64-apple-darwin
|
||||
bundle: app-server
|
||||
artifact_name: x86_64-apple-darwin-app-server
|
||||
binaries: "codex-app-server"
|
||||
binaries: "codex-app-server codex-code-mode-host"
|
||||
build_dmg: "false"
|
||||
|
||||
steps:
|
||||
@@ -707,6 +716,11 @@ jobs:
|
||||
mkdir -p "$dest"
|
||||
|
||||
for binary in ${{ matrix.binaries }}; do
|
||||
# Both variants package the host, but only the primary bundle publishes
|
||||
# standalone binary archives to avoid duplicate release asset names.
|
||||
if [[ "${{ matrix.bundle }}" == "app-server" && "$binary" == "codex-code-mode-host" ]]; then
|
||||
continue
|
||||
fi
|
||||
cp "target/${{ matrix.target }}/release/${binary}" "$dest/${binary}-${{ matrix.target }}"
|
||||
done
|
||||
|
||||
@@ -911,22 +925,22 @@ jobs:
|
||||
- target: aarch64-apple-darwin
|
||||
bundle: primary
|
||||
artifact_name: aarch64-apple-darwin
|
||||
binaries: "codex codex-responses-api-proxy"
|
||||
binaries: "codex codex-code-mode-host codex-responses-api-proxy"
|
||||
verify_dmg: "true"
|
||||
- target: aarch64-apple-darwin
|
||||
bundle: app-server
|
||||
artifact_name: aarch64-apple-darwin-app-server
|
||||
binaries: "codex-app-server"
|
||||
binaries: "codex-app-server codex-code-mode-host"
|
||||
verify_dmg: "false"
|
||||
- target: x86_64-apple-darwin
|
||||
bundle: primary
|
||||
artifact_name: x86_64-apple-darwin
|
||||
binaries: "codex codex-responses-api-proxy"
|
||||
binaries: "codex codex-code-mode-host codex-responses-api-proxy"
|
||||
verify_dmg: "true"
|
||||
- target: x86_64-apple-darwin
|
||||
bundle: app-server
|
||||
artifact_name: x86_64-apple-darwin-app-server
|
||||
binaries: "codex-app-server"
|
||||
binaries: "codex-app-server codex-code-mode-host"
|
||||
verify_dmg: "false"
|
||||
|
||||
steps:
|
||||
@@ -983,6 +997,12 @@ jobs:
|
||||
binary_path="${RUNNER_TEMP}/signed-binaries/${binary}"
|
||||
verify_signed_binary "$binary_path"
|
||||
|
||||
# The app-server package contains the host, but its standalone archives
|
||||
# are omitted above to avoid duplicate release asset names.
|
||||
if [[ "${{ matrix.bundle }}" == "app-server" && "$binary" == "codex-code-mode-host" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
direct_archive_dir="${RUNNER_TEMP}/direct-archive-${binary}-${target}"
|
||||
rm -rf "$direct_archive_dir"
|
||||
mkdir -p "$direct_archive_dir"
|
||||
@@ -1014,6 +1034,7 @@ jobs:
|
||||
mkdir -p "$package_dir"
|
||||
tar -xzf "${packaged_dir}/${package_stem}-${target}.tar.gz" -C "$package_dir"
|
||||
verify_signed_binary "${package_dir}/bin/${package_entrypoint}"
|
||||
verify_signed_binary "${package_dir}/bin/codex-code-mode-host"
|
||||
|
||||
if [[ "${{ matrix.verify_dmg }}" != "true" ]]; then
|
||||
exit 0
|
||||
|
||||
@@ -10,7 +10,8 @@ The builder creates a canonical Codex package directory:
|
||||
.
|
||||
├── codex-package.json
|
||||
├── bin
|
||||
│ └── <entrypoint>[.exe]
|
||||
│ ├── <entrypoint>[.exe]
|
||||
│ └── codex-code-mode-host[.exe]
|
||||
├── codex-resources
|
||||
│ ├── bwrap # Linux only
|
||||
│ ├── zsh/bin/zsh # supported Unix targets only
|
||||
@@ -40,6 +41,7 @@ grouped `cargo build` command per package when they are needed and no prebuilt
|
||||
override was provided:
|
||||
|
||||
- all targets: the selected entrypoint, unless `--entrypoint-bin` is provided
|
||||
- all targets: `codex-code-mode-host`, unless `--code-mode-host-bin` is provided
|
||||
- Linux targets: `bwrap`, unless `--bwrap-bin` is provided
|
||||
- Windows targets: `codex-command-runner` and `codex-windows-sandbox-setup`,
|
||||
unless the corresponding prebuilt helper flags are provided
|
||||
@@ -50,6 +52,9 @@ explicit target. Release jobs that already built and signed/notarized the
|
||||
entrypoint should pass `--entrypoint-bin` so the package contains that exact
|
||||
binary instead of rebuilding it.
|
||||
|
||||
Release jobs should likewise pass `--code-mode-host-bin` so the package contains
|
||||
the signed host executable beside the signed entrypoint.
|
||||
|
||||
Release jobs that already built package resource binaries should also pass the
|
||||
corresponding resource flags: `--bwrap-bin` for Linux packages, and
|
||||
`--codex-command-runner-bin` plus `--codex-windows-sandbox-setup-bin` for
|
||||
|
||||
@@ -17,6 +17,7 @@ CODEX_RS_ROOT = REPO_ROOT / "codex-rs"
|
||||
@dataclass(frozen=True)
|
||||
class SourceBuildOutputs:
|
||||
entrypoint_bin: Path
|
||||
code_mode_host_bin: Path
|
||||
bwrap_bin: Path | None
|
||||
codex_command_runner_bin: Path | None
|
||||
codex_windows_sandbox_setup_bin: Path | None
|
||||
@@ -29,6 +30,7 @@ def build_source_binaries(
|
||||
cargo: str,
|
||||
profile: str,
|
||||
entrypoint_bin: Path | None,
|
||||
code_mode_host_bin: Path | None,
|
||||
bwrap_bin: Path | None,
|
||||
codex_command_runner_bin: Path | None,
|
||||
codex_windows_sandbox_setup_bin: Path | None,
|
||||
@@ -43,6 +45,7 @@ def build_source_binaries(
|
||||
spec,
|
||||
variant,
|
||||
build_entrypoint=entrypoint_bin is None,
|
||||
build_code_mode_host=code_mode_host_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
|
||||
@@ -61,7 +64,7 @@ def build_source_binaries(
|
||||
cmd.extend(["--bin", binary])
|
||||
|
||||
cargo_env = None
|
||||
if entrypoint_bin is None:
|
||||
if entrypoint_bin is None or code_mode_host_bin is None:
|
||||
codex_v8_env = resolve_codex_v8_cargo_env(spec)
|
||||
if codex_v8_env:
|
||||
cargo_env = {**os.environ, **codex_v8_env}
|
||||
@@ -80,6 +83,11 @@ def build_source_binaries(
|
||||
entrypoint_bin,
|
||||
output_dir / variant.entrypoint_name(spec),
|
||||
),
|
||||
code_mode_host_bin=(
|
||||
code_mode_host_bin.resolve()
|
||||
if code_mode_host_bin is not None
|
||||
else output_dir / f"codex-code-mode-host{spec.exe_suffix}"
|
||||
),
|
||||
bwrap_bin=resolve_output_path(
|
||||
bwrap_bin,
|
||||
output_dir / "bwrap" if spec.is_linux else None,
|
||||
@@ -102,6 +110,7 @@ def source_binaries_for_target(
|
||||
variant: PackageVariant,
|
||||
*,
|
||||
build_entrypoint: bool,
|
||||
build_code_mode_host: bool,
|
||||
build_bwrap: bool,
|
||||
build_codex_command_runner: bool,
|
||||
build_codex_windows_sandbox_setup: bool,
|
||||
@@ -109,6 +118,8 @@ def source_binaries_for_target(
|
||||
binaries = []
|
||||
if build_entrypoint:
|
||||
binaries.append(variant.cargo_bin)
|
||||
if build_code_mode_host:
|
||||
binaries.append("codex-code-mode-host")
|
||||
if build_bwrap:
|
||||
binaries.append("bwrap")
|
||||
if build_codex_command_runner:
|
||||
@@ -174,6 +185,7 @@ def cargo_profile_dirname(profile: str) -> str:
|
||||
def validate_source_outputs(outputs: SourceBuildOutputs) -> None:
|
||||
for path in [
|
||||
outputs.entrypoint_bin,
|
||||
outputs.code_mode_host_bin,
|
||||
outputs.bwrap_bin,
|
||||
outputs.codex_command_runner_bin,
|
||||
outputs.codex_windows_sandbox_setup_bin,
|
||||
|
||||
@@ -82,6 +82,14 @@ def parse_args() -> argparse.Namespace:
|
||||
"variant. If omitted, the entrypoint is built with Cargo."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--code-mode-host-bin",
|
||||
type=Path,
|
||||
help=(
|
||||
"Optional prebuilt codex-code-mode-host executable. If omitted, "
|
||||
"the host is built with Cargo."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--bwrap-bin",
|
||||
type=Path,
|
||||
@@ -148,6 +156,11 @@ def main() -> int:
|
||||
"prebuilt entrypoint executable",
|
||||
"--entrypoint-bin",
|
||||
),
|
||||
code_mode_host_bin=resolve_optional_input_path(
|
||||
args.code_mode_host_bin,
|
||||
"prebuilt code-mode host executable",
|
||||
"--code-mode-host-bin",
|
||||
),
|
||||
bwrap_bin=resolve_optional_input_path(
|
||||
args.bwrap_bin,
|
||||
"prebuilt Linux bwrap executable",
|
||||
@@ -167,6 +180,7 @@ def main() -> int:
|
||||
version = read_workspace_version()
|
||||
inputs = PackageInputs(
|
||||
entrypoint_bin=source_outputs.entrypoint_bin,
|
||||
code_mode_host_bin=source_outputs.code_mode_host_bin,
|
||||
rg_bin=resolve_rg_bin(spec, args.rg_bin),
|
||||
zsh_bin=resolve_zsh_bin(spec, args.zsh_manifest),
|
||||
bwrap_bin=source_outputs.bwrap_bin,
|
||||
|
||||
@@ -51,6 +51,11 @@ def build_package_dir(
|
||||
bin_dir / entrypoint_name,
|
||||
is_windows=spec.is_windows,
|
||||
)
|
||||
copy_executable(
|
||||
inputs.code_mode_host_bin,
|
||||
bin_dir / f"codex-code-mode-host{spec.exe_suffix}",
|
||||
is_windows=spec.is_windows,
|
||||
)
|
||||
copy_executable(inputs.rg_bin, path_dir / spec.rg_name, is_windows=spec.is_windows)
|
||||
|
||||
if inputs.zsh_bin is not None:
|
||||
@@ -130,6 +135,7 @@ def validate_package_dir(
|
||||
|
||||
required_files = [
|
||||
Path("bin") / variant.entrypoint_name(spec),
|
||||
Path("bin") / f"codex-code-mode-host{spec.exe_suffix}",
|
||||
Path("codex-path") / spec.rg_name,
|
||||
]
|
||||
executable_files = list(required_files)
|
||||
|
||||
@@ -39,6 +39,7 @@ class PackageVariant:
|
||||
@dataclass(frozen=True)
|
||||
class PackageInputs:
|
||||
entrypoint_bin: Path
|
||||
code_mode_host_bin: Path
|
||||
rg_bin: Path
|
||||
zsh_bin: Path | None
|
||||
bwrap_bin: Path | None
|
||||
|
||||
@@ -20,6 +20,7 @@ class SourceBinariesForTargetTest(unittest.TestCase):
|
||||
TARGET_SPECS["aarch64-apple-darwin"],
|
||||
PACKAGE_VARIANTS["codex"],
|
||||
build_entrypoint=False,
|
||||
build_code_mode_host=False,
|
||||
build_bwrap=False,
|
||||
build_codex_command_runner=False,
|
||||
build_codex_windows_sandbox_setup=False,
|
||||
@@ -35,6 +36,7 @@ class SourceBinariesForTargetTest(unittest.TestCase):
|
||||
TARGET_SPECS["x86_64-unknown-linux-musl"],
|
||||
PACKAGE_VARIANTS["codex"],
|
||||
build_entrypoint=False,
|
||||
build_code_mode_host=False,
|
||||
build_bwrap=False,
|
||||
build_codex_command_runner=False,
|
||||
build_codex_windows_sandbox_setup=False,
|
||||
@@ -50,6 +52,7 @@ class SourceBinariesForTargetTest(unittest.TestCase):
|
||||
TARGET_SPECS["x86_64-pc-windows-msvc"],
|
||||
PACKAGE_VARIANTS["codex"],
|
||||
build_entrypoint=False,
|
||||
build_code_mode_host=False,
|
||||
build_bwrap=False,
|
||||
build_codex_command_runner=False,
|
||||
build_codex_windows_sandbox_setup=False,
|
||||
@@ -63,6 +66,7 @@ class SourceBinariesForTargetTest(unittest.TestCase):
|
||||
TARGET_SPECS["x86_64-pc-windows-msvc"],
|
||||
PACKAGE_VARIANTS["codex"],
|
||||
build_entrypoint=False,
|
||||
build_code_mode_host=False,
|
||||
build_bwrap=False,
|
||||
build_codex_command_runner=True,
|
||||
build_codex_windows_sandbox_setup=True,
|
||||
@@ -70,10 +74,25 @@ class SourceBinariesForTargetTest(unittest.TestCase):
|
||||
["codex-command-runner", "codex-windows-sandbox-setup"],
|
||||
)
|
||||
|
||||
def test_missing_code_mode_host_is_built_for_app_server(self) -> None:
|
||||
self.assertEqual(
|
||||
source_binaries_for_target(
|
||||
TARGET_SPECS["aarch64-apple-darwin"],
|
||||
PACKAGE_VARIANTS["codex-app-server"],
|
||||
build_entrypoint=False,
|
||||
build_code_mode_host=True,
|
||||
build_bwrap=False,
|
||||
build_codex_command_runner=False,
|
||||
build_codex_windows_sandbox_setup=False,
|
||||
),
|
||||
["codex-code-mode-host"],
|
||||
)
|
||||
|
||||
def test_build_uses_prebuilt_windows_helpers_without_running_cargo(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
root = Path(temp_dir)
|
||||
entrypoint = touch_file(root / "codex.exe")
|
||||
code_mode_host = touch_file(root / "codex-code-mode-host.exe")
|
||||
command_runner = touch_file(root / "codex-command-runner.exe")
|
||||
sandbox_setup = touch_file(root / "codex-windows-sandbox-setup.exe")
|
||||
|
||||
@@ -83,12 +102,14 @@ class SourceBinariesForTargetTest(unittest.TestCase):
|
||||
cargo=str(root / "cargo-that-should-not-run"),
|
||||
profile="release",
|
||||
entrypoint_bin=entrypoint,
|
||||
code_mode_host_bin=code_mode_host,
|
||||
bwrap_bin=None,
|
||||
codex_command_runner_bin=command_runner,
|
||||
codex_windows_sandbox_setup_bin=sandbox_setup,
|
||||
)
|
||||
|
||||
self.assertEqual(outputs.entrypoint_bin, entrypoint)
|
||||
self.assertEqual(outputs.code_mode_host_bin, code_mode_host)
|
||||
self.assertEqual(outputs.codex_command_runner_bin, command_runner)
|
||||
self.assertEqual(outputs.codex_windows_sandbox_setup_bin, sandbox_setup)
|
||||
|
||||
|
||||
56
scripts/codex_package/test_layout.py
Normal file
56
scripts/codex_package/test_layout.py
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
||||
|
||||
from codex_package.layout import build_package_dir
|
||||
from codex_package.layout import validate_package_dir
|
||||
from codex_package.targets import PACKAGE_VARIANTS
|
||||
from codex_package.targets import PackageInputs
|
||||
from codex_package.targets import TARGET_SPECS
|
||||
|
||||
|
||||
class PackageLayoutTest(unittest.TestCase):
|
||||
def test_app_server_package_places_code_mode_host_beside_entrypoint(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
root = Path(temp_dir)
|
||||
package_dir = root / "package"
|
||||
package_dir.mkdir()
|
||||
inputs = PackageInputs(
|
||||
entrypoint_bin=touch_executable(root / "codex-app-server"),
|
||||
code_mode_host_bin=touch_executable(root / "codex-code-mode-host"),
|
||||
rg_bin=touch_executable(root / "rg"),
|
||||
zsh_bin=None,
|
||||
bwrap_bin=touch_executable(root / "bwrap"),
|
||||
codex_command_runner_bin=None,
|
||||
codex_windows_sandbox_setup_bin=None,
|
||||
)
|
||||
|
||||
build_package_dir(
|
||||
package_dir,
|
||||
"1.2.3",
|
||||
PACKAGE_VARIANTS["codex-app-server"],
|
||||
TARGET_SPECS["x86_64-unknown-linux-musl"],
|
||||
inputs,
|
||||
)
|
||||
validate_package_dir(
|
||||
package_dir,
|
||||
PACKAGE_VARIANTS["codex-app-server"],
|
||||
TARGET_SPECS["x86_64-unknown-linux-musl"],
|
||||
include_zsh=False,
|
||||
)
|
||||
|
||||
self.assertTrue((package_dir / "bin" / "codex-code-mode-host").is_file())
|
||||
|
||||
|
||||
def touch_executable(path: Path) -> Path:
|
||||
path.touch(mode=0o755)
|
||||
return path
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -538,6 +538,7 @@ function Test-PackageContentsAreComplete {
|
||||
$expectedFiles = @(
|
||||
"codex-package.json",
|
||||
"bin\codex.exe",
|
||||
"bin\codex-code-mode-host.exe",
|
||||
"codex-path\rg.exe",
|
||||
"codex-resources\codex-command-runner.exe",
|
||||
"codex-resources\codex-windows-sandbox-setup.exe"
|
||||
|
||||
@@ -680,7 +680,10 @@ install_package_release() {
|
||||
rm -rf "$stage_release"
|
||||
mkdir -p "$stage_release"
|
||||
tar -xzf "$archive_path" -C "$stage_release"
|
||||
chmod 0755 "$stage_release/bin/codex" "$stage_release/codex-path/rg"
|
||||
chmod 0755 \
|
||||
"$stage_release/bin/codex" \
|
||||
"$stage_release/bin/codex-code-mode-host" \
|
||||
"$stage_release/codex-path/rg"
|
||||
if [ -f "$stage_release/codex-resources/bwrap" ]; then
|
||||
chmod 0755 "$stage_release/codex-resources/bwrap"
|
||||
fi
|
||||
@@ -733,6 +736,7 @@ release_dir_is_complete() {
|
||||
package)
|
||||
[ -f "$release_dir/codex-package.json" ] &&
|
||||
[ -x "$release_dir/bin/codex" ] &&
|
||||
[ -x "$release_dir/bin/codex-code-mode-host" ] &&
|
||||
[ -x "$release_dir/codex" ] &&
|
||||
[ -x "$release_dir/codex-path/rg" ] ||
|
||||
return 1
|
||||
|
||||
@@ -53,6 +53,10 @@ def runtime_binary_name() -> str:
|
||||
return "codex.exe" if _is_windows() else "codex"
|
||||
|
||||
|
||||
def runtime_code_mode_host_name() -> str:
|
||||
return "codex-code-mode-host.exe" if _is_windows() else "codex-code-mode-host"
|
||||
|
||||
|
||||
def staged_runtime_package_root(root: Path) -> Path:
|
||||
return root / RUNTIME_PACKAGE_ROOT
|
||||
|
||||
@@ -276,6 +280,9 @@ def _validate_codex_package_layout(package_dir: Path, package_archive: Path) ->
|
||||
package_binary = package_dir / "bin" / runtime_binary_name()
|
||||
if not package_binary.is_file():
|
||||
missing_entries.append(str(Path("bin") / runtime_binary_name()))
|
||||
code_mode_host = package_dir / "bin" / runtime_code_mode_host_name()
|
||||
if not code_mode_host.is_file():
|
||||
missing_entries.append(str(Path("bin") / runtime_code_mode_host_name()))
|
||||
if missing_entries:
|
||||
missing = ", ".join(missing_entries)
|
||||
raise RuntimeError(f"Missing Codex package layout entries in {package_archive}: {missing}")
|
||||
|
||||
@@ -57,6 +57,7 @@ def _write_fake_codex_package(package_dir: Path, script) -> Path:
|
||||
(package_dir / "codex-path").mkdir()
|
||||
(package_dir / "codex-package.json").write_text('{"variant":"codex"}\n')
|
||||
(package_dir / "bin" / script.runtime_binary_name()).write_text("fake codex\n")
|
||||
(package_dir / "bin" / script.runtime_code_mode_host_name()).write_text("fake code mode host\n")
|
||||
(package_dir / "codex-resources" / "bwrap").write_text("fake bwrap\n")
|
||||
(package_dir / "codex-path" / "rg").write_text("fake rg\n")
|
||||
return package_dir
|
||||
@@ -682,11 +683,13 @@ def test_stage_runtime_release_copies_package_layout_and_sets_version(
|
||||
assert {
|
||||
"metadata": (package_root / "codex-package.json").read_text(),
|
||||
"codex": (package_root / "bin" / script.runtime_binary_name()).read_text(),
|
||||
"code_mode_host": (package_root / "bin" / script.runtime_code_mode_host_name()).read_text(),
|
||||
"bwrap": (package_root / "codex-resources" / "bwrap").read_text(),
|
||||
"rg": (package_root / "codex-path" / "rg").read_text(),
|
||||
} == {
|
||||
"metadata": '{"variant":"codex"}\n',
|
||||
"codex": "fake codex\n",
|
||||
"code_mode_host": "fake code mode host\n",
|
||||
"bwrap": "fake bwrap\n",
|
||||
"rg": "fake rg\n",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user