rust-release #11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: rust-release | |
| on: | |
| push: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }} | |
| cancel-in-progress: true | |
| jobs: | |
| metadata: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| release_version: ${{ steps.compute.outputs.release_version }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Compute release version | |
| id: compute | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| base_version="$(grep -m1 '^version' codex-rs/Cargo.toml | sed -E 's/version *= *"([^"]+)".*/\1/')" | |
| short_sha="${GITHUB_SHA::7}" | |
| echo "release_version=${base_version}-${short_sha}" >> "$GITHUB_OUTPUT" | |
| build-unix: | |
| needs: metadata | |
| name: Build - ${{ matrix.runner }} - ${{ matrix.target }} | |
| runs-on: ${{ matrix.runner }} | |
| timeout-minutes: 120 | |
| permissions: | |
| contents: read | |
| defaults: | |
| run: | |
| working-directory: codex-rs | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - runner: ubuntu-24.04 | |
| target: x86_64-unknown-linux-musl | |
| - runner: macos-15-xlarge | |
| target: x86_64-apple-darwin | |
| - runner: macos-15-xlarge | |
| target: aarch64-apple-darwin | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Install Linux build dependencies | |
| if: ${{ runner.os == 'Linux' }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| sudo apt-get update -y | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev libubsan1 | |
| - uses: dtolnay/rust-toolchain@1.93.0 | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Use hermetic Cargo home | |
| if: ${{ matrix.target == 'x86_64-unknown-linux-musl' }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| cargo_home="${GITHUB_WORKSPACE}/.cargo-home" | |
| mkdir -p "${cargo_home}/bin" | |
| echo "CARGO_HOME=${cargo_home}" >> "$GITHUB_ENV" | |
| echo "${cargo_home}/bin" >> "$GITHUB_PATH" | |
| : > "${cargo_home}/config.toml" | |
| - name: Install Zig | |
| if: ${{ matrix.target == 'x86_64-unknown-linux-musl' }} | |
| uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 | |
| with: | |
| version: 0.14.0 | |
| - name: Install musl build tools | |
| if: ${{ matrix.target == 'x86_64-unknown-linux-musl' }} | |
| env: | |
| TARGET: ${{ matrix.target }} | |
| shell: bash | |
| run: bash "${GITHUB_WORKSPACE}/.github/scripts/install-musl-build-tools.sh" | |
| - name: Configure rustc UBSan wrapper | |
| if: ${{ matrix.target == 'x86_64-unknown-linux-musl' }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| ubsan="" | |
| if command -v ldconfig >/dev/null 2>&1; then | |
| ubsan="$(ldconfig -p | grep -m1 'libubsan\.so\.1' | sed -E 's/.*=> (.*)$/\1/')" | |
| fi | |
| wrapper_root="${RUNNER_TEMP:-/tmp}" | |
| wrapper="${wrapper_root}/rustc-ubsan-wrapper" | |
| cat > "${wrapper}" <<EOF | |
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| if [[ -n "${ubsan}" ]]; then | |
| export LD_PRELOAD="${ubsan}\${LD_PRELOAD:+:\${LD_PRELOAD}}" | |
| fi | |
| exec "\$1" "\${@:2}" | |
| EOF | |
| chmod +x "${wrapper}" | |
| echo "RUSTC_WRAPPER=${wrapper}" >> "$GITHUB_ENV" | |
| echo "RUSTC_WORKSPACE_WRAPPER=" >> "$GITHUB_ENV" | |
| - name: Clear sanitizer flags | |
| if: ${{ matrix.target == 'x86_64-unknown-linux-musl' }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| echo "AWS_LC_SYS_NO_JITTER_ENTROPY=1" >> "$GITHUB_ENV" | |
| target_no_jitter="AWS_LC_SYS_NO_JITTER_ENTROPY_${{ matrix.target }}" | |
| target_no_jitter="${target_no_jitter//-/_}" | |
| echo "${target_no_jitter}=1" >> "$GITHUB_ENV" | |
| echo "RUSTFLAGS=" >> "$GITHUB_ENV" | |
| echo "CARGO_ENCODED_RUSTFLAGS=" >> "$GITHUB_ENV" | |
| echo "RUSTDOCFLAGS=" >> "$GITHUB_ENV" | |
| echo "CARGO_BUILD_RUSTFLAGS=" >> "$GITHUB_ENV" | |
| echo "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS=" >> "$GITHUB_ENV" | |
| echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS=" >> "$GITHUB_ENV" | |
| echo "CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS=" >> "$GITHUB_ENV" | |
| echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUSTFLAGS=" >> "$GITHUB_ENV" | |
| - name: Configure musl rusty_v8 artifact overrides | |
| if: ${{ matrix.target == 'x86_64-unknown-linux-musl' }} | |
| env: | |
| TARGET: ${{ matrix.target }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| version="$(python3 "${GITHUB_WORKSPACE}/.github/scripts/rusty_v8_bazel.py" resolved-v8-crate-version)" | |
| release_tag="rusty-v8-v${version}" | |
| base_url="https://github.com/openai/codex/releases/download/${release_tag}" | |
| archive="${base_url}/librusty_v8_release_${TARGET}.a.gz" | |
| binding_dir="${RUNNER_TEMP}/rusty_v8" | |
| binding_path="${binding_dir}/src_binding_release_${TARGET}.rs" | |
| mkdir -p "${binding_dir}" | |
| curl -fsSL "${base_url}/src_binding_release_${TARGET}.rs" -o "${binding_path}" | |
| echo "RUSTY_V8_ARCHIVE=${archive}" >> "$GITHUB_ENV" | |
| echo "RUSTY_V8_SRC_BINDING_PATH=${binding_path}" >> "$GITHUB_ENV" | |
| - name: Cargo build | |
| shell: bash | |
| run: cargo build --target ${{ matrix.target }} --release --bin codex | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: codex-bin-${{ matrix.target }} | |
| path: codex-rs/target/${{ matrix.target }}/release/codex | |
| if-no-files-found: error | |
| build-windows: | |
| needs: metadata | |
| name: Build - windows-2025 - ${{ matrix.target }} | |
| runs-on: windows-2025 | |
| timeout-minutes: 90 | |
| permissions: | |
| contents: read | |
| defaults: | |
| run: | |
| working-directory: codex-rs | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: | |
| - x86_64-pc-windows-msvc | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dtolnay/rust-toolchain@1.93.0 | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Cargo build | |
| shell: bash | |
| run: | | |
| cargo build --target ${{ matrix.target }} --release \ | |
| --bin codex \ | |
| --bin codex-windows-sandbox-setup \ | |
| --bin codex-command-runner | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: codex-bin-${{ matrix.target }} | |
| path: | | |
| codex-rs/target/${{ matrix.target }}/release/codex.exe | |
| codex-rs/target/${{ matrix.target }}/release/codex-windows-sandbox-setup.exe | |
| codex-rs/target/${{ matrix.target }}/release/codex-command-runner.exe | |
| if-no-files-found: error | |
| publish-npm: | |
| needs: | |
| - metadata | |
| - build-unix | |
| - build-windows | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 22 | |
| registry-url: https://registry.npmjs.org | |
| - name: Update npm | |
| run: npm install -g npm@latest | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: codex-bin-* | |
| path: ${{ runner.temp }}/artifacts | |
| - name: Assemble vendor tree | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| artifacts_root="${RUNNER_TEMP}/artifacts" | |
| vendor_root="${RUNNER_TEMP}/npm-root/vendor" | |
| mkdir -p \ | |
| "${vendor_root}/x86_64-unknown-linux-musl/codex" \ | |
| "${vendor_root}/x86_64-apple-darwin/codex" \ | |
| "${vendor_root}/aarch64-apple-darwin/codex" \ | |
| "${vendor_root}/x86_64-pc-windows-msvc/codex" | |
| cp "${artifacts_root}/codex-bin-x86_64-unknown-linux-musl/codex" \ | |
| "${vendor_root}/x86_64-unknown-linux-musl/codex/codex" | |
| cp "${artifacts_root}/codex-bin-x86_64-apple-darwin/codex" \ | |
| "${vendor_root}/x86_64-apple-darwin/codex/codex" | |
| cp "${artifacts_root}/codex-bin-aarch64-apple-darwin/codex" \ | |
| "${vendor_root}/aarch64-apple-darwin/codex/codex" | |
| cp "${artifacts_root}/codex-bin-x86_64-pc-windows-msvc/codex.exe" \ | |
| "${vendor_root}/x86_64-pc-windows-msvc/codex/codex.exe" | |
| cp "${artifacts_root}/codex-bin-x86_64-pc-windows-msvc/codex-windows-sandbox-setup.exe" \ | |
| "${vendor_root}/x86_64-pc-windows-msvc/codex/codex-windows-sandbox-setup.exe" | |
| cp "${artifacts_root}/codex-bin-x86_64-pc-windows-msvc/codex-command-runner.exe" \ | |
| "${vendor_root}/x86_64-pc-windows-msvc/codex/codex-command-runner.exe" | |
| - uses: facebook/install-dotslash@v2 | |
| - name: Install ripgrep payloads | |
| run: python3 codex-cli/scripts/install_native_deps.py --component rg "${RUNNER_TEMP}/npm-root" | |
| - name: Stage npm tarballs | |
| env: | |
| VERSION: ${{ needs.metadata.outputs.release_version }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| out_dir="${GITHUB_WORKSPACE}/dist/npm" | |
| mkdir -p "${out_dir}" | |
| vendor_src="${RUNNER_TEMP}/npm-root/vendor" | |
| packages=( | |
| codex | |
| codex-linux-x64 | |
| codex-darwin-x64 | |
| codex-darwin-arm64 | |
| codex-win32-x64 | |
| ) | |
| for package in "${packages[@]}"; do | |
| stage_dir="$(mktemp -d "${RUNNER_TEMP}/npm-stage-${package}-XXXXXX")" | |
| if [[ "${package}" == "codex" ]]; then | |
| pack_output="${out_dir}/codex-npm-${VERSION}.tgz" | |
| python3 codex-cli/scripts/build_npm_package.py \ | |
| --package "${package}" \ | |
| --release-version "${VERSION}" \ | |
| --staging-dir "${stage_dir}" \ | |
| --pack-output "${pack_output}" | |
| else | |
| platform="${package#codex-}" | |
| pack_output="${out_dir}/codex-npm-${platform}-${VERSION}.tgz" | |
| python3 codex-cli/scripts/build_npm_package.py \ | |
| --package "${package}" \ | |
| --release-version "${VERSION}" \ | |
| --staging-dir "${stage_dir}" \ | |
| --pack-output "${pack_output}" \ | |
| --vendor-src "${vendor_src}" | |
| fi | |
| rm -rf "${stage_dir}" | |
| done | |
| - name: Publish to npm | |
| env: | |
| VERSION: ${{ needs.metadata.outputs.release_version }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| shopt -s nullglob | |
| tarballs=(dist/npm/*-"${VERSION}".tgz) | |
| if [[ ${#tarballs[@]} -eq 0 ]]; then | |
| echo "No npm tarballs found in dist/npm for version ${VERSION}" | |
| exit 1 | |
| fi | |
| for tarball in "${tarballs[@]}"; do | |
| filename="$(basename "${tarball}")" | |
| publish_cmd=(npm publish "${GITHUB_WORKSPACE}/${tarball}" --access public) | |
| tag="" | |
| case "${filename}" in | |
| codex-npm-linux-*-"${VERSION}".tgz) | |
| tag="${filename#codex-npm-}" | |
| tag="${tag%-${VERSION}.tgz}" | |
| ;; | |
| codex-npm-darwin-*-"${VERSION}".tgz) | |
| tag="${filename#codex-npm-}" | |
| tag="${tag%-${VERSION}.tgz}" | |
| ;; | |
| codex-npm-win32-*-"${VERSION}".tgz) | |
| tag="${filename#codex-npm-}" | |
| tag="${tag%-${VERSION}.tgz}" | |
| ;; | |
| codex-npm-"${VERSION}".tgz) | |
| tag="latest" | |
| ;; | |
| *) | |
| echo "Unexpected npm tarball: ${filename}" | |
| exit 1 | |
| ;; | |
| esac | |
| if [[ -n "${tag}" ]]; then | |
| publish_cmd+=(--tag "${tag}") | |
| fi | |
| echo "+ ${publish_cmd[*]}" | |
| set +e | |
| publish_output="$("${publish_cmd[@]}" 2>&1)" | |
| publish_status=$? | |
| set -e | |
| echo "${publish_output}" | |
| if [[ ${publish_status} -eq 0 ]]; then | |
| continue | |
| fi | |
| if grep -qiE "previously published|cannot publish over|version already exists" <<< "${publish_output}"; then | |
| echo "Skipping already-published package version for ${filename}" | |
| continue | |
| fi | |
| exit "${publish_status}" | |
| done |