diff --git a/.github/scripts/build-codex-package-archive.sh b/.github/scripts/build-codex-package-archive.sh
index 80da4cf20..229213cc5 100644
--- a/.github/scripts/build-codex-package-archive.sh
+++ b/.github/scripts/build-codex-package-archive.sh
@@ -9,6 +9,7 @@ Usage: build-codex-package-archive.sh \
--entrypoint-dir
\
--archive-dir \
[--bwrap-bin ] \
+ [--zsh-manifest ] \
[--codex-command-runner-bin ] \
[--codex-windows-sandbox-setup-bin ] \
[--target-suffixed-entrypoint]
@@ -48,6 +49,10 @@ while [[ $# -gt 0 ]]; do
bwrap_bin_provided="true"
shift 2
;;
+ --zsh-manifest)
+ resource_args+=(--zsh-manifest "${2:?--zsh-manifest requires a value}")
+ shift 2
+ ;;
--codex-command-runner-bin)
resource_args+=(
--codex-command-runner-bin
diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml
index a2646e3ea..49d24abc1 100644
--- a/.github/workflows/rust-release.yml
+++ b/.github/workflows/rust-release.yml
@@ -14,6 +14,9 @@ on:
tags:
- "rust-v*.*.*"
+env:
+ CODEX_ZSH_RELEASE_TAG: codex-zsh-v0.1.0
+
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
@@ -354,6 +357,15 @@ jobs:
cp target/${{ matrix.target }}/release/codex-${{ matrix.target }}.dmg "$dest/codex-${{ matrix.target }}.dmg"
fi
+ - name: Download packaged zsh manifest
+ if: ${{ runner.os != 'macOS' }}
+ shell: bash
+ run: |
+ set -euo pipefail
+ curl -fsSL \
+ "https://github.com/${GITHUB_REPOSITORY}/releases/download/${CODEX_ZSH_RELEASE_TAG}/codex-zsh" \
+ -o "${RUNNER_TEMP}/codex-zsh"
+
- name: Build Codex package archive
if: ${{ runner.os != 'macOS' }}
shell: bash
@@ -366,7 +378,8 @@ jobs:
--target "$TARGET" \
--bundle "$BUNDLE" \
--entrypoint-dir "target/${TARGET}/release" \
- --archive-dir "dist/${TARGET}"
+ --archive-dir "dist/${TARGET}" \
+ --zsh-manifest "${RUNNER_TEMP}/codex-zsh"
- name: Build Python runtime wheel
if: ${{ matrix.bundle == 'primary' && runner.os != 'macOS' }}
@@ -697,6 +710,14 @@ jobs:
cp "target/${{ matrix.target }}/release/${binary}" "$dest/${binary}-${{ matrix.target }}"
done
+ - name: Download packaged zsh manifest
+ shell: bash
+ run: |
+ set -euo pipefail
+ curl -fsSL \
+ "https://github.com/${GITHUB_REPOSITORY}/releases/download/${CODEX_ZSH_RELEASE_TAG}/codex-zsh" \
+ -o "${RUNNER_TEMP}/codex-zsh"
+
- name: Build Codex package archive
shell: bash
env:
@@ -708,7 +729,8 @@ jobs:
--target "$TARGET" \
--bundle "$BUNDLE" \
--entrypoint-dir "target/${TARGET}/release" \
- --archive-dir "dist/${TARGET}"
+ --archive-dir "dist/${TARGET}" \
+ --zsh-manifest "${RUNNER_TEMP}/codex-zsh"
- name: Build Python runtime wheel
if: ${{ matrix.bundle == 'primary' }}
@@ -1043,11 +1065,6 @@ jobs:
with:
publish: true
- zsh-release-assets:
- name: zsh release assets
- needs: tag-check
- uses: ./.github/workflows/rust-release-zsh.yml
-
release:
needs:
- tag-check
@@ -1055,7 +1072,6 @@ jobs:
- finalize-macos
- build-windows
- argument-comment-lint-release-assets
- - zsh-release-assets
if: >-
${{
always() &&
@@ -1063,8 +1079,7 @@ jobs:
needs.build.result == 'success' &&
needs.finalize-macos.result == 'success' &&
needs.build-windows.result == 'success' &&
- needs.argument-comment-lint-release-assets.result == 'success' &&
- needs.zsh-release-assets.result == 'success'
+ needs.argument-comment-lint-release-assets.result == 'success'
}}
name: release
runs-on: ubuntu-latest
@@ -1113,7 +1128,7 @@ jobs:
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: dist
- pattern: "{*-symbols,argument-comment-lint-*,codex-zsh-*,python-runtime-wheel-*}"
+ pattern: "{*-symbols,argument-comment-lint-*,python-runtime-wheel-*}"
- name: List
run: ls -R dist/
@@ -1236,13 +1251,6 @@ jobs:
tag: ${{ github.ref_name }}
config: .github/dotslash-config.json
- - uses: facebook/dotslash-publish-release@9c9ec027515c34db9282a09a25a9cab5880b2c52 # v2
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- tag: ${{ github.ref_name }}
- config: .github/dotslash-zsh-config.json
-
- uses: facebook/dotslash-publish-release@9c9ec027515c34db9282a09a25a9cab5880b2c52 # v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/scripts/codex_package/README.md b/scripts/codex_package/README.md
index 323a3ce5b..b76c18c3c 100644
--- a/scripts/codex_package/README.md
+++ b/scripts/codex_package/README.md
@@ -73,4 +73,6 @@ The patched zsh fork used by `shell_zsh_fork` is fetched from the DotSlash
manifest at `scripts/codex_package/codex-zsh` when the selected target has a
matching prebuilt artifact. Downloaded archives are cached under
`$TMPDIR/codex-package/-zsh` and installed at
-`codex-resources/zsh/bin/zsh`.
+`codex-resources/zsh/bin/zsh`. Pass `--zsh-manifest` to use a different
+DotSlash manifest, such as the manifest published with a standalone zsh
+artifact release.
diff --git a/scripts/codex_package/cli.py b/scripts/codex_package/cli.py
index b7d919e4f..1dd276827 100644
--- a/scripts/codex_package/cli.py
+++ b/scripts/codex_package/cli.py
@@ -90,6 +90,14 @@ def parse_args() -> argparse.Namespace:
"targets, bwrap is built with Cargo."
),
)
+ parser.add_argument(
+ "--zsh-manifest",
+ type=Path,
+ help=(
+ "Optional DotSlash manifest for the patched zsh fork instead of "
+ "scripts/codex_package/codex-zsh."
+ ),
+ )
parser.add_argument(
"--codex-command-runner-bin",
type=Path,
@@ -160,7 +168,7 @@ def main() -> int:
inputs = PackageInputs(
entrypoint_bin=source_outputs.entrypoint_bin,
rg_bin=resolve_rg_bin(spec, args.rg_bin),
- zsh_bin=resolve_zsh_bin(spec),
+ zsh_bin=resolve_zsh_bin(spec, args.zsh_manifest),
bwrap_bin=source_outputs.bwrap_bin,
codex_command_runner_bin=source_outputs.codex_command_runner_bin,
codex_windows_sandbox_setup_bin=source_outputs.codex_windows_sandbox_setup_bin,
diff --git a/scripts/codex_package/test_zsh.py b/scripts/codex_package/test_zsh.py
new file mode 100644
index 000000000..b4f536cfc
--- /dev/null
+++ b/scripts/codex_package/test_zsh.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python3
+
+import hashlib
+import json
+from pathlib import Path
+import sys
+import tarfile
+import tempfile
+import unittest
+from unittest.mock import patch
+
+sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
+
+from codex_package.targets import TARGET_SPECS
+from codex_package.zsh import resolve_zsh_bin
+
+
+class ResolveZshBinTest(unittest.TestCase):
+ def test_uses_manifest_override(self) -> None:
+ with tempfile.TemporaryDirectory() as temp_dir:
+ root = Path(temp_dir)
+ archive = root / "codex-zsh.tar.gz"
+ source = root / "zsh"
+ source.write_bytes(b"standalone zsh")
+ with tarfile.open(archive, "w:gz") as tar:
+ tar.add(source, arcname="codex-zsh/bin/zsh")
+
+ manifest = root / "codex-zsh"
+ manifest.write_text(
+ json.dumps(
+ {
+ "platforms": {
+ "linux-x86_64": {
+ "size": archive.stat().st_size,
+ "hash": "sha256",
+ "digest": hashlib.sha256(
+ archive.read_bytes()
+ ).hexdigest(),
+ "format": "tar.gz",
+ "path": "codex-zsh/bin/zsh",
+ "providers": [{"url": archive.as_uri()}],
+ }
+ }
+ }
+ ),
+ encoding="utf-8",
+ )
+
+ with patch(
+ "codex_package.dotslash.default_cache_root",
+ return_value=root / "cache",
+ ):
+ zsh_bin = resolve_zsh_bin(
+ TARGET_SPECS["x86_64-unknown-linux-musl"], manifest
+ )
+
+ self.assertIsNotNone(zsh_bin)
+ assert zsh_bin is not None
+ self.assertEqual(zsh_bin.read_bytes(), b"standalone zsh")
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/scripts/codex_package/zsh.py b/scripts/codex_package/zsh.py
index f4ee7e19d..4ec2db502 100644
--- a/scripts/codex_package/zsh.py
+++ b/scripts/codex_package/zsh.py
@@ -11,10 +11,13 @@ ZSH_MANIFEST = REPO_ROOT / "scripts" / "codex_package" / "codex-zsh"
ZSH_RESOURCE_PATH = Path("zsh") / "bin" / "zsh"
-def resolve_zsh_bin(spec: TargetSpec) -> Path | None:
+def resolve_zsh_bin(
+ spec: TargetSpec,
+ manifest_path: Path | None = None,
+) -> Path | None:
return fetch_dotslash_executable(
spec,
- manifest_path=ZSH_MANIFEST,
+ manifest_path=manifest_path or ZSH_MANIFEST,
artifact_label="codex-zsh",
cache_key=f"{spec.target}-zsh",
dest_name="zsh",