From 3f01f56b4d647220cde8f922f10b2e1294e2a0d7 Mon Sep 17 00:00:00 2001 From: theDancingDeveloper Date: Fri, 9 Oct 2026 09:44:34 +0000 Subject: [PATCH 1/3] Add the fork musl release workflow Builds static x86_64 and aarch64 musl binaries on ubuntu-24.04 and ubuntu-24.04-arm, reusing the upstream musl setup (zig 0.14.0, install-musl-build-tools.sh, setup-rusty-v8, AWS_LC_SYS_NO_JITTER_ENTROPY). bwrap is built and stripped first and its digest exported as CODEX_BWRAP_SHA256, which linux-sandbox embeds and verifies. The workspace version 0.0.0 is stamped +fork. so codex --version reports the fork. Publishes a GitHub release tagged with the full commit SHA plus SHA256SUMS. Every action is pinned to a full commit SHA verified to exist. New file with a fork-unique name; no upstream workflow is edited. --- .github/workflows/fork-release.yml | 155 +++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 .github/workflows/fork-release.yml diff --git a/.github/workflows/fork-release.yml b/.github/workflows/fork-release.yml new file mode 100644 index 000000000000..970274ffe31a --- /dev/null +++ b/.github/workflows/fork-release.yml @@ -0,0 +1,155 @@ +# Fork-only release workflow. Builds static musl binaries of the fork and +# publishes a GitHub release tagged with the full fork commit SHA, which is +# how the Vogt engine installs the fork (WI-1142). +# +# New file with a fork-unique name on purpose: upstream workflow files are +# never edited here, so rebasing onto upstream stays conflict-free. +name: fork-release + +on: + push: + branches: [fork/main] + workflow_dispatch: + +permissions: + contents: write + +env: + # aws-lc's jitter entropy path does not build on musl. + AWS_LC_SYS_NO_JITTER_ENTROPY: "1" + +jobs: + build: + name: ${{ matrix.target }} + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - target: x86_64-unknown-linux-musl + runner: ubuntu-24.04 + - target: aarch64-unknown-linux-musl + runner: ubuntu-24.04-arm + steps: + - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.0.1 + with: + persist-credentials: false + + # Reuses the upstream musl setup verbatim: zig 0.14.0 as the C toolchain, + # then .github/scripts/install-musl-build-tools.sh (musl gcc linker, + # libcap built for the target, OpenSSL). + - name: Install Zig + uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 + with: + version: "0.14.0" + use-cache: false + + - name: Install musl build tools + env: + TARGET: ${{ matrix.target }} + run: bash "${GITHUB_WORKSPACE}/.github/scripts/install-musl-build-tools.sh" + + - name: Set up Rust toolchain + uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0 + with: + targets: ${{ matrix.target }} + + # Downloads the Codex-built rusty_v8 prebuilts from the upstream release + # and verifies them against the in-tree checksum manifest. + - name: Configure rusty_v8 artifact overrides and verify checksums + uses: ./.github/actions/setup-rusty-v8 + with: + target: ${{ matrix.target }} + + # bwrap is built and stripped first: linux-sandbox embeds + # option_env!("CODEX_BWRAP_SHA256") and verifies the bundled bwrap + # against it, so the digest must be exported before the codex build. + - name: Build bwrap and export digest + shell: bash + run: | + set -euo pipefail + target="${{ matrix.target }}" + cargo build --target "$target" --release --bin bwrap + bwrap_path="target/${target}/release/bwrap" + strip --strip-debug --strip-unneeded "$bwrap_path" + digest="$(sha256sum "$bwrap_path" | awk '{print $1}')" + echo "CODEX_BWRAP_SHA256=${digest}" >> "$GITHUB_ENV" + + # The workspace version is 0.0.0; stamp it as +fork. + # so `codex --version` reports the fork. Cargo bakes the version in via + # CARGO_PKG_VERSION, which clap's `version` attribute prints. + - name: Stamp fork version + shell: bash + run: | + set -euo pipefail + # The fork base is the upstream stable tag; recorded in FORK.md and + # advanced by the rebase procedure. `git describe` cannot be used: + # upstream tags are not fetched into this checkout. + upstream_version="0.162.0" + stamp="${upstream_version}+fork.${GITHUB_SHA:0:9}" + sed -i "0,/^version = \"0.0.0\"/s//version = \"${stamp}\"/" codex-rs/Cargo.toml + grep -m1 '^version' codex-rs/Cargo.toml + + - name: Build release binaries + shell: bash + run: | + set -euo pipefail + target="${{ matrix.target }}" + cargo build --target "$target" --release --bin codex --bin codex-code-mode-host + for bin in codex codex-code-mode-host bwrap; do + strip --strip-debug --strip-unneeded "target/${target}/release/${bin}" + done + + - name: Package + shell: bash + run: | + set -euo pipefail + target="${{ matrix.target }}" + stage="dist/${target}" + mkdir -p "$stage" + for bin in codex codex-code-mode-host bwrap; do + cp "target/${target}/release/${bin}" "$stage/${bin}" + done + (cd dist && sha256sum "${target}/codex" "${target}/codex-code-mode-host" "${target}/bwrap") > "dist/SHA256SUMS-${target}" + tar -C dist -czf "dist/codex-${target}.tar.gz" "${target}" + + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: ${{ matrix.target }} + path: | + dist/codex-${{ matrix.target }}.tar.gz + dist/SHA256SUMS-${{ matrix.target }} + + release: + name: publish + needs: build + runs-on: ubuntu-24.04 + steps: + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + path: release + merge-multiple: true + + - name: Assemble checksums + shell: bash + run: | + set -euo pipefail + cat release/SHA256SUMS-* | sort > release/SHA256SUMS + rm release/SHA256SUMS-* + + # The release tag is the full fork commit SHA, so the Vogt engine can + # install exactly the commit it pins. + - name: Publish GitHub release + env: + GH_TOKEN: ${{ github.token }} + shell: bash + run: | + set -euo pipefail + if gh release view "$GITHUB_SHA" >/dev/null 2>&1; then + echo "release ${GITHUB_SHA} already exists" + exit 0 + fi + gh release create "$GITHUB_SHA" release/* \ + --target "$GITHUB_SHA" \ + --title "fork ${GITHUB_SHA:0:9}" \ + --notes "Fork build of ${GITHUB_SHA}. Static musl binaries for x86_64 and aarch64; verify with SHA256SUMS." From 48e39fc74ff0ae83c84f96e6b0346047fc325ab8 Mon Sep 17 00:00:00 2001 From: theDancingDeveloper Date: Fri, 9 Oct 2026 09:52:49 +0000 Subject: [PATCH 2/3] Address the release workflow review - contents: read at the top level, contents: write only on the release job. - bwrap is no longer stripped a second time after hashing, which would change the bytes CODEX_BWRAP_SHA256 covers. The package step asserts the shipped bwrap's sha256 equals the embedded digest and fails the build otherwise. - The release step sets GH_REPO to github.repository so gh cannot fall back to the upstream repository. --- .github/workflows/fork-release.yml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/workflows/fork-release.yml b/.github/workflows/fork-release.yml index 970274ffe31a..5486657f15d3 100644 --- a/.github/workflows/fork-release.yml +++ b/.github/workflows/fork-release.yml @@ -12,7 +12,7 @@ on: workflow_dispatch: permissions: - contents: write + contents: read env: # aws-lc's jitter entropy path does not build on musl. @@ -96,9 +96,12 @@ jobs: set -euo pipefail target="${{ matrix.target }}" cargo build --target "$target" --release --bin codex --bin codex-code-mode-host - for bin in codex codex-code-mode-host bwrap; do + for bin in codex codex-code-mode-host; do strip --strip-debug --strip-unneeded "target/${target}/release/${bin}" done + # bwrap was stripped before hashing so CODEX_BWRAP_SHA256 covers the + # exact bytes shipped. Stripping it again would change those bytes + # and invalidate the digest the codex binary embeds. - name: Package shell: bash @@ -111,6 +114,13 @@ jobs: cp "target/${target}/release/${bin}" "$stage/${bin}" done (cd dist && sha256sum "${target}/codex" "${target}/codex-code-mode-host" "${target}/bwrap") > "dist/SHA256SUMS-${target}" + # The shipped bwrap must be byte-for-byte the one whose digest was + # embedded into the codex binary. + shipped="$(sha256sum "dist/${target}/bwrap" | awk '{print $1}')" + if [[ "$shipped" != "$CODEX_BWRAP_SHA256" ]]; then + echo "shipped bwrap ${shipped} != embedded CODEX_BWRAP_SHA256 ${CODEX_BWRAP_SHA256}" >&2 + exit 1 + fi tar -C dist -czf "dist/codex-${target}.tar.gz" "${target}" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 @@ -124,6 +134,8 @@ jobs: name: publish needs: build runs-on: ubuntu-24.04 + permissions: + contents: write steps: - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: @@ -142,6 +154,7 @@ jobs: - name: Publish GitHub release env: GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} shell: bash run: | set -euo pipefail From 4893226614e72752c5867a079148f1df717ef194 Mon Sep 17 00:00:00 2001 From: theDancingDeveloper Date: Fri, 9 Oct 2026 09:54:53 +0000 Subject: [PATCH 3/3] Run the build in the codex-rs workspace The repo root has no Cargo.toml, so every cargo build failed. The build job now defaults its run steps to codex-rs/, the version stamp edits Cargo.toml there, and the artifact paths are prefixed codex-rs/ because actions do not honour defaults.run. The musl build-tools step stays at the repo root: its script and setup-rusty-v8 write under GITHUB_WORKSPACE. --- .github/workflows/fork-release.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/fork-release.yml b/.github/workflows/fork-release.yml index 5486657f15d3..c000f25d3131 100644 --- a/.github/workflows/fork-release.yml +++ b/.github/workflows/fork-release.yml @@ -30,6 +30,10 @@ jobs: runner: ubuntu-24.04 - target: aarch64-unknown-linux-musl runner: ubuntu-24.04-arm + # The workspace Cargo.toml is codex-rs/Cargo.toml; the repo root has none. + defaults: + run: + working-directory: codex-rs steps: - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.0.1 with: @@ -45,6 +49,7 @@ jobs: use-cache: false - name: Install musl build tools + working-directory: ${{ github.workspace }} env: TARGET: ${{ matrix.target }} run: bash "${GITHUB_WORKSPACE}/.github/scripts/install-musl-build-tools.sh" @@ -87,8 +92,8 @@ jobs: # upstream tags are not fetched into this checkout. upstream_version="0.162.0" stamp="${upstream_version}+fork.${GITHUB_SHA:0:9}" - sed -i "0,/^version = \"0.0.0\"/s//version = \"${stamp}\"/" codex-rs/Cargo.toml - grep -m1 '^version' codex-rs/Cargo.toml + sed -i "0,/^version = \"0.0.0\"/s//version = \"${stamp}\"/" Cargo.toml + grep -m1 '^version' Cargo.toml - name: Build release binaries shell: bash @@ -127,8 +132,8 @@ jobs: with: name: ${{ matrix.target }} path: | - dist/codex-${{ matrix.target }}.tar.gz - dist/SHA256SUMS-${{ matrix.target }} + codex-rs/dist/codex-${{ matrix.target }}.tar.gz + codex-rs/dist/SHA256SUMS-${{ matrix.target }} release: name: publish