feat: reload auth and project instructions dynamically #32
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: | |
| build-unix: | |
| name: Build - ${{ matrix.runner }} - ${{ matrix.target }} | |
| runs-on: ${{ matrix.runner }} | |
| timeout-minutes: 240 | |
| permissions: | |
| contents: read | |
| defaults: | |
| run: | |
| working-directory: codex-rs | |
| env: | |
| CARGO_PROFILE_RELEASE_LTO: thin | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - runner: ubuntu-24.04 | |
| target: x86_64-unknown-linux-musl | |
| - runner: ubuntu-24.04-arm | |
| target: aarch64-unknown-linux-musl | |
| - runner: macos-15-intel | |
| target: x86_64-apple-darwin | |
| - runner: macos-15 | |
| 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: ${{ contains(matrix.target, '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: Cache Cargo home and target dir | |
| if: ${{ contains(matrix.target, 'unknown-linux-musl') }} | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ${{ github.workspace }}/.cargo-home/registry | |
| ${{ github.workspace }}/.cargo-home/git | |
| codex-rs/target | |
| key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('codex-rs/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-${{ matrix.target }}-cargo- | |
| - name: Cache Cargo home and target dir | |
| if: ${{ !contains(matrix.target, 'unknown-linux-musl') }} | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| codex-rs/target | |
| key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('codex-rs/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-${{ matrix.target }}-cargo- | |
| - name: Install Zig | |
| if: ${{ contains(matrix.target, 'unknown-linux-musl') }} | |
| uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 | |
| with: | |
| version: 0.14.0 | |
| - name: Install musl build tools | |
| if: ${{ contains(matrix.target, '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: ${{ contains(matrix.target, '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: ${{ contains(matrix.target, '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: ${{ contains(matrix.target, '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}" | |
| binding_dir="${RUNNER_TEMP}/rusty_v8" | |
| archive_path="${binding_dir}/librusty_v8_release_${TARGET}.a.gz" | |
| binding_path="${binding_dir}/src_binding_release_${TARGET}.rs" | |
| checksums_path="${binding_dir}/rusty_v8_release_${TARGET}.sha256" | |
| checksums_source="${GITHUB_WORKSPACE}/third_party/v8/rusty_v8_${version//./_}.sha256" | |
| mkdir -p "${binding_dir}" | |
| curl -fsSL "${base_url}/librusty_v8_release_${TARGET}.a.gz" -o "${archive_path}" | |
| curl -fsSL "${base_url}/src_binding_release_${TARGET}.rs" -o "${binding_path}" | |
| grep -E " (librusty_v8_release_${TARGET}[.]a[.]gz|src_binding_release_${TARGET}[.]rs)$" \ | |
| "${checksums_source}" > "${checksums_path}" | |
| if [[ "$(wc -l < "${checksums_path}")" -ne 2 ]]; then | |
| echo "Expected exactly two checksums for ${TARGET} in ${checksums_source}" >&2 | |
| exit 1 | |
| fi | |
| (cd "${binding_dir}" && sha256sum -c "${checksums_path}") | |
| echo "RUSTY_V8_ARCHIVE=${archive_path}" >> "$GITHUB_ENV" | |
| echo "RUSTY_V8_SRC_BINDING_PATH=${binding_path}" >> "$GITHUB_ENV" | |
| - name: Cargo build | |
| shell: bash | |
| run: cargo build --locked --target ${{ matrix.target }} --release -p codex-cli --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: | |
| 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: Cache Cargo home and target dir | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| codex-rs/target | |
| key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('codex-rs/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-${{ matrix.target }}-cargo- | |
| - name: Cargo build | |
| shell: bash | |
| run: | | |
| cargo build --locked --target ${{ matrix.target }} --release \ | |
| -p codex-cli \ | |
| -p codex-windows-sandbox \ | |
| --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-release: | |
| needs: | |
| - build-unix | |
| - build-windows | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| 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 "base_version=${base_version}" >> "$GITHUB_OUTPUT" | |
| echo "release_version=${base_version}-${short_sha}" >> "$GITHUB_OUTPUT" | |
| echo "release_tag=codext-v${base_version}-${short_sha}" >> "$GITHUB_OUTPUT" | |
| - name: Generate release notes | |
| id: release_notes | |
| env: | |
| BASE_VERSION: ${{ steps.compute.outputs.base_version }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| notes_path="${RUNNER_TEMP}/release-notes.md" | |
| upstream_tag="rust-v${BASE_VERSION}" | |
| upstream_label="codex-v${BASE_VERSION}" | |
| upstream_url="https://github.com/openai/codex/releases/tag/${upstream_tag}" | |
| { | |
| printf 'For upstream changes, see [%s](%s).\n\n' "${upstream_label}" "${upstream_url}" | |
| git log -1 --format=%B "${GITHUB_SHA}" | |
| echo | |
| } > "${notes_path}" | |
| echo "path=${notes_path}" >> "$GITHUB_OUTPUT" | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: codex-bin-* | |
| path: ${{ runner.temp }}/artifacts | |
| - name: Stage release assets | |
| env: | |
| VERSION: ${{ steps.compute.outputs.release_version }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| artifacts_root="${RUNNER_TEMP}/artifacts" | |
| out_dir="${GITHUB_WORKSPACE}/dist/release" | |
| mkdir -p "${out_dir}" | |
| linux_stage="$(mktemp -d "${RUNNER_TEMP}/release-linux-x64-XXXXXX")" | |
| cp "${artifacts_root}/codex-bin-x86_64-unknown-linux-musl/codex" "${linux_stage}/codext" | |
| chmod +x "${linux_stage}/codext" | |
| tar -C "${linux_stage}" -czf "${out_dir}/codext-linux-x64-${VERSION}.tar.gz" codext | |
| linux_arm64_stage="$(mktemp -d "${RUNNER_TEMP}/release-linux-arm64-XXXXXX")" | |
| cp "${artifacts_root}/codex-bin-aarch64-unknown-linux-musl/codex" "${linux_arm64_stage}/codext" | |
| chmod +x "${linux_arm64_stage}/codext" | |
| tar -C "${linux_arm64_stage}" -czf "${out_dir}/codext-linux-arm64-${VERSION}.tar.gz" codext | |
| darwin_x64_stage="$(mktemp -d "${RUNNER_TEMP}/release-darwin-x64-XXXXXX")" | |
| cp "${artifacts_root}/codex-bin-x86_64-apple-darwin/codex" "${darwin_x64_stage}/codext" | |
| chmod +x "${darwin_x64_stage}/codext" | |
| tar -C "${darwin_x64_stage}" -czf "${out_dir}/codext-darwin-x64-${VERSION}.tar.gz" codext | |
| darwin_arm64_stage="$(mktemp -d "${RUNNER_TEMP}/release-darwin-arm64-XXXXXX")" | |
| cp "${artifacts_root}/codex-bin-aarch64-apple-darwin/codex" "${darwin_arm64_stage}/codext" | |
| chmod +x "${darwin_arm64_stage}/codext" | |
| tar -C "${darwin_arm64_stage}" -czf "${out_dir}/codext-darwin-arm64-${VERSION}.tar.gz" codext | |
| windows_stage="$(mktemp -d "${RUNNER_TEMP}/release-win32-x64-XXXXXX")" | |
| cp "${artifacts_root}/codex-bin-x86_64-pc-windows-msvc/codex.exe" "${windows_stage}/codext.exe" | |
| cp "${artifacts_root}/codex-bin-x86_64-pc-windows-msvc/codex-windows-sandbox-setup.exe" "${windows_stage}/codex-windows-sandbox-setup.exe" | |
| cp "${artifacts_root}/codex-bin-x86_64-pc-windows-msvc/codex-command-runner.exe" "${windows_stage}/codex-command-runner.exe" | |
| ( | |
| cd "${windows_stage}" | |
| zip -q -r "${out_dir}/codext-win32-x64-${VERSION}.zip" . | |
| ) | |
| - name: Create or update GitHub Release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE_NAME: ${{ steps.compute.outputs.release_version }} | |
| RELEASE_TAG: ${{ steps.compute.outputs.release_tag }} | |
| RELEASE_NOTES: ${{ steps.release_notes.outputs.path }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if gh release view "${RELEASE_TAG}" --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then | |
| gh release edit "${RELEASE_TAG}" \ | |
| --repo "${GITHUB_REPOSITORY}" \ | |
| --title "codext ${RELEASE_NAME}" \ | |
| --notes-file "${RELEASE_NOTES}" \ | |
| --latest | |
| else | |
| gh release create "${RELEASE_TAG}" \ | |
| --repo "${GITHUB_REPOSITORY}" \ | |
| --title "codext ${RELEASE_NAME}" \ | |
| --notes-file "${RELEASE_NOTES}" \ | |
| --target "${GITHUB_SHA}" \ | |
| --latest | |
| fi | |
| gh release upload "${RELEASE_TAG}" dist/release/* \ | |
| --repo "${GITHUB_REPOSITORY}" \ | |
| --clobber | |
| publish-npm: | |
| needs: | |
| - build-unix | |
| - build-windows | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| contents: read | |
| 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" | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| # Node 24 bundles npm >= 11.5.1, which trusted publishing requires. | |
| node-version: 24 | |
| registry-url: https://registry.npmjs.org | |
| - 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}/aarch64-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-aarch64-unknown-linux-musl/codex" \ | |
| "${vendor_root}/aarch64-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: ${{ steps.compute.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-linux-arm64 | |
| 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: ${{ steps.compute.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 |