Skip to content

build: add Codex package builder#23513

Merged
bolinfest merged 1 commit into
mainfrom
pr23513
May 19, 2026
Merged

build: add Codex package builder#23513
bolinfest merged 1 commit into
mainfrom
pr23513

Conversation

@bolinfest
Copy link
Copy Markdown
Collaborator

@bolinfest bolinfest commented May 19, 2026

Why

Codex CLI packaging is currently split across npm staging, standalone installers, and release bundle creation, which makes it hard to define and validate a single valid package directory. This adds the first standalone package builder so later release paths can converge on the same canonical layout.

What changed

  • Added scripts/build_codex_package.py as the stable executable wrapper around scripts/codex_package.
  • Added modules for CLI parsing, target metadata, grouped cargo builds, package layout validation, and archive writing.
  • The builder creates a package directory with codex-package.json, bin/, codex-resources/, and codex-path, and can serialize it as .tar.gz, .tar.zst, or .zip.
  • Source-built artifacts are built by one grouped cargo build: codex for all targets, bwrap for Linux, and the Windows sandbox helpers for Windows. rg remains an input because it is vendored from upstream rather than built from this repo.
  • Added scripts/codex_package/README.md to document the package layout, source-built artifacts, and cargo profile behavior.

Verification

  • Ran wrapper/module syntax compilation.
  • Ran scripts/build_codex_package.py --help from /private/tmp.
  • Ran fake-cargo package/archive builds for macOS, Linux, and Windows target layouts, including an assertion that generated tar archives contain no duplicate member names.

Stack created with Sapling. Best reviewed with ReviewStack.

@bolinfest bolinfest requested a review from viyatb-oai May 19, 2026 18:01
@bolinfest bolinfest marked this pull request as ready for review May 19, 2026 18:01
Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 76db498c66

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/codex_package/archive.py Outdated
@bolinfest
Copy link
Copy Markdown
Collaborator Author

Addressed the P2 about duplicate tar members.

write_tar_archive() now passes recursive=False to tarfile.add(), so directory entries are added without recursively re-adding files that package_entries() already emits. I also reran the fake-cargo package/archive verification with an assertion that generated tar archives contain no duplicate member names.

Copy link
Copy Markdown
Collaborator

@viyatb-oai viyatb-oai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall. I left two P2 follow-ups that seem worth tightening before this builder becomes a shared release path.

print("+", " ".join(cmd))
subprocess.run(cmd, cwd=CODEX_RS_ROOT, check=True)

output_dir = cargo_profile_output_dir(spec, profile)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Honor CARGO_TARGET_DIR when locating the freshly built artifacts

This cargo build can legitimately write outside codex-rs/target when the caller sets CARGO_TARGET_DIR, but the lookup below always reconstructs CODEX_RS_ROOT / "target" / .... In that setup the build succeeds and the packager then fails with cargo build did not produce expected binary, even though Cargo did produce it. The repo already has other tooling that preserves this override, so I think this builder should do the same.

Suggested change
output_dir = cargo_profile_output_dir(spec, profile)
output_dir = cargo_profile_output_dir(spec, profile)

with cargo_profile_output_dir() resolving from CARGO_TARGET_DIR when it is set, and falling back to CODEX_RS_ROOT / "target" otherwise.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 164fbc8. cargo_profile_output_dir() now resolves from CARGO_TARGET_DIR when it is set, using absolute paths as-is and interpreting relative paths from codex-rs, then falls back to codex-rs/target. I also verified this with a fake-Cargo package build.

) -> Path:
if explicit_path is not None:
path = explicit_path.resolve()
if not path.is_file():
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Reject a non-executable --rg-bin instead of packaging it as valid

Right now --rg-bin only has to be a regular file. On Unix, copy_executable() then adds execute bits to the copy, and validate_package_dir() only checks that the destination is executable afterward. That means something like --rg-bin README.md can still produce a package that passes validation even though the shipped rg payload is unusable.

Suggested change
if not path.is_file():
if not path.is_file():
raise RuntimeError(f"{description} does not exist: {path}")
if not path.stat().st_mode & 0o111:
raise RuntimeError(f"{description} is not executable: {path}")

That keeps the package validation tied to the input artifact rather than making any regular file look executable during copying.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 164fbc8. Explicit --rg-bin inputs now have to be regular executable files before package assembly; otherwise the builder fails with a ripgrep executable is not executable error. I verified this with a non-executable override in the fake-Cargo package check.

@bolinfest bolinfest enabled auto-merge (squash) May 19, 2026 19:52
@bolinfest bolinfest merged commit 7f4d7ae into main May 19, 2026
47 of 62 checks passed
@bolinfest bolinfest deleted the pr23513 branch May 19, 2026 19:54
@github-actions github-actions Bot locked and limited conversation to collaborators May 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants