Commit Graph

144 Commits

  • Disable DMG staging for signed macOS promotion (#22900)
    ## Why
    `promote_signed` is now used to finish a release from an externally
    signed macOS handoff, but this release path (temporarily) no longer
    distributes DMGs. Keeping DMG staging enabled made the handoff
    unnecessarily require DMG assets and notarization/stapling validation
    even though the promoted release only needs the signed macOS binaries.
    
    ## What changed
    - Set every `stage-signed-macos` matrix entry to `build_dmg: "false"`,
    including the primary macOS bundles.
    - Kept the existing DMG staging branch in place behind
    `matrix.build_dmg` so it can be re-enabled deliberately later.
    - Updated the workflow header comment so the signed handoff contract
    asks for signed binaries, not signed DMGs.
    
    The regular signed build path that creates, signs, notarizes, and stages
    DMGs is unchanged; this only affects the `promote_signed` handoff path.
  • Fix signed macOS release promotion follow-up jobs (#22788)
    ## Why
    
    The `release_mode=promote_signed` path intentionally skips the build
    jobs after signed macOS artifacts are staged, then runs the `release`
    job from the signed handoff. In the `rust-v0.131.0-alpha.19` promotion
    run, `release` succeeded but the npm, PyPI, and `latest-alpha-cli`
    follow-up jobs were skipped because their custom job `if:` expressions
    let GitHub Actions apply the implicit `success()` status check before
    reading `needs.release.outputs.*`.
    
    The unsigned build handoff does not need DotSlash manifests. Publishing
    unsigned DotSlash manifests creates release assets that can conflict
    with the later signed promotion, especially shared outputs such as
    `bwrap`, `codex-command-runner`, and `codex-windows-sandbox-setup`.
    
    ## What Changed
    
    - Stop publishing DotSlash manifests when `SIGN_MACOS == 'false'`.
    - Delete `.github/dotslash-unsigned-config.json`.
    - Gate post-release jobs with the `!cancelled()` status function plus an
    explicit `needs.release.result == 'success'` check before consulting
    release outputs.
    - Keep the existing publish eligibility rules for npm, PyPI, WinGet, and
    `latest-alpha-cli`.
    
    ## Verification
    
    - `rg -n "dotslash-unsigned-config|SIGN_MACOS ==
    'false'.*dotslash|unsigned-config" .github/workflows/rust-release.yml
    .github || true`
    - `git diff --check -- .github/workflows/rust-release.yml
    .github/dotslash-unsigned-config.json`
  • ci: support signed macOS release promotion (#22737)
    ## Why
    
    `rust-release.yml` can create unsigned macOS artifacts for external
    signing, but there was no signed resume path after those artifacts
    returned from a secure enclave. Release operators need a way to reuse
    the first run artifacts, ingest signed macOS binaries and DMGs, and
    continue the normal signed release path without rebuilding every
    platform or treating handoff assets as final release assets.
    
    ## How this is meant to be used
    
    First, start the release as an unsigned macOS build against the release
    tag:
    
    ```shell
    gh workflow run rust-release.yml \
      --repo openai/codex \
      --ref rust-vX.Y.Z \
      -f release_mode=build_unsigned
    ```
    
    That run builds the normal Linux/Windows artifacts and publishes
    unsigned macOS handoff artifacts. The unsigned macOS binaries are then
    copied to the secure enclave, signed and notarized there, packaged as a
    signed handoff archive, and uploaded back to the GitHub Release for the
    same tag.
    
    The signed handoff asset should contain either target directories such
    as `aarch64-apple-darwin/` and `x86_64-apple-darwin/`, or artifact
    directories such as `aarch64-apple-darwin-app-server/`. The promote
    workflow accepts either layout. The directories should contain the
    signed binaries and, for primary macOS bundles, the signed and stapled
    DMGs.
    
    For example, after signing, upload the handoff asset to the release:
    
    ```shell
    gh release upload rust-vX.Y.Z \
      signed-macos-rust-vX.Y.Z.tar.zst \
      --repo openai/codex \
      --clobber
    ```
    
    Then start the promotion run. `unsigned_run_id` is the workflow run id
    from the first `build_unsigned` run, and `signed_macos_asset` is the
    exact Release asset name uploaded by the secure enclave:
    
    ```shell
    gh workflow run rust-release.yml \
      --repo openai/codex \
      --ref rust-vX.Y.Z \
      -f release_mode=promote_signed \
      -f unsigned_run_id=1234567890 \
      -f signed_macos_asset=signed-macos-rust-vX.Y.Z.tar.zst \
      -f signed_macos_sha256=<sha256>
    ```
    
    The `signed_macos_sha256` input is optional, but when provided the
    promotion run verifies the handoff archive before unpacking it. The
    promotion run also validates that `unsigned_run_id` points to a
    successful manual `rust-release` run for the same tag and commit before
    importing artifacts.
    
    ## What Changed
    
    - Add explicit manual `release_mode` values for `build_unsigned` and
    `promote_signed` while keeping `sign_macos` as a deprecated
    compatibility input.
    - Add promote inputs for `unsigned_run_id`, `signed_macos_asset`, and
    optional `signed_macos_sha256`.
    - Add a `stage-signed-macos` job that downloads the signed handoff asset
    from the GitHub Release, verifies signed binaries and stapled DMGs,
    repacks normal macOS release artifacts, and builds macOS Python runtime
    wheels.
    - Teach the release job to download Part 1 artifacts from the unsigned
    run, discard unsigned macOS staging artifacts, re-upload promoted Linux
    and Windows artifacts for npm staging, and then run the signed release
    tail.
    - Validate that `unsigned_run_id` points to a successful manual
    `rust-release` run for the same tag and commit before importing
    artifacts.
    - Limit unsigned macOS artifact upload to the unsigned build path so
    normal signed releases do not publish unsigned handoff binaries.
    - Clean up unsigned and signed handoff release assets after successful
    promotion.
    
    ## Verification
    
    - Parsed `.github/workflows/rust-release.yml` with Ruby YAML loading.
    
    No developers.openai.com documentation update is needed.
  • Chore: better published unsigned artifacts (#22649)
    This is the exact same change as @bolinfest made but he could not push
    because of github action change permission.
    
    ## Why
    
    The `rust-release` workflow can now be run manually with
    `sign_macos=false` to skip macOS signing, but that path previously
    stopped before creating a GitHub Release. That left the unsigned macOS
    binaries available only as workflow-run artifacts, which are awkward to
    fetch from automation and cannot be retrieved with a simple
    unauthenticated `curl`.
    
    For the unsigned path we still should not perform the normal release
    side effects: no npm or Python publishing, no WinGet publishing, no
    `latest-alpha-cli` branch update, and no promotion to GitHub's latest
    release. The goal is only to make the build outputs easy to fetch from
    the release page.
    
    ## What changed
    
    - Allow the `release` job in `.github/workflows/rust-release.yml` to run
    for `workflow_dispatch` runs with `sign_macos=false`.
    - For unsigned runs, keep the unsigned macOS artifacts plus the normal
    Linux and Windows release artifacts needed for DotSlash, then
    create/update the GitHub Release with `make_latest: false`.
    - Keep the normal publish/promote paths gated to signed releases:
      - npm staging and publish
      - Python runtime publish
      - WinGet publish
      - `latest-alpha-cli` update
      - developer-site deploy
      - normal DotSlash release files
    - Add `.github/dotslash-unsigned-config.json`, which publishes
    `*-unsigned` DotSlash files that use unsigned macOS artifacts and the
    normal Linux/Windows artifacts.
    
    
    ## What I added
    PLEASE READ THIS!!!
    I added `codex-command-runner` and `codex-windows-sandbox-setup` entries
    to `.github/dotslash-unsigned-config.json` so that with
    `sign_macos=false` we would still get the dotslash files for those
    artifacts which are necessary for windows builds.
  • Add unsigned macOS release artifacts (#22559)
    ## Summary
    - Upload unsigned macOS release binaries before signing so they remain
    available from the workflow run if signing fails
    - Add a manual `workflow_dispatch` option, `sign_macos`, defaulting to
    `true`
    - When `sign_macos=false`, skip macOS signing, signed-name macOS
    artifacts, DMGs, npm/DotSlash/PyPI publishing, latest release marking,
    and `latest-alpha-cli` updates
    
    
    ## Process
    HAVE NOT TESTED YET BUT we should be able to run
    ```
    gh workflow run rust-release.yml \
      -R openai/codex \
      --ref rust-v0.132.0 \
      -f sign_macos=false
    ```
    
    which will then start the rust-release script with `sign_macos` and
    therefore do not codesign mac and also no release afterward.
  • Scope macOS signing secrets to release environment (#22443)
    ## Summary
    - Split macOS Rust release builds into a dedicated `build-macos` job
    - Attach the `macos-signing` environment only to the macOS signing/build
    job
    - Keep Linux release builds outside the Apple signing environment while
    preserving the existing shared release build steps
  • [1/8] Pin Python SDK runtime dependency (#21891)
    ## Why
    
    The Python SDK depends on the app-server runtime package for the bundled
    `codex` binary and schema source of truth. That relationship should be
    explicit in package metadata instead of inferred from matching version
    numbers, so installers, lockfiles, and reviewers can see exactly which
    runtime the SDK expects.
    
    ## What
    
    - Declare `openai-codex-cli-bin==0.131.0a4` as a Python SDK dependency.
    - Update runtime setup helpers to resolve the runtime version from the
    declared dependency pin.
    - Refresh the SDK lockfile for the pinned runtime wheel.
    - Update package/runtime tests and docs that describe where the runtime
    version comes from.
    
    ## Stack
    
    1. This PR `[1/8]` Pin Python SDK runtime dependency
    2. #21893 `[2/8]` Generate Python SDK types from pinned runtime
    3. #21895 `[3/8]` Run Python SDK tests in CI
    4. #21896 `[4/8]` Define Python SDK public API surface
    5. #21905 `[5/8]` Rename Python SDK package to `openai-codex`
    6. #21910 `[6/8]` Add high-level Python SDK approval mode
    7. #22014 `[7/8]` Add Python SDK app-server integration harness
    8. #22021 `[8/8]` Add Python SDK Ruff formatting
    
    ## Verification
    
    - Added coverage for the SDK runtime dependency pin and runtime
    distribution naming.
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • Publish Python runtime wheels on release (#21784)
    ## Why
    
    Published Python SDK builds depend on an exact `openai-codex-cli-bin`
    runtime package, but the release workflow did not publish that runtime
    package to PyPI. That left the SDK packaging story incomplete: release
    artifacts could produce Codex binaries, but Python users still needed a
    matching wheel carrying the platform-specific runtime and helper
    executables.
    
    This PR is stacked on #21787 so release jobs can include helper binaries
    in runtime wheels: Linux wheels include `bwrap` for sandbox fallback,
    and Windows wheels include the signed sandbox/elevation helpers beside
    `codex.exe`.
    
    ## What changed
    
    - Builds platform-specific `openai-codex-cli-bin` wheels from signed
    release binaries on macOS, Linux, and Windows release runners.
    - Packages Linux `bwrap` into musllinux runtime wheels.
    - Packages Windows sandbox helper executables into Windows runtime
    wheels.
    - Uploads runtime wheels as GitHub release assets and publishes them to
    PyPI using trusted publishing from the `pypi` GitHub environment.
    - Keeps the new Python runtime publish job non-blocking so failures need
    follow-up but do not fail the Rust release workflow.
    - Pins the PyPA publish action to the `v1.13.0` commit SHA for
    reproducible release publishing.
    - Documents that runtime wheels are platform wheels published through
    PyPI trusted publishing.
    
    ## Testing
    
    - `ruby -e 'require "yaml"; ARGV.each { |f| YAML.load_file(f); puts "ok
    #{f}" }' .github/workflows/rust-release.yml
    .github/workflows/rust-release-windows.yml`
    - `git diff --check`
    
    CI is the real end-to-end verification for the release workflow path.
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • [codex] Address some more GHA hygiene issues (#21622)
    This does two things:
    
    - We use `persist-credentials: false` everywhere now. This is
    unfortunately not the default in GitHub Actions, but it prevents
    `actions/checkout` from dropping `secrets.GITHUB_TOKEN` onto disk.
    - We interpose (some) template expansions through environment variables.
    I've limited this to contexts that have non-fixed values; contexts that
    are fixed (like `*.result`) are not dangerous to expand directly inline
    (but maybe we should clean those up in the future for consistency
    anyways).
    
    This is a medium-risk change in terms of CI breakage: I did a scan for
    usage of `git push` and other commands that implicitly use the persisted
    credential, but couldn't find any. Even still, some implicit usages of
    the persisted credentials may be lurking. Please ping ww@ if any issues
    arise.
  • Use --locked in cargo build and lint invocations (#21602)
    This ensures CI fails if the committed lockfile is outdated
  • [codex] Fully qualify hash-pins in GitHub Actions (#21436)
    This builds on top of https://github.com/openai/codex/pull/15828 by
    ensuring that hash-pinned actions with version comments are fully
    qualified, rather than referencing floating/mutable comments like "v7".
    This makes actions management tools behave more consistently.
    
    This shouldn't break anything, since it's comment only. But if it does,
    ping ww@ 🙂
  • release: bundle bwrap with Linux codex DotSlash artifact (#21312)
    ## Why
    
    #21255 changed the Linux sandbox fallback so Codex can use a bundled
    `codex-resources/bwrap` executable when no suitable system `bwrap` is
    available. That lookup is relative to the native Codex executable
    returned by
    `std::env::current_exe()`, as implemented in
    [`bundled_bwrap.rs`](https://github.com/openai/codex/blob/9766d3d51cec885114b6d6c53a02e9efbaf87171/codex-rs/linux-sandbox/src/bundled_bwrap.rs#L83-L93).
    
    The release already publishes a separate `bwrap` DotSlash output, but
    the Linux `codex` DotSlash output still pointed at a single-binary
    `.zst` payload. Running the `codex` DotSlash manifest only materializes
    the native `codex` executable; it does not also create sibling files
    from the separate `bwrap` manifest. The fallback path therefore needs
    the Linux `codex` DotSlash artifact itself to include the real `bwrap`
    executable at `codex-resources/bwrap`.
    
    ## What changed
    
    - stage a Linux primary `codex-<target>-bundle.tar.zst` release artifact
    containing `codex` and `codex-resources/bwrap`
    - point the Linux `codex` DotSlash outputs at that bundle tarball
    - leave the standalone `bwrap` DotSlash output in place for consumers
    that want to fetch `bwrap` directly
    
    ## Verification
    
    - `jq . .github/dotslash-config.json`
    - Ruby YAML parse of `.github/workflows/rust-release.yml`
  • release: publish standalone bwrap artifacts (#21256)
    **Summary**
    - Build Linux `bwrap` before the main release binaries.
    - Export the release `bwrap` SHA-256 as `CODEX_BWRAP_SHA256` so the
    Codex binary can verify the bundled fallback.
    - Sign, stage, and upload `bwrap` alongside the primary Linux release
    artifacts.
    
    **Verification**
    - YAML parse check for `.github/workflows/rust-release.yml`
    
    
    
    
    
    
    
    
    
    
    
    ---
    [//]: # (BEGIN SAPLING FOOTER)
    Stack created with [Sapling](https://sapling-scm.com). Best reviewed
    with [ReviewStack](https://reviewstack.dev/openai/codex/pull/21256).
    * #21257
    * __->__ #21256
  • fix: cargo deny (#20627)
    Fix cargo deny by ack the `RUSTSEC` while a fix land
    ```
      RUSTSEC-2026-0118
      NSEC3 closest-encloser proof validation enters unbounded loop on cross-zone responses
    
      RUSTSEC-2026-0119
      CPU exhaustion during message encoding due to O(n²) name compression
    
      Dependency path:
    
      hickory-proto 0.25.2
      └── hickory-resolver 0.25.2
          └── rama-dns 0.3.0-alpha.4
              └── rama-tcp 0.3.0-alpha.4
                  └── codex-network-proxy
    ```
    
    Also upgrade some workers version to prevent this:
    ```
    warning[license-not-encountered]: license was not encountered
        ┌─ ./codex-rs/deny.toml:131:6
        │
    131 │     "OpenSSL",
        │      ━━━━━━━ unmatched license allowance
    
    warning[duplicate]: found 2 duplicate entries for crate 'base64'
       ┌─ /github/workspace/codex-rs/Cargo.lock:79:1
       │
    79 │ ╭ base64 0.21.7 registry+https://github.com/rust-lang/crates.io-index
    80 │ │ base64 0.22.1 registry+https://github.com/rust-lang/crates.io-index
       │ ╰───────────────────────────────────────────────────────────────────┘ lock entries
    ```
  • ci: increase Windows release workflow timeouts (#20343)
    ## Why
    
    #20271 increased the `90`-minute timeout in `rust-release.yml`, but it
    did not update the reusable Windows workflow in
    `rust-release-windows.yml`. As a result, the Windows release compile
    jobs were still capped at `60` minutes and the `windows-x64` primary
    build could continue timing out.
    
    We are keeping the existing `90`-minute timeout in `rust-release.yml`.
    That increase was still directionally correct because the top-level
    release build benefits from extra headroom; the mistake was assuming it
    also covered the reusable Windows jobs.
    
    ## What Changed
    - increase the reusable Windows release workflow timeouts in
    `rust-release-windows.yml` from `60` minutes to `90` minutes
    - update the comment in `rust-release.yml` so it no longer implies that
    the top-level timeout covers the Windows reusable jobs
  • chore: increase release build timeout from 60 min to 90 (#20271)
    Build times are creeping up, so increase the timeout as a precaution.
  • Guard npm update readiness (#19389)
    ## Why
    For npm/Bun-managed installs, the update prompt was treating the latest
    GitHub release as ready to install. During the `0.124.0` release, GitHub
    and npm visibility were not atomic: the root npm wrapper could become
    visible before the npm registry marked that version as the package
    `latest`. That left a window where users could be prompted to upgrade
    before npm was ready for the release.
    
    ## What changed
    - Keep GitHub Releases as the candidate latest-version source for
    npm/Bun installs, but only write the existing `version.json` cache after
    npm registry metadata proves that same root version is ready.
    - Add `codex-rs/tui/src/npm_registry.rs` to validate npm readiness by
    checking `dist-tags.latest` and root package `dist` metadata for the
    GitHub candidate version.
    - Move version parsing helpers into
    `codex-rs/tui/src/update_versions.rs` so that logic can be tested
    without compiling the release-only `updates.rs` module under tests.
    - Update `.github/workflows/rust-release.yml` so the six known platform
    tarballs publish before the root `@openai/codex` wrapper. Other npm
    tarballs publish before the root wrapper, and the SDK publishes after
    the root package it depends on.
  • ci: publish codex-app-server release artifacts (#19447)
    ## Why
    The VS Code extension and desktop app do not need the full TUI binary,
    and `codex-app-server` is materially smaller than standalone `codex`. We
    still want to publish it as an official release artifact, but building
    it by tacking another `--bin` onto the existing release `cargo build`
    invocations would lengthen those jobs.
    
    This change keeps `codex-app-server` on its own release bundle so it can
    build in parallel with the existing `codex` and helper bundles.
    
    ## What changed
    - Made `.github/workflows/rust-release.yml` bundle-aware so each macOS
    and Linux MUSL target now builds either the existing `primary` bundle
    (`codex` and `codex-responses-api-proxy`) or a standalone `app-server`
    bundle (`codex-app-server`).
    - Preserved the historical artifact names for the primary macOS/Linux
    bundles so `scripts/stage_npm_packages.py` and
    `codex-cli/scripts/install_native_deps.py` continue to find release
    assets under the paths they already expect, while giving the new
    app-server artifacts distinct names.
    - Added a matching `app-server` bundle to
    `.github/workflows/rust-release-windows.yml`, and updated the final
    Windows packaging job to download, sign, stage, and archive
    `codex-app-server.exe` alongside the existing release binaries.
    - Generalized the shared signing actions in
    `.github/actions/linux-code-sign/action.yml`,
    `.github/actions/macos-code-sign/action.yml`, and
    `.github/actions/windows-code-sign/action.yml` so each workflow row
    declares its binaries once and reuses that list for build, signing, and
    staging.
    - Added `codex-app-server` to `.github/dotslash-config.json` so releases
    also publish a generated DotSlash manifest for the standalone app-server
    binary.
    - Kept the macOS DMG focused on the existing `primary` bundle;
    `codex-app-server` ships as the regular standalone archives and DotSlash
    manifest.
    
    ## Verification
    - Parsed the modified workflow and action YAML files locally with
    `python3` + `yaml.safe_load(...)`.
    - Parsed `.github/dotslash-config.json` locally with `python3` +
    `json.loads(...)`.
    - Reviewed the resulting release matrices, artifact names, and packaging
    paths to confirm that `codex-app-server` is built separately on macOS,
    Linux MUSL, and Windows, while the existing npm staging and Windows
    `codex` zip bundling contracts remain intact.
  • ci: stop publishing GNU Linux release artifacts (#19445)
    ## Why
    We already prefer shipping the MUSL Linux builds, and the in-repo
    release consumers resolve Linux release assets through the MUSL targets.
    Keeping the GNU release jobs around adds release time and extra assets
    without serving the paths we actually publish and consume.
    
    This is also easier to reason about as a standalone change: future work
    can point back to this PR as the intentional decision to stop publishing
    `x86_64-unknown-linux-gnu` and `aarch64-unknown-linux-gnu` release
    artifacts.
    
    ## What changed
    - Removed the `x86_64-unknown-linux-gnu` and `aarch64-unknown-linux-gnu`
    entries from the `build` matrix in `.github/workflows/rust-release.yml`.
    - Added a short comment in that matrix documenting that Linux release
    artifacts intentionally ship MUSL-linked binaries.
    
    ## Verification
    - Reviewed `.github/workflows/rust-release.yml` to confirm that the
    release workflow now only builds Linux release artifacts for
    `x86_64-unknown-linux-musl` and `aarch64-unknown-linux-musl`.
  • fix: pin inputs (#17471)
    ## Summary
    - Pin Rust git patch dependencies to immutable revisions and make
    cargo-deny reject unknown git and registry sources unless explicitly
    allowlisted.
    - Add checked-in SHA-256 coverage for the current rusty_v8 release
    assets, wire those hashes into Bazel, and verify CI override downloads
    before use.
    - Add rusty_v8 MODULE.bazel update/check tooling plus a Bazel CI guard
    so future V8 bumps cannot drift from the checked-in checksum manifest.
    - Pin release/lint cargo installs and all external GitHub Actions refs
    to immutable inputs.
    
    ## Future V8 bump flow
    Run these after updating the resolved `v8` crate version and checksum
    manifest:
    
    ```bash
    python3 .github/scripts/rusty_v8_bazel.py update-module-bazel
    python3 .github/scripts/rusty_v8_bazel.py check-module-bazel
    ```
    
    The update command rewrites the matching `rusty_v8_<crate_version>`
    `http_file` SHA-256 values in `MODULE.bazel` from
    `third_party/v8/rusty_v8_<crate_version>.sha256`. The check command is
    also wired into Bazel CI to block drift.
    
    ## Notes
    - This intentionally excludes RustSec dependency upgrades and
    bubblewrap-related changes per request.
    - The branch was rebased onto the latest origin/main before opening the
    PR.
    
    ## Validation
    - cargo fetch --locked
    - cargo deny check advisories
    - cargo deny check
    - cargo deny check sources
    - python3 .github/scripts/rusty_v8_bazel.py check-module-bazel
    - python3 .github/scripts/rusty_v8_bazel.py update-module-bazel
    - python3 -m unittest discover -s .github/scripts -p
    'test_rusty_v8_bazel.py'
    - python3 -m py_compile .github/scripts/rusty_v8_bazel.py
    .github/scripts/rusty_v8_module_bazel.py
    .github/scripts/test_rusty_v8_bazel.py
    - repo-wide GitHub Actions `uses:` audit: all external action refs are
    pinned to 40-character SHAs
    - yq eval on touched workflows and local actions
    - git diff --check
    - just bazel-lock-check
    
    ## Hash verification
    - Confirmed `MODULE.bazel` hashes match
    `third_party/v8/rusty_v8_146_4_0.sha256`.
    - Confirmed GitHub release asset digests for denoland/rusty_v8
    `v146.4.0` and openai/codex `rusty-v8-v146.4.0` match the checked-in
    hashes.
    - Streamed and SHA-256 hashed all 10 `MODULE.bazel` rusty_v8 asset URLs
    locally; every downloaded byte stream matched both `MODULE.bazel` and
    the checked-in manifest.
    
    ## Pin verification
    - Confirmed signing-action pins match the peeled commits for their tag
    comments: `sigstore/cosign-installer@v3.7.0`, `azure/login@v2`, and
    `azure/trusted-signing-action@v0`.
    - Pinned the remaining tag-based action refs in Bazel CI/setup:
    `actions/setup-node@v6`, `facebook/install-dotslash@v2`,
    `bazelbuild/setup-bazelisk@v3`, and `actions/cache/restore@v5`.
    - Normalized all `bazelbuild/setup-bazelisk@v3` refs to the peeled
    commit behind the annotated tag.
    - Audited Cargo git dependencies: every manifest git dependency uses
    `rev` only, every `Cargo.lock` git source has `?rev=<sha>#<same-sha>`,
    and `cargo deny check sources` passes with `required-git-spec = "rev"`.
    - Shallow-fetched each distinct git dependency repo at its pinned SHA
    and verified Git reports each object as a commit.
  • Use Node 24 for npm publish (#16755)
    Avoid self-upgrading the runner's bundled npm in release publishing;
    Node 24 already provides an npm CLI that supports trusted publishing.
    
    Co-authored-by: Codex <noreply@openai.com>
  • [codex] Pin GitHub Actions workflow references (#15828)
    Pin floating external GitHub Actions workflow refs to immutable SHAs.
    
    Why are we doing this? Please see the rationale doc:
    https://docs.google.com/document/d/1qOURCNx2zszQ0uWx7Fj5ERu4jpiYjxLVWBWgKa2wTsA/edit?tab=t.0
    
    Did this break you? Please roll back and let hintz@ know
  • fix: keep zsh-fork release assets after removing shell-tool-mcp (#15644)
    ## Why
    
    `shell-tool-mcp` and the Bash fork are no longer needed, but the patched
    zsh fork is still relevant for shell escalation and for the
    DotSlash-backed zsh-fork integration tests.
    
    Deleting the old `shell-tool-mcp` workflow also deleted the only
    pipeline that rebuilt those patched zsh binaries. This keeps the package
    removal, while preserving a small release path that can be reused
    whenever `codex-rs/shell-escalation/patches/zsh-exec-wrapper.patch`
    changes.
    
    ## What changed
    
    - removed the `shell-tool-mcp` workspace package, its npm
    packaging/release jobs, the Bash test fixture, and the remaining
    Bash-specific compatibility wiring
    - deleted the old `.github/workflows/shell-tool-mcp.yml` and
    `.github/workflows/shell-tool-mcp-ci.yml` workflows now that their
    responsibilities have been replaced or removed
    - kept the zsh patch under
    `codex-rs/shell-escalation/patches/zsh-exec-wrapper.patch` and updated
    the `codex-rs/shell-escalation` docs/code to describe the zsh-based flow
    directly
    - added `.github/workflows/rust-release-zsh.yml` to build only the three
    zsh binaries that `codex-rs/app-server/tests/suite/zsh` needs today:
      - `aarch64-apple-darwin` on `macos-15`
      - `x86_64-unknown-linux-musl` on `ubuntu-24.04`
      - `aarch64-unknown-linux-musl` on `ubuntu-24.04`
    - extracted the shared zsh build/smoke-test/stage logic into
    `.github/scripts/build-zsh-release-artifact.sh`, made that helper
    directly executable, and now invoke it directly from the workflow so the
    Linux and macOS jobs only keep the OS-specific setup in YAML
    - wired those standalone `codex-zsh-*.tar.gz` assets into
    `rust-release.yml` and added `.github/dotslash-zsh-config.json` so
    releases also publish a `codex-zsh` DotSlash file
    - updated the checked-in `codex-rs/app-server/tests/suite/zsh` fixture
    comments to explain that new releases come from the standalone zsh
    assets, while the checked-in fixture remains pinned to the latest
    historical release until a newer zsh artifact is published
    - tightened a couple of follow-on cleanups in
    `codex-rs/shell-escalation`: the `ExecParams::command` comment now
    describes the shell `-c`/`-lc` string more clearly, and the README now
    points at the same `git.code.sf.net` zsh source URL that the workflow
    uses
    
    ## Testing
    
    - `cargo test -p codex-shell-escalation`
    - `just argument-comment-lint`
    - `bash -n .github/scripts/build-zsh-release-artifact.sh`
    - attempted `cargo test -p codex-core`; unrelated existing failures
    remain, but the touched `tools::runtimes::shell::unix_escalation::*`
    coverage passed during that run
  • Bump vedantmgoyal9/winget-releaser from 19e706d4c9121098010096f9c495a70a7518b30f to 7bd472be23763def6e16bd06cc8b1cdfab0e2fd5 (#14777)
    Bumps
    [vedantmgoyal9/winget-releaser](https://github.com/vedantmgoyal9/winget-releaser)
    from 19e706d4c9121098010096f9c495a70a7518b30f to
    7bd472be23763def6e16bd06cc8b1cdfab0e2fd5.
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/vedantmgoyal9/winget-releaser/commit/7bd472be23763def6e16bd06cc8b1cdfab0e2fd5"><code>7bd472b</code></a>
    docs: add description to inputs (<a
    href="https://redirect.github.com/vedantmgoyal9/winget-releaser/issues/335">#335</a>)</li>
    <li><a
    href="https://github.com/vedantmgoyal9/winget-releaser/commit/a43926ed822e5a076ac8a81e0a794915cbad51d1"><code>a43926e</code></a>
    fix: cargo command not found in <code>ubuntu-slim</code> runner (<a
    href="https://redirect.github.com/vedantmgoyal9/winget-releaser/issues/334">#334</a>)</li>
    <li>See full diff in <a
    href="https://github.com/vedantmgoyal9/winget-releaser/compare/19e706d4c9121098010096f9c495a70a7518b30f...7bd472be23763def6e16bd06cc8b1cdfab0e2fd5">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    Dependabot will resolve any conflicts with this PR as long as you don't
    alter it yourself. You can also trigger a rebase manually by commenting
    `@dependabot rebase`.
    
    [//]: # (dependabot-automerge-start)
    [//]: # (dependabot-automerge-end)
    
    ---
    
    <details>
    <summary>Dependabot commands and options</summary>
    <br />
    
    You can trigger Dependabot actions by commenting on this PR:
    - `@dependabot rebase` will rebase this PR
    - `@dependabot recreate` will recreate this PR, overwriting any edits
    that have been made to it
    - `@dependabot show <dependency name> ignore conditions` will show all
    of the ignore conditions of the specified dependency
    - `@dependabot ignore this major version` will close this PR and stop
    Dependabot creating any more for this major version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this minor version` will close this PR and stop
    Dependabot creating any more for this minor version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this dependency` will close this PR and stop
    Dependabot creating any more for this dependency (unless you reopen the
    PR or upgrade to it yourself)
    
    
    </details>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • chore(deps): bump pnpm/action-setup from 4 to 5 (#15484)
    Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 4
    to 5.
    <details>
    <summary>Release notes</summary>
    <p><em>Sourced from <a
    href="https://github.com/pnpm/action-setup/releases">pnpm/action-setup's
    releases</a>.</em></p>
    <blockquote>
    <h2>v5.0.0</h2>
    <p>Updated the action to use Node.js 24.</p>
    <h2>v4.4.0</h2>
    <p>Updated the action to use Node.js 24.</p>
    <h2>v4.3.0</h2>
    <h2>What's Changed</h2>
    <ul>
    <li>docs: fix the run_install example in the Readme by <a
    href="https://github.com/dreyks"><code>@​dreyks</code></a> in <a
    href="https://redirect.github.com/pnpm/action-setup/pull/175">pnpm/action-setup#175</a></li>
    <li>chore: remove unused <code>@types/node-fetch</code> dependency by <a
    href="https://github.com/silverwind"><code>@​silverwind</code></a> in <a
    href="https://redirect.github.com/pnpm/action-setup/pull/186">pnpm/action-setup#186</a></li>
    <li>Clarify that package_json_file is relative to GITHUB_WORKSPACE by <a
    href="https://github.com/chris-martin"><code>@​chris-martin</code></a>
    in <a
    href="https://redirect.github.com/pnpm/action-setup/pull/184">pnpm/action-setup#184</a></li>
    <li>feat: store caching by <a
    href="https://github.com/jrmajor"><code>@​jrmajor</code></a> in <a
    href="https://redirect.github.com/pnpm/action-setup/pull/188">pnpm/action-setup#188</a></li>
    <li>refactor: remove star imports by <a
    href="https://github.com/KSXGitHub"><code>@​KSXGitHub</code></a> in <a
    href="https://redirect.github.com/pnpm/action-setup/pull/196">pnpm/action-setup#196</a></li>
    <li>fix(ci): exclude macos by <a
    href="https://github.com/KSXGitHub"><code>@​KSXGitHub</code></a> in <a
    href="https://redirect.github.com/pnpm/action-setup/pull/197">pnpm/action-setup#197</a></li>
    </ul>
    <h2>New Contributors</h2>
    <ul>
    <li><a href="https://github.com/dreyks"><code>@​dreyks</code></a> made
    their first contribution in <a
    href="https://redirect.github.com/pnpm/action-setup/pull/175">pnpm/action-setup#175</a></li>
    <li><a
    href="https://github.com/silverwind"><code>@​silverwind</code></a> made
    their first contribution in <a
    href="https://redirect.github.com/pnpm/action-setup/pull/186">pnpm/action-setup#186</a></li>
    <li><a
    href="https://github.com/chris-martin"><code>@​chris-martin</code></a>
    made their first contribution in <a
    href="https://redirect.github.com/pnpm/action-setup/pull/184">pnpm/action-setup#184</a></li>
    <li><a href="https://github.com/jrmajor"><code>@​jrmajor</code></a> made
    their first contribution in <a
    href="https://redirect.github.com/pnpm/action-setup/pull/188">pnpm/action-setup#188</a></li>
    <li><a
    href="https://github.com/Boosted-Bonobo"><code>@​Boosted-Bonobo</code></a>
    made their first contribution in <a
    href="https://redirect.github.com/pnpm/action-setup/pull/199">pnpm/action-setup#199</a></li>
    </ul>
    <p><strong>Full Changelog</strong>: <a
    href="https://github.com/pnpm/action-setup/compare/v4.2.0...v4.3.0">https://github.com/pnpm/action-setup/compare/v4.2.0...v4.3.0</a></p>
    <h2>v4.2.0</h2>
    <p>When there's a <code>.npmrc</code> file at the root of the
    repository, pnpm will be fetched from the registry that is specified in
    that <code>.npmrc</code> file <a
    href="https://redirect.github.com/pnpm/action-setup/pull/179">#179</a></p>
    <h2>v4.1.0</h2>
    <p>Add support for <code>package.yaml</code> <a
    href="https://redirect.github.com/pnpm/action-setup/pull/156">#156</a>.</p>
    </blockquote>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li>See full diff in <a
    href="https://github.com/pnpm/action-setup/compare/v4...v5">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    [![Dependabot compatibility
    score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pnpm/action-setup&package-manager=github_actions&previous-version=4&new-version=5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
    
    Dependabot will resolve any conflicts with this PR as long as you don't
    alter it yourself. You can also trigger a rebase manually by commenting
    `@dependabot rebase`.
    
    [//]: # (dependabot-automerge-start)
    [//]: # (dependabot-automerge-end)
    
    ---
    
    <details>
    <summary>Dependabot commands and options</summary>
    <br />
    
    You can trigger Dependabot actions by commenting on this PR:
    - `@dependabot rebase` will rebase this PR
    - `@dependabot recreate` will recreate this PR, overwriting any edits
    that have been made to it
    - `@dependabot show <dependency name> ignore conditions` will show all
    of the ignore conditions of the specified dependency
    - `@dependabot ignore this major version` will close this PR and stop
    Dependabot creating any more for this major version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this minor version` will close this PR and stop
    Dependabot creating any more for this minor version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this dependency` will close this PR and stop
    Dependabot creating any more for this dependency (unless you reopen the
    PR or upgrade to it yourself)
    
    
    </details>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Add v8-poc consumer of our new built v8 (#15203)
    This adds a dummy v8-poc project that in Cargo links against our
    prebuilt binaries and the ones provided by rusty_v8 for non musl
    platforms. This demonstrates that we can successfully link and use v8 on
    all platforms that we want to target.
    
    In bazel things are slightly more complicated. Since the libraries as
    published have libc++ linked in already we end up with a lot of double
    linked symbols if we try to use them in bazel land. Instead we fall back
    to building rusty_v8 and v8 from source (cached of course) on the
    platforms we ship to.
    
    There is likely some compatibility drift in the windows bazel builder
    that we'll need to reconcile before we can re-enable them. I'm happy to
    be on the hook to unwind that.
  • Publish runnable DotSlash package for argument-comment lint (#15198)
    ## Why
    
    To date, the argument-comment linter introduced in
    https://github.com/openai/codex/pull/14651 had to be built from source
    to run, which can be a bit slow (both for local dev and when it is run
    in CI). Because of the potential slowness, I did not wire it up to run
    as part of `just clippy` or anything like that. As a result, I have seen
    a number of occasions where folks put up PRs that violate the lint, see
    it fail in CI, and then have to put up their PR again.
    
    The goal of this PR is to pre-build a runnable version of the linter and
    then make it available via a DotSlash file. Once it is available, I will
    update `just clippy` and other touchpoints to make it a natural part of
    the dev cycle so lint violations should get flagged _before_ putting up
    a PR for review.
    
    To get things started, we will build the DotSlash file as part of an
    alpha release. Though I don't expect the linter to change often, so I'll
    probably change this to only build as part of mainline releases once we
    have a working DotSlash file. (Ultimately, we should probably move the
    linter into its own repo so it can have its own release cycle.)
    
    ## What Changed
    - add a reusable `rust-release-argument-comment-lint.yml` workflow that
    builds host-specific archives for macOS arm64, Linux arm64/x64, and
    Windows x64
    - wire `rust-release.yml` to publish the `argument-comment-lint`
    DotSlash manifest on all releases for now, including alpha tags
    - package a runnable layout instead of a bare library
    
    The Unix archive layout is:
    
    ```text
    argument-comment-lint/
      bin/
        argument-comment-lint
        cargo-dylint
      lib/
        libargument_comment_lint@nightly-2025-09-18-<target>.dylib|so
    ```
    
    On Windows the same layout is published as a `.zip`, with `.exe` and
    `.dll` filenames instead.
    
    DotSlash resolves the package entrypoint to
    `argument-comment-lint/bin/argument-comment-lint`. That runner finds the
    sibling bundled `cargo-dylint` binary plus the single packaged Dylint
    library under `lib/`, then invokes `cargo-dylint dylint --lib-path
    <that-library>` with the repo's default lint settings.
  • Pin setup-zig GitHub Action to immutable SHA (#14858)
    ### Motivation
    - Pinning the action to an immutable commit SHA reduces the risk of
    arbitrary code execution in runners with repository access and secrets.
    
    ### Description
    - Replaced `uses: mlugg/setup-zig@v2` with `uses:
    mlugg/setup-zig@d1434d0886 # v2` in three
    workflow files.
    - Updated the following files: ` .github/workflows/rust-ci.yml`, `
    .github/workflows/rust-release.yml`, and `
    .github/workflows/shell-tool-mcp.yml` to reference the immutable SHA
    while preserving the original `v2` intent in a trailing comment.
    
    ### Testing
    - No automated tests were run because this is a workflow-only change and
    does not affect repository source code, so CI validation will occur on
    the next workflow execution.
    
    ------
    [Codex
    Task](https://chatgpt.com/codex/tasks/task_i_69763f570234832d9c67b1b66a27c78d)
  • fix: tighten up shell arg quoting in GitHub workflows (#14864)
    Inspired by the work done over in
    https://github.com/openai/codex-action/pull/74, this tightens up our use
    of GitHub expressions as shell/environment variables.
  • Codex/winget auto update (#12943)
    Publish CLI releases to winget.
    
    Uses https://github.com/vedantmgoyal9/winget-releaser to greatly reduce
    boilerplate needed to create winget-pkgs manifets
  • chore(deps): bump actions/upload-artifact from 6 to 7 (#13207)
    Bumps
    [actions/upload-artifact](https://github.com/actions/upload-artifact)
    from 6 to 7.
    <details>
    <summary>Release notes</summary>
    <p><em>Sourced from <a
    href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's
    releases</a>.</em></p>
    <blockquote>
    <h2>v7.0.0</h2>
    <h2>v7 What's new</h2>
    <h3>Direct Uploads</h3>
    <p>Adds support for uploading single files directly (unzipped). Callers
    can set the new <code>archive</code> parameter to <code>false</code> to
    skip zipping the file during upload. Right now, we only support single
    files. The action will fail if the glob passed resolves to multiple
    files. The <code>name</code> parameter is also ignored with this
    setting. Instead, the name of the artifact will be the name of the
    uploaded file.</p>
    <h3>ESM</h3>
    <p>To support new versions of the <code>@actions/*</code> packages,
    we've upgraded the package to ESM.</p>
    <h2>What's Changed</h2>
    <ul>
    <li>Add proxy integration test by <a
    href="https://github.com/Link"><code>@​Link</code></a>- in <a
    href="https://redirect.github.com/actions/upload-artifact/pull/754">actions/upload-artifact#754</a></li>
    <li>Upgrade the module to ESM and bump dependencies by <a
    href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
    <a
    href="https://redirect.github.com/actions/upload-artifact/pull/762">actions/upload-artifact#762</a></li>
    <li>Support direct file uploads by <a
    href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
    <a
    href="https://redirect.github.com/actions/upload-artifact/pull/764">actions/upload-artifact#764</a></li>
    </ul>
    <h2>New Contributors</h2>
    <ul>
    <li><a href="https://github.com/Link"><code>@​Link</code></a>- made
    their first contribution in <a
    href="https://redirect.github.com/actions/upload-artifact/pull/754">actions/upload-artifact#754</a></li>
    </ul>
    <p><strong>Full Changelog</strong>: <a
    href="https://github.com/actions/upload-artifact/compare/v6...v7.0.0">https://github.com/actions/upload-artifact/compare/v6...v7.0.0</a></p>
    </blockquote>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/actions/upload-artifact/commit/bbbca2ddaa5d8feaa63e36b76fdaad77386f024f"><code>bbbca2d</code></a>
    Support direct file uploads (<a
    href="https://redirect.github.com/actions/upload-artifact/issues/764">#764</a>)</li>
    <li><a
    href="https://github.com/actions/upload-artifact/commit/589182c5a4cec8920b8c1bce3e2fab1c97a02296"><code>589182c</code></a>
    Upgrade the module to ESM and bump dependencies (<a
    href="https://redirect.github.com/actions/upload-artifact/issues/762">#762</a>)</li>
    <li><a
    href="https://github.com/actions/upload-artifact/commit/47309c993abb98030a35d55ef7ff34b7fa1074b5"><code>47309c9</code></a>
    Merge pull request <a
    href="https://redirect.github.com/actions/upload-artifact/issues/754">#754</a>
    from actions/Link-/add-proxy-integration-tests</li>
    <li><a
    href="https://github.com/actions/upload-artifact/commit/02a8460834e70dab0ce194c64360c59dc1475ef0"><code>02a8460</code></a>
    Add proxy integration test</li>
    <li>See full diff in <a
    href="https://github.com/actions/upload-artifact/compare/v6...v7">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    [![Dependabot compatibility
    score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/upload-artifact&package-manager=github_actions&previous-version=6&new-version=7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
    
    Dependabot will resolve any conflicts with this PR as long as you don't
    alter it yourself. You can also trigger a rebase manually by commenting
    `@dependabot rebase`.
    
    [//]: # (dependabot-automerge-start)
    [//]: # (dependabot-automerge-end)
    
    ---
    
    <details>
    <summary>Dependabot commands and options</summary>
    <br />
    
    You can trigger Dependabot actions by commenting on this PR:
    - `@dependabot rebase` will rebase this PR
    - `@dependabot recreate` will recreate this PR, overwriting any edits
    that have been made to it
    - `@dependabot show <dependency name> ignore conditions` will show all
    of the ignore conditions of the specified dependency
    - `@dependabot ignore this major version` will close this PR and stop
    Dependabot creating any more for this major version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this minor version` will close this PR and stop
    Dependabot creating any more for this minor version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this dependency` will close this PR and stop
    Dependabot creating any more for this dependency (unless you reopen the
    PR or upgrade to it yourself)
    
    
    </details>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    Co-authored-by: Eric Traut <etraut@openai.com>
  • chore(deps): bump actions/download-artifact from 7 to 8 (#13208)
    Bumps
    [actions/download-artifact](https://github.com/actions/download-artifact)
    from 7 to 8.
    <details>
    <summary>Release notes</summary>
    <p><em>Sourced from <a
    href="https://github.com/actions/download-artifact/releases">actions/download-artifact's
    releases</a>.</em></p>
    <blockquote>
    <h2>v8.0.0</h2>
    <h2>v8 - What's new</h2>
    <h3>Direct downloads</h3>
    <p>To support direct uploads in <code>actions/upload-artifact</code>,
    the action will no longer attempt to unzip all downloaded files.
    Instead, the action checks the <code>Content-Type</code> header ahead of
    unzipping and skips non-zipped files. Callers wishing to download a
    zipped file as-is can also set the new <code>skip-decompress</code>
    parameter to <code>false</code>.</p>
    <h3>Enforced checks (breaking)</h3>
    <p>A previous release introduced digest checks on the download. If a
    download hash didn't match the expected hash from the server, the action
    would log a warning. Callers can now configure the behavior on mismatch
    with the <code>digest-mismatch</code> parameter. To be secure by
    default, we are now defaulting the behavior to <code>error</code> which
    will fail the workflow run.</p>
    <h3>ESM</h3>
    <p>To support new versions of the @actions/* packages, we've upgraded
    the package to ESM.</p>
    <h2>What's Changed</h2>
    <ul>
    <li>Don't attempt to un-zip non-zipped downloads by <a
    href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
    <a
    href="https://redirect.github.com/actions/download-artifact/pull/460">actions/download-artifact#460</a></li>
    <li>Add a setting to specify what to do on hash mismatch and default it
    to <code>error</code> by <a
    href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
    <a
    href="https://redirect.github.com/actions/download-artifact/pull/461">actions/download-artifact#461</a></li>
    </ul>
    <p><strong>Full Changelog</strong>: <a
    href="https://github.com/actions/download-artifact/compare/v7...v8.0.0">https://github.com/actions/download-artifact/compare/v7...v8.0.0</a></p>
    </blockquote>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/actions/download-artifact/commit/70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3"><code>70fc10c</code></a>
    Merge pull request <a
    href="https://redirect.github.com/actions/download-artifact/issues/461">#461</a>
    from actions/danwkennedy/digest-mismatch-behavior</li>
    <li><a
    href="https://github.com/actions/download-artifact/commit/f258da9a506b755b84a09a531814700b86ccfc62"><code>f258da9</code></a>
    Add change docs</li>
    <li><a
    href="https://github.com/actions/download-artifact/commit/ccc058e5fbb0bb2352213eaec3491e117cbc4a5c"><code>ccc058e</code></a>
    Fix linting issues</li>
    <li><a
    href="https://github.com/actions/download-artifact/commit/bd7976ba57ecea96e6f3df575eb922d11a12a9fd"><code>bd7976b</code></a>
    Add a setting to specify what to do on hash mismatch and default it to
    <code>error</code></li>
    <li><a
    href="https://github.com/actions/download-artifact/commit/ac21fcf45e0aaee541c0f7030558bdad38d77d6c"><code>ac21fcf</code></a>
    Merge pull request <a
    href="https://redirect.github.com/actions/download-artifact/issues/460">#460</a>
    from actions/danwkennedy/download-no-unzip</li>
    <li><a
    href="https://github.com/actions/download-artifact/commit/15999bff51058bc7c19b50ebbba518eaef7c26c0"><code>15999bf</code></a>
    Add note about package bumps</li>
    <li><a
    href="https://github.com/actions/download-artifact/commit/974686ed5098c7f9c9289ec946b9058e496a2561"><code>974686e</code></a>
    Bump the version to <code>v8</code> and add release notes</li>
    <li><a
    href="https://github.com/actions/download-artifact/commit/fbe48b1d2756394be4cd4358ed3bc1343b330e75"><code>fbe48b1</code></a>
    Update test names to make it clearer what they do</li>
    <li><a
    href="https://github.com/actions/download-artifact/commit/96bf374a614d4360e225874c3efd6893a3f285e7"><code>96bf374</code></a>
    One more test fix</li>
    <li><a
    href="https://github.com/actions/download-artifact/commit/b8c4819ef592cbe04fd93534534b38f853864332"><code>b8c4819</code></a>
    Fix skip decompress test</li>
    <li>Additional commits viewable in <a
    href="https://github.com/actions/download-artifact/compare/v7...v8">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    [![Dependabot compatibility
    score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/download-artifact&package-manager=github_actions&previous-version=7&new-version=8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
    
    Dependabot will resolve any conflicts with this PR as long as you don't
    alter it yourself. You can also trigger a rebase manually by commenting
    `@dependabot rebase`.
    
    [//]: # (dependabot-automerge-start)
    [//]: # (dependabot-automerge-end)
    
    ---
    
    <details>
    <summary>Dependabot commands and options</summary>
    <br />
    
    You can trigger Dependabot actions by commenting on this PR:
    - `@dependabot rebase` will rebase this PR
    - `@dependabot recreate` will recreate this PR, overwriting any edits
    that have been made to it
    - `@dependabot show <dependency name> ignore conditions` will show all
    of the ignore conditions of the specified dependency
    - `@dependabot ignore this major version` will close this PR and stop
    Dependabot creating any more for this major version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this minor version` will close this PR and stop
    Dependabot creating any more for this minor version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this dependency` will close this PR and stop
    Dependabot creating any more for this dependency (unless you reopen the
    PR or upgrade to it yourself)
    
    
    </details>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Add Windows direct install script (#12741)
    ## Summary
    - add a direct install script for Windows at
    `scripts/install/install.ps1`
    - extend release staging so `install.ps1` is published alongside
    `install.sh`
    - install the Windows runtime payload (`codex.exe`, `rg.exe`, and helper
    binaries) from the existing platform npm package
    
    ## Dependencies
    - Depends on https://github.com/openai/codex/pull/12740
    
    ## Testing
    - Smoke-tested with powershell
  • Add macOS and Linux direct install script (#12740)
    ## Summary
    - add a direct install script for macOS and Linux at
    `scripts/install/install.sh`
    - stage `install.sh` into `dist/` during release so it is published as a
    GitHub release asset
    - reuse the existing platform npm payload so the installer includes both
    `codex` and `rg`
    
    ## Testing
    - `bash -n scripts/install/install.sh`
    - local macOS `curl | sh` smoke test against a locally served copy of
    the script
  • add AWS_LC_SYS_NO_JITTER_ENTROPY=1 to release musl build step to unblock releases (#12720)
    linux musl build steps in `rust-release.yml` are [currently
    broken](https://github.com/openai/codex/actions/runs/22367312571)
    because of linking issues due to ubsan-calling types (`jitterentropy`)
    leaking into the build.
    
    add `AWS_LC_SYS_NO_JITTER_ENTROPY=1` to the musl build step to avoid
    linking those ubsan-calling types. this is a more temporary fix, we need
    to clean up ubsan usage upstream so they dont leak into release-build
    steps anyways.
    
    codex's more thorough explanation below:
    
    [pr 9859](https://github.com/openai/codex/pull/9859) added [MITM
    init](https://github.com/openai/codex/pull/9859/changes#diff-db782967007060c5520651633e1ea21681d64be21f2b791d3d84519860245b97R62-R68)
    in network-proxy, which wires in cert generation code (rcgen/rustls).
    this didnt bump/change dep versions, but it changed symbol reachability
    at link time.
    
    for musl builds, that made aws-lc-sys’s jitterentropy objects get pulled
    into the final link. those objects contain UBSan calls
    (__ubsan_handle_*). musl release linking is static (*-linux-musl-gcc,
    -nodefaultlibs) and does not link a musl UBSan runtime, so link fails
    with undefined __ubsan_*.
    
    before, our custom musl CI UBSan steps (install libubsan1, RUSTC_WRAPPER
    + LD_PRELOAD, partial flag scrubbing) masked some sanitizer issues.
    after this pr, more aws-lc code became link-reachable, and that band-aid
    wasn't enough.
  • fix(ci) lock rust toolchain at 1.93.0 to unblock (#11703)
    ## Summary
    CI is broken on main because our CI toolchain is trying to run 1.93.1
    while our rust toolchain is locked at 1.93.0. I'm sure it's likely safe
    to upgrade, but let's keep things stable for now.
    
    ## Testing
    - [x] CI should hopefully pass
  • rust-release: exclude cargo-timing.html from release assets (#11564)
    ## Why
    The `release` job in `.github/workflows/rust-release.yml` uploads
    `files: dist/**` via `softprops/action-gh-release`. The downloaded
    timing artifacts include multiple files with the same basename,
    `cargo-timing.html` (one per target), which causes release asset
    collisions/races and can fail with GitHub release-assets API `404 Not
    Found` errors.
    
    ## What Changed
    - Updated the existing cleanup step before `Create GitHub Release` to
    remove all `cargo-timing.html` files from `dist/`.
    - Removed any now-empty directories after deleting those timing files.
    
    Relevant change:
    -
    https://github.com/openai/codex/blob/daba003d32f299579e9b89240aa8ebdc9f161424/.github/workflows/rust-release.yml#L423
    
    ## Verification
    - Confirmed from failing release logs that multiple `cargo-timing.html`
    files were being included in `dist/**` and that the release step failed
    while operating on duplicate-named assets.
    - Verified the workflow now deletes those files before the release
    upload step, so `cargo-timing.html` is no longer part of the release
    asset set.
  • ci: capture cargo timings in Rust CI and release workflows (#11543)
    ## Why
    We want actionable build-hotspot data from CI so we can tune Rust
    workflow performance (for example, target coverage, cache behavior, and
    job shape) based on actual compile-time bottlenecks.
    
    `cargo` timing reports are lightweight and provide a direct way to
    inspect where compilation time is spent.
    
    ## What Changed
    - Updated `.github/workflows/rust-release.yml` to run `cargo build` with
    `--timings` and upload `target/**/cargo-timings/cargo-timing.html`.
    - Updated `.github/workflows/rust-release-windows.yml` to run `cargo
    build` with `--timings` and upload
    `target/**/cargo-timings/cargo-timing.html`.
    - Updated `.github/workflows/rust-ci.yml` to:
      - run `cargo clippy` with `--timings`
      - run `cargo nextest run` with `--timings` (stable-compatible)
    - upload `target/**/cargo-timings/cargo-timing.html` artifacts for both
    the clippy and nextest jobs
    
    Artifacts are matrix-scoped via artifact names so timings can be
    compared per target/profile.
    
    ## Verification
    - Confirmed the net diff is limited to:
      - `.github/workflows/rust-ci.yml`
      - `.github/workflows/rust-release.yml`
      - `.github/workflows/rust-release-windows.yml`
    - Verified timing uploads are added immediately after the corresponding
    timed commands in each workflow.
    - Confirmed stable Cargo accepts plain `--timings` for the compile phase
    (`cargo test --no-run --timings`) and generates
    `target/cargo-timings/cargo-timing.html`.
    - Ran VS Code diagnostics on modified workflow files; no new diagnostics
    were introduced by these changes.
  • build(linux-sandbox): always compile vendored bubblewrap on Linux; remove CODEX_BWRAP_ENABLE_FFI (#11498)
    ## Summary
    This PR removes the temporary `CODEX_BWRAP_ENABLE_FFI` flag and makes
    Linux builds always compile vendored bubblewrap support for
    `codex-linux-sandbox`.
    
    ## Changes
    - Removed `CODEX_BWRAP_ENABLE_FFI` gating from
    `codex-rs/linux-sandbox/build.rs`.
    - Linux builds now fail fast if vendored bubblewrap compilation fails
    (instead of warning and continuing).
    - Updated fallback/help text in
    `codex-rs/linux-sandbox/src/vendored_bwrap.rs` to remove references to
    `CODEX_BWRAP_ENABLE_FFI`.
    - Removed `CODEX_BWRAP_ENABLE_FFI` env wiring from:
      - `.github/workflows/rust-ci.yml`
      - `.github/workflows/bazel.yml`
      - `.github/workflows/rust-release.yml`
    
    ---------
    
    Co-authored-by: David Zbarsky <zbarsky@openai.com>
  • ci: remove actions/cache from rust release workflows (#11540)
    ## Why
    
    `rust-release` cache restore has had very low practical value, while
    cache save consistently costs significant time (usually adding ~3
    minutes to the critical path of a release workflow).
    
    From successful release-tag runs with cache steps (`289` runs total):
    - Alpha tags: cache download averaged ~5s/run, cache upload averaged
    ~230s/run.
    - Stable tags: cache download averaged ~5s/run, cache upload averaged
    ~227s/run.
    - Windows release builds specifically: download ~2s/run vs upload
    ~169-170s/run.
    
    Hard step-level signal from the same successful release-tag runs:
    - Cache restore (`Run actions/cache`): `2,314` steps, total `1,515s`
    (~0.65s/step).
    - `95.3%` of restore steps finished in `<=1s`; `99.7%` finished in
    `<=2s`; `0` steps took `>=10s`.
    - Cache save (`Post Run actions/cache`): `2,314` steps, total `66,295s`
    (~28.65s/step).
    
    Run-level framing:
    - Download total was `<=10s` in `288/289` runs (`99.7%`).
    - Upload total was `>=120s` in `285/289` runs (`98.6%`).
    
    The net effect is that release jobs are spending time uploading caches
    that are rarely useful for subsequent runs.
    
    ## What Changed
    
    - Removed the `actions/cache@v5` step from
    `.github/workflows/rust-release.yml`.
    - Removed the `actions/cache@v5` step from
    `.github/workflows/rust-release-windows.yml`.
    - Left build, signing, packaging, and publishing flow unchanged.
    
    ## Validation
    
    - Queried historical `rust-release` run/job step timing and compared
    cache download vs upload for alpha and stable release tags.
    - Spot-checked release logs and observed repeated `Cache not found ...`
    followed by `Cache saved ...` patterns.
  • feat: try to fix bugs I saw in the wild in the resource parsing logic (#11513)
    I gave Codex the following bug report about the logic to report the
    host's resources introduced in
    https://github.com/openai/codex/pull/11488 and this PR is its proposed
    fix.
    
    The fix seems like an escaping issue, mostly.
    
    ---
    
    The logic to print out the runner specs has an awk error on Mac:
    
    ```
    Runner: GitHub Actions 1014936475
    OS: macOS 15.7.3
    Hardware model: VirtualMac2,1
    CPU architecture: arm64
    Logical CPUs: 5
    Physical CPUs: 5
    awk: syntax error at source line 1
     context is
    	{printf >>>  \ <<< "%.1f GiB\\n\", $1 / 1024 / 1024 / 1024}
    awk: illegal statement at source line 1
    Total RAM: 
    Disk usage:
    Filesystem      Size    Used   Avail Capacity iused ifree %iused  Mounted on
    /dev/disk3s5   320Gi   237Gi    64Gi    79%    2.0M  671M    0%   /System/Volumes/Data
    ```
    
    as well as Linux:
    
    ```
    Runner: GitHub Actions 1014936469
    OS: Linux runnervmwffz4 6.11.0-1018-azure #18~24.04.1-Ubuntu SMP Sat Jun 28 04:46:03 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
    awk: cmd. line:1: /Model name/ {gsub(/^[ \t]+/,\"\",$2); print $2; exit}
    awk: cmd. line:1:                              ^ backslash not last character on line
    CPU model: 
    Logical CPUs: 4
    awk: cmd. line:1: /MemTotal/ {printf \"%.1f GiB\\n\", $2 / 1024 / 1024}
    awk: cmd. line:1:                    ^ backslash not last character on line
    Total RAM: 
    Disk usage:
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/root        72G   50G   22G  70% /
    ```
  • feat: build windows support binaries in parallel (#11500)
    Windows release builds were compiling and linking four release binaries
    on a single runner, which slowed the release pipeline. The
    Windows-specific logic also made `rust-release.yml` harder to read and
    maintain.
    
    ## What Changed
    
    - Extracted Windows release logic into a reusable workflow at
    `.github/workflows/rust-release-windows.yml`.
    - Updated `.github/workflows/rust-release.yml` to call the reusable
    Windows workflow via `workflow_call`.
    - Parallelized Windows binary builds with one 4-entry matrix over two
    targets (`x86_64-pc-windows-msvc`, `aarch64-pc-windows-msvc`) and two
    bundles (`primary`, `helpers`).
    - Kept signing centralized per target by downloading both prebuilt
    bundles and signing all four executables together.
    - Preserved final release artifact behavior and filtered intermediate
    `windows-binaries*` artifacts out of the published release asset set.
  • feat: use more powerful machines for building Windows releases (#11488)
    Windows release builds in `.github/workflows/rust-release.yml` were
    still using GitHub-hosted `windows-latest` and `windows-11-arm` runners.
    This change aligns release builds with the faster dedicated Codex runner
    pool already used in CI, and adds machine-spec logging at startup so
    runner capacity (CPU/RAM/disk) is visible in build logs.
    
    ## What Changed
    
    - Updated the `build` job to support matrix entries that provide a full
    `runs_on` object:
      - `runs-on: ${{ matrix.runs_on || matrix.runner }}`
    - Switched Windows release matrix entries to Codex runners:
      - `windows-latest` -> `windows-x64` with:
        - `group: codex-runners`
        - `labels: codex-windows-x64`
      - `windows-11-arm` -> `windows-arm64` with:
        - `group: codex-runners`
        - `labels: codex-windows-arm64`
    - Updated the ARM-specific zstd install condition to match the new
    runner id:
      - `matrix.runner == 'windows-arm64'`
    - Added early platform-specific runner diagnostics steps
    (Linux/macOS/Windows) that print OS, CPU, logical CPU count, total RAM,
    and disk usage.
  • Use thin LTO for alpha Rust release builds (#11348)
    We are looking to speed up build times for alpha releases, but we do not
    want to completely compromise on runtime performance by shipping debug
    builds. This PR changes our CI so that alpha releases build with
    `lto="thin"` instead of `lto="fat"`.
    
    Specifically, this change keeps `[profile.release] lto = "fat"` as the
    default in `Cargo.toml`, but overrides LTO in CI using
    `CARGO_PROFILE_RELEASE_LTO`:
    - `rust-release.yml`: use `thin` for `-alpha` tags, otherwise `fat`
    - `shell-tool-mcp.yml`: use `thin` for `-alpha` versions, otherwise
    `fat`
    
    Tradeoffs:
    - Alpha binaries may be somewhat larger and/or slightly slower than
    fat-LTO builds
    - LTO policy now lives in workflow logic for two pipelines, so
    consistency must be maintained across both files
    
    Note `CARGO_PROFILE_<name>_LTO` is documented on
    https://doc.rust-lang.org/cargo/reference/environment-variables.html#configuration-environment-variables.