mirror of
https://github.com/openai/codex.git
synced 2026-10-29 19:08:43 +00:00
Ship the standalone executor in release packages (#57837)
## What changed - Include `codex-exec-server` in canonical CLI and app-server packages and advertise its path through `execServer` in `codex-package.json`. - Build and sign the executor in release workflows, preserve signed prebuilt inputs, and verify packaged signatures. Use empty entitlements for the macOS executor. - Have installers check for the executor when package metadata advertises it, while continuing to accept older packages. - Omit the standalone executor and its manifest entry from npm packages to stay within npm's package size limit. Keep `codex exec-server` and its runtime helpers available. ## Testing Add package smoke tests for executor initialization, version reporting, filesystem and process sandbox enforcement, and invalid-argument/configuration parity with `codex exec-server`. Extend archive, npm staging, and macOS signing tests to cover executor contents, executable permissions, preserved bytes, and entitlement verification. GitOrigin-RevId: bc741fe7faa6fe631d076de18d448c55247c23c7
This commit is contained in:
committed by
copyberry
parent
d359945843
commit
b91f2515f5
@@ -136,6 +136,8 @@ case "$target" in
|
||||
;;
|
||||
esac
|
||||
|
||||
resource_args+=(--exec-server-bin "${entrypoint_dir%/}/codex-exec-server${exe_suffix}")
|
||||
|
||||
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")
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict/>
|
||||
</plist>
|
||||
@@ -19,7 +19,7 @@ CODE_SIGNING_ID = "codex"
|
||||
APP = Path("CodexCLI.app")
|
||||
EXECUTABLE = APP / "Contents/MacOS/codex"
|
||||
SIGNING = Path(__file__).resolve().parent
|
||||
HELPERS = ("bin/codex-code-mode-host", "codex-path/rg")
|
||||
HELPERS = ("bin/codex-code-mode-host", "bin/codex-exec-server", "codex-path/rg")
|
||||
LAUNCHER = """#!/bin/sh
|
||||
set -eu
|
||||
entry="$0"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import plistlib
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
@@ -134,6 +135,12 @@ def main(configuration: bundle.ProfileConfiguration | None = None):
|
||||
check=True,
|
||||
)
|
||||
if relative.startswith("bin/"):
|
||||
# Signing tools may omit the blob when no entitlements are requested.
|
||||
if (
|
||||
actual.stat().st_size == 0
|
||||
and plistlib.loads(entitlements.read_bytes()) == {}
|
||||
):
|
||||
actual.write_bytes(entitlements.read_bytes())
|
||||
expected = reports / f"{name}-expected.plist"
|
||||
subprocess.run(
|
||||
[
|
||||
|
||||
@@ -34,10 +34,15 @@ if name == "codesign":
|
||||
target = Path(args[-1]).name
|
||||
if target == "CodexCLI.app":
|
||||
source = Path(os.environ["CODEX_REPO_ROOT"]) / "signing-verification/codex-provisioned-entitlements.plist"
|
||||
elif target in ("codex", "codex-code-mode-host"):
|
||||
elif target in ("codex", "codex-code-mode-host", "codex-exec-server"):
|
||||
source = Path(os.environ["MOCK_SIGNING_SCRIPTS"]) / (target + ".entitlements.plist")
|
||||
else:
|
||||
sys.exit(0)
|
||||
if target == "codex-exec-server" and os.environ.get("MOCK_EXECUTOR_ENTITLEMENTS"):
|
||||
sys.stdout.buffer.write(plistlib.dumps({"unexpected": True}))
|
||||
sys.exit(0)
|
||||
if not plistlib.loads(source.read_bytes()) and os.environ.get("MOCK_OMIT_EMPTY_ENTITLEMENTS"):
|
||||
sys.exit(0)
|
||||
if os.environ.get("MOCK_WRONG_ENTITLEMENTS"):
|
||||
sys.stdout.buffer.write(plistlib.dumps({"unexpected": True}))
|
||||
else:
|
||||
@@ -145,15 +150,21 @@ class MacosSigningTests(ProvisioningTestCase):
|
||||
)
|
||||
|
||||
def test_standard_and_provisioned_signing_and_verification(self):
|
||||
for provisioned, target in itertools.product(
|
||||
(False, True), ("aarch64-apple-darwin", "x86_64-apple-darwin")
|
||||
for provisioned, target, omit_empty in itertools.product(
|
||||
(False, True),
|
||||
("aarch64-apple-darwin", "x86_64-apple-darwin"),
|
||||
(False, True),
|
||||
):
|
||||
with (
|
||||
self.subTest(provisioned=provisioned, target=target),
|
||||
self.subTest(
|
||||
provisioned=provisioned, target=target, omit_empty=omit_empty
|
||||
),
|
||||
tempfile.TemporaryDirectory() as directory,
|
||||
):
|
||||
root = Path(directory).resolve()
|
||||
package, driver, env = self.fixture(root, provisioned, target)
|
||||
if omit_empty:
|
||||
env["MOCK_OMIT_EMPTY_ENTITLEMENTS"] = "1"
|
||||
result = self.run_driver(driver, "sign", package, env)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
result = self.run_driver(driver, "verify", package, env)
|
||||
@@ -189,13 +200,13 @@ class MacosSigningTests(ProvisioningTestCase):
|
||||
)
|
||||
self.assertEqual(
|
||||
["--entitlements" in call for call in signing],
|
||||
[True, True, False],
|
||||
[True, True, True, False],
|
||||
)
|
||||
self.assertEqual(
|
||||
[call[0] for call in calls if call[0].startswith("notarize")],
|
||||
["notarize_with_akv.py"]
|
||||
if provisioned
|
||||
else ["notarize_macos_binary_with_akv.sh"] * 3,
|
||||
else ["notarize_macos_binary_with_akv.sh"] * 4,
|
||||
)
|
||||
self.assertEqual(
|
||||
[call[1:] for call in calls if call[0] == "lipo"],
|
||||
@@ -318,7 +329,12 @@ class MacosSigningTests(ProvisioningTestCase):
|
||||
|
||||
def test_verification_rejects_wrong_signing_identity_and_entitlements(self):
|
||||
for provisioned, failure in itertools.product(
|
||||
(False, True), ("MOCK_WRONG_SIGNING_IDENTITY", "MOCK_WRONG_ENTITLEMENTS")
|
||||
(False, True),
|
||||
(
|
||||
"MOCK_WRONG_SIGNING_IDENTITY",
|
||||
"MOCK_WRONG_ENTITLEMENTS",
|
||||
"MOCK_EXECUTOR_ENTITLEMENTS",
|
||||
),
|
||||
):
|
||||
with (
|
||||
self.subTest(provisioned=provisioned, failure=failure),
|
||||
|
||||
Reference in New Issue
Block a user