name: rust-release-bash on: push: tags: - "codex-bash-v*.*.*" pull_request: paths: - ".github/dotslash-bash-config.json" - ".github/scripts/build-bash-release-artifact.sh" - ".github/scripts/test-shell-exec-wrapper-chain.sh" - ".github/workflows/rust-release-bash.yml" - "codex-rs/shell-escalation/patches/bash-exec-wrapper.patch" env: BASH_COMMIT: a8a1c2fac029404d3f42cd39f5a20f24b6e4fe4b BASH_PATCH: codex-rs/shell-escalation/patches/bash-exec-wrapper.patch ZSH_FORK_RELEASE_TAG: codex-zsh-v0.1.0 concurrency: group: ${{ github.workflow }}::${{ github.ref_name }} cancel-in-progress: false jobs: metadata: runs-on: ubuntu-latest outputs: release_tag: ${{ steps.release_tag.outputs.release_tag }} steps: - name: Validate release tag if: github.event_name == 'push' id: release_tag env: RELEASE_TAG: ${{ github.ref_name }} shell: bash run: | set -euo pipefail if [[ ! "${RELEASE_TAG}" =~ ^codex-bash-v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "Tag ${RELEASE_TAG} does not match codex-bash-vX.Y.Z." >&2 exit 1 fi echo "release_tag=${RELEASE_TAG}" >> "${GITHUB_OUTPUT}" - name: Ensure release does not exist if: github.event_name == 'push' env: GH_TOKEN: ${{ github.token }} RELEASE_TAG: ${{ steps.release_tag.outputs.release_tag }} shell: bash run: | set -euo pipefail if gh release view "${RELEASE_TAG}" --repo "${GITHUB_REPOSITORY}" > /dev/null 2>&1; then echo "Release ${RELEASE_TAG} already exists; publish changed artifacts under a new tag." >&2 exit 1 fi linux: name: Build bash (Linux) - ${{ matrix.variant }} - ${{ matrix.target }} needs: metadata runs-on: ${{ matrix.runner }} timeout-minutes: 30 container: image: ${{ matrix.image }} env: BASH_HOST: ${{ matrix.host }} CC: musl-gcc LDFLAGS: -static strategy: fail-fast: false matrix: include: - runner: ubuntu-24.04 target: x86_64-unknown-linux-musl host: x86_64-linux-musl variant: ubuntu-24.04 image: ubuntu:24.04 archive_name: codex-bash-x86_64-unknown-linux-musl.tar.gz - runner: ubuntu-24.04-arm target: aarch64-unknown-linux-musl host: aarch64-linux-musl variant: ubuntu-24.04 image: arm64v8/ubuntu:24.04 archive_name: codex-bash-aarch64-unknown-linux-musl.tar.gz steps: - name: Install build prerequisites shell: bash run: | set -euo pipefail apt-get update DEBIAN_FRONTEND=noninteractive apt-get install -y \ autoconf \ bison \ binutils \ build-essential \ ca-certificates \ file \ gettext \ git \ musl-tools - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Build, smoke-test, and stage bash artifact shell: bash run: | "${GITHUB_WORKSPACE}/.github/scripts/build-bash-release-artifact.sh" \ "dist/bash/${{ matrix.target }}/${{ matrix.archive_name }}" - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: codex-bash-${{ matrix.target }} path: dist/bash/${{ matrix.target }}/* if-no-files-found: error darwin: name: Build bash (macOS) - ${{ matrix.variant }} - ${{ matrix.target }} needs: metadata runs-on: ${{ matrix.runner }} timeout-minutes: 30 env: MACOSX_DEPLOYMENT_TARGET: "12.0" strategy: fail-fast: false matrix: include: - runner: macos-15-large target: x86_64-apple-darwin variant: macos-15 archive_name: codex-bash-x86_64-apple-darwin.tar.gz - runner: macos-15-xlarge target: aarch64-apple-darwin variant: macos-15 archive_name: codex-bash-aarch64-apple-darwin.tar.gz steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Build, smoke-test, and stage bash artifact shell: bash run: | "${GITHUB_WORKSPACE}/.github/scripts/build-bash-release-artifact.sh" \ "dist/bash/${{ matrix.target }}/${{ matrix.archive_name }}" - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: codex-bash-${{ matrix.target }} path: dist/bash/${{ matrix.target }}/* if-no-files-found: error cross-shell-smoke: name: Smoke test bash and zsh fork chain needs: - linux runs-on: ubuntu-24.04 permissions: contents: read actions: read steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Download bash artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: codex-bash-x86_64-unknown-linux-musl path: dist/bash - name: Download zsh fork artifact env: GH_TOKEN: ${{ github.token }} shell: bash run: | set -euo pipefail mkdir -p dist/zsh gh release download "${ZSH_FORK_RELEASE_TAG}" \ --repo "${GITHUB_REPOSITORY}" \ --pattern codex-zsh-x86_64-unknown-linux-musl.tar.gz \ --dir dist/zsh - name: Test nested shell forks shell: bash run: | set -euo pipefail mkdir -p dist/extracted/bash dist/extracted/zsh tar -xzf dist/bash/codex-bash-x86_64-unknown-linux-musl.tar.gz \ -C dist/extracted/bash tar -xzf dist/zsh/codex-zsh-x86_64-unknown-linux-musl.tar.gz \ -C dist/extracted/zsh .github/scripts/test-shell-exec-wrapper-chain.sh \ dist/extracted/bash/codex-bash/bin/bash \ dist/extracted/zsh/codex-zsh/bin/zsh publish-release: if: github.event_name == 'push' needs: - metadata - linux - darwin - cross-shell-smoke runs-on: ubuntu-latest permissions: contents: write actions: read steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: dist - name: Create GitHub Release uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1 with: tag_name: ${{ needs.metadata.outputs.release_tag }} name: ${{ needs.metadata.outputs.release_tag }} files: dist/** # Keep bash artifact releases out of Codex's normal "latest release" channel. prerelease: true - name: Publish DotSlash manifest uses: facebook/dotslash-publish-release@9c9ec027515c34db9282a09a25a9cab5880b2c52 # v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag: ${{ needs.metadata.outputs.release_tag }} config: .github/dotslash-bash-config.json