ci: build Codex package archives in release workflow (#23582)

## Why

Release CI already builds the Codex entrypoints before staging
artifacts, and the package builder can now package those prebuilt
binaries directly. The workflow should produce package-shaped sidecar
archives from the same staged entrypoints that downstream distribution
channels will eventually consume, without rebuilding `codex` or
`codex-app-server` inside the packaging step.

This intentionally does **not** publish the new package archives as
GitHub Release assets yet. The archives are kept with workflow artifacts
until npm, Homebrew, `install.sh`, winget, and related consumers are
ready to switch over.

## What changed

- Adds a `Build Codex package archive` step to
`.github/workflows/rust-release.yml` after target artifacts are staged.
- Runs `scripts/build_codex_package.py` for both release bundles:
- `primary` builds `codex-package-${TARGET}.tar.gz` with `--variant
codex`.
- `app-server` builds `codex-app-server-package-${TARGET}.tar.gz` with
`--variant codex-app-server`.
- Passes `--entrypoint-bin target/${TARGET}/release/<entrypoint>` so
packages contain the entrypoint already built by the workflow.
- Deletes both package archive names before the final GitHub Release
upload so they remain workflow artifacts only for now.

## Verification

- Parsed `.github/workflows/rust-release.yml` with Ruby's YAML loader.








---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/23582).
* #23596
* __->__ #23582
This commit is contained in:
Michael Bolin
2026-05-19 22:43:53 -07:00
committed by GitHub
Unverified
parent 343a74076f
commit 57a68fb9e3
3 changed files with 157 additions and 0 deletions
@@ -0,0 +1,112 @@
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'EOF'
Usage: build-codex-package-archive.sh \
--target <rust-target> \
--bundle <primary|app-server> \
--entrypoint-dir <dir> \
--archive-dir <dir> \
[--target-suffixed-entrypoint]
EOF
}
target=""
bundle=""
entrypoint_dir=""
archive_dir=""
target_suffixed_entrypoint="false"
while [[ $# -gt 0 ]]; do
case "$1" in
--target)
target="${2:?--target requires a value}"
shift 2
;;
--bundle)
bundle="${2:?--bundle requires a value}"
shift 2
;;
--entrypoint-dir)
entrypoint_dir="${2:?--entrypoint-dir requires a value}"
shift 2
;;
--archive-dir)
archive_dir="${2:?--archive-dir requires a value}"
shift 2
;;
--target-suffixed-entrypoint)
target_suffixed_entrypoint="true"
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unexpected argument: $1" >&2
usage >&2
exit 1
;;
esac
done
if [[ -z "$target" || -z "$bundle" || -z "$entrypoint_dir" || -z "$archive_dir" ]]; then
usage >&2
exit 1
fi
case "$bundle" in
primary)
variant="codex"
entrypoint="codex"
archive_stem="codex-package"
;;
app-server)
variant="codex-app-server"
entrypoint="codex-app-server"
archive_stem="codex-app-server-package"
;;
*)
echo "No Codex package variant for bundle: $bundle" >&2
exit 1
;;
esac
exe_suffix=""
case "$target" in
*windows*)
exe_suffix=".exe"
;;
esac
entrypoint_name="$entrypoint"
if [[ "$target_suffixed_entrypoint" == "true" ]]; then
entrypoint_name="${entrypoint_name}-${target}"
fi
repo_root="${GITHUB_WORKSPACE:-}"
if [[ -z "$repo_root" ]]; then
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
fi
if command -v python3 >/dev/null 2>&1; then
python_bin="python3"
else
python_bin="python"
fi
mkdir -p "$archive_dir"
package_dir="${RUNNER_TEMP:-/tmp}/${archive_stem}-${target}"
archive_path="${archive_dir}/${archive_stem}-${target}.tar.gz"
rm -rf "$package_dir"
"$python_bin" "${repo_root}/scripts/build_codex_package.py" \
--target "$target" \
--variant "$variant" \
--entrypoint-bin "${entrypoint_dir%/}/${entrypoint_name}${exe_suffix}" \
--cargo-profile release \
--package-dir "$package_dir" \
--archive-output "$archive_path" \
--force
@@ -220,6 +220,18 @@ jobs:
"$dest/${binary}-${{ matrix.target }}.exe"
done
- name: Build Codex package archives
shell: bash
run: |
set -euo pipefail
for bundle in primary app-server; do
bash "${GITHUB_WORKSPACE}/.github/scripts/build-codex-package-archive.sh" \
--target "${{ matrix.target }}" \
--bundle "$bundle" \
--entrypoint-dir "target/${{ matrix.target }}/release" \
--archive-dir "dist/${{ matrix.target }}"
done
- name: Build Python runtime wheel
shell: bash
run: |
+33
View File
@@ -519,6 +519,20 @@ jobs:
cp target/${{ matrix.target }}/release/codex-${{ matrix.target }}.dmg "$dest/codex-${{ matrix.target }}.dmg"
fi
- name: Build Codex package archive
if: ${{ runner.os != 'macOS' || env.SIGN_MACOS == 'true' }}
shell: bash
env:
TARGET: ${{ matrix.target }}
BUNDLE: ${{ matrix.bundle }}
run: |
set -euo pipefail
bash "${GITHUB_WORKSPACE}/.github/scripts/build-codex-package-archive.sh" \
--target "$TARGET" \
--bundle "$BUNDLE" \
--entrypoint-dir "target/${TARGET}/release" \
--archive-dir "dist/${TARGET}"
- name: Build Python runtime wheel
if: ${{ matrix.bundle == 'primary' && (runner.os != 'macOS' || env.SIGN_MACOS == 'true') }}
shell: bash
@@ -819,6 +833,20 @@ jobs:
--platform-tag "$platform_tag"
"${RUNNER_TEMP}/python-runtime-build-venv/bin/python" -m build --wheel --outdir "$wheel_dir" "$stage_dir"
- name: Build Codex package archive
shell: bash
env:
TARGET: ${{ matrix.target }}
BUNDLE: ${{ matrix.bundle }}
run: |
set -euo pipefail
bash "${GITHUB_WORKSPACE}/.github/scripts/build-codex-package-archive.sh" \
--target "$TARGET" \
--bundle "$BUNDLE" \
--entrypoint-dir "dist/${TARGET}" \
--archive-dir "dist/${TARGET}" \
--target-suffixed-entrypoint
- name: Upload Python runtime wheel
if: ${{ matrix.bundle == 'primary' }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
@@ -1079,6 +1107,11 @@ jobs:
# If included in files: dist/**, release upload races on duplicate
# asset names and can fail with 404s.
find dist -type f -name 'cargo-timing.html' -delete
# Keep package-builder sidecar archives as workflow artifacts only
# until distribution channels are ready to consume them.
find dist -type f \
\( -name 'codex-package-*' -o -name 'codex-app-server-package-*' \) \
-delete
find dist -type d -empty -delete
ls -R dist/