Skip to content

Commit e23e7cb

Browse files
authored
release: consume standalone zsh artifacts (#30116)
## Why Once #30114 publishes zsh independently, regular Rust releases should reuse that protected, versioned artifact set instead of rebuilding identical zsh binaries for every Codex version. Keeping the zsh release tag explicit in the workflow also makes future artifact upgrades deliberate and easy to review. This PR assumes the first standalone artifact release will be published as `codex-zsh-v0.1.0` before this change lands. ## What changed - Added `CODEX_ZSH_RELEASE_TAG` near the top of `.github/workflows/rust-release.yml`, initially pinned to `codex-zsh-v0.1.0`. - Download the standalone release’s generated `codex-zsh` DotSlash manifest before assembling Linux and macOS Codex packages. - Added a `--zsh-manifest` package-builder override so release packaging fetches the matching target archive and verifies the size and SHA-256 digest recorded in that manifest. - Removed the reusable zsh build job from regular Rust releases. - Stopped copying zsh archives into each Rust release and stopped regenerating a zsh DotSlash manifest there. Windows packaging remains unchanged because the patched zsh resource is only shipped for supported Unix targets. ## Testing - Added package-helper coverage that supplies a standalone manifest override and verifies the extracted zsh bytes. - Ran the `scripts/codex_package` unit test suite. - Validated `.github/scripts/build-codex-package-archive.sh` with `bash -n`.
1 parent 891f1f4 commit e23e7cb

6 files changed

Lines changed: 111 additions & 22 deletions

File tree

.github/scripts/build-codex-package-archive.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Usage: build-codex-package-archive.sh \
99
--entrypoint-dir <dir> \
1010
--archive-dir <dir> \
1111
[--bwrap-bin <path>] \
12+
[--zsh-manifest <path>] \
1213
[--codex-command-runner-bin <path>] \
1314
[--codex-windows-sandbox-setup-bin <path>] \
1415
[--target-suffixed-entrypoint]
@@ -48,6 +49,10 @@ while [[ $# -gt 0 ]]; do
4849
bwrap_bin_provided="true"
4950
shift 2
5051
;;
52+
--zsh-manifest)
53+
resource_args+=(--zsh-manifest "${2:?--zsh-manifest requires a value}")
54+
shift 2
55+
;;
5156
--codex-command-runner-bin)
5257
resource_args+=(
5358
--codex-command-runner-bin

.github/workflows/rust-release.yml

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ on:
1414
tags:
1515
- "rust-v*.*.*"
1616

17+
env:
18+
CODEX_ZSH_RELEASE_TAG: codex-zsh-v0.1.0
19+
1720
concurrency:
1821
group: ${{ github.workflow }}
1922
cancel-in-progress: true
@@ -354,6 +357,15 @@ jobs:
354357
cp target/${{ matrix.target }}/release/codex-${{ matrix.target }}.dmg "$dest/codex-${{ matrix.target }}.dmg"
355358
fi
356359
360+
- name: Download packaged zsh manifest
361+
if: ${{ runner.os != 'macOS' }}
362+
shell: bash
363+
run: |
364+
set -euo pipefail
365+
curl -fsSL \
366+
"https://github.com/${GITHUB_REPOSITORY}/releases/download/${CODEX_ZSH_RELEASE_TAG}/codex-zsh" \
367+
-o "${RUNNER_TEMP}/codex-zsh"
368+
357369
- name: Build Codex package archive
358370
if: ${{ runner.os != 'macOS' }}
359371
shell: bash
@@ -366,7 +378,8 @@ jobs:
366378
--target "$TARGET" \
367379
--bundle "$BUNDLE" \
368380
--entrypoint-dir "target/${TARGET}/release" \
369-
--archive-dir "dist/${TARGET}"
381+
--archive-dir "dist/${TARGET}" \
382+
--zsh-manifest "${RUNNER_TEMP}/codex-zsh"
370383
371384
- name: Build Python runtime wheel
372385
if: ${{ matrix.bundle == 'primary' && runner.os != 'macOS' }}
@@ -697,6 +710,14 @@ jobs:
697710
cp "target/${{ matrix.target }}/release/${binary}" "$dest/${binary}-${{ matrix.target }}"
698711
done
699712
713+
- name: Download packaged zsh manifest
714+
shell: bash
715+
run: |
716+
set -euo pipefail
717+
curl -fsSL \
718+
"https://github.com/${GITHUB_REPOSITORY}/releases/download/${CODEX_ZSH_RELEASE_TAG}/codex-zsh" \
719+
-o "${RUNNER_TEMP}/codex-zsh"
720+
700721
- name: Build Codex package archive
701722
shell: bash
702723
env:
@@ -708,7 +729,8 @@ jobs:
708729
--target "$TARGET" \
709730
--bundle "$BUNDLE" \
710731
--entrypoint-dir "target/${TARGET}/release" \
711-
--archive-dir "dist/${TARGET}"
732+
--archive-dir "dist/${TARGET}" \
733+
--zsh-manifest "${RUNNER_TEMP}/codex-zsh"
712734
713735
- name: Build Python runtime wheel
714736
if: ${{ matrix.bundle == 'primary' }}
@@ -1043,28 +1065,21 @@ jobs:
10431065
with:
10441066
publish: true
10451067

1046-
zsh-release-assets:
1047-
name: zsh release assets
1048-
needs: tag-check
1049-
uses: ./.github/workflows/rust-release-zsh.yml
1050-
10511068
release:
10521069
needs:
10531070
- tag-check
10541071
- build
10551072
- finalize-macos
10561073
- build-windows
10571074
- argument-comment-lint-release-assets
1058-
- zsh-release-assets
10591075
if: >-
10601076
${{
10611077
always() &&
10621078
needs.tag-check.result == 'success' &&
10631079
needs.build.result == 'success' &&
10641080
needs.finalize-macos.result == 'success' &&
10651081
needs.build-windows.result == 'success' &&
1066-
needs.argument-comment-lint-release-assets.result == 'success' &&
1067-
needs.zsh-release-assets.result == 'success'
1082+
needs.argument-comment-lint-release-assets.result == 'success'
10681083
}}
10691084
name: release
10701085
runs-on: ubuntu-latest
@@ -1113,7 +1128,7 @@ jobs:
11131128
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
11141129
with:
11151130
path: dist
1116-
pattern: "{*-symbols,argument-comment-lint-*,codex-zsh-*,python-runtime-wheel-*}"
1131+
pattern: "{*-symbols,argument-comment-lint-*,python-runtime-wheel-*}"
11171132

11181133
- name: List
11191134
run: ls -R dist/
@@ -1236,13 +1251,6 @@ jobs:
12361251
tag: ${{ github.ref_name }}
12371252
config: .github/dotslash-config.json
12381253

1239-
- uses: facebook/dotslash-publish-release@9c9ec027515c34db9282a09a25a9cab5880b2c52 # v2
1240-
env:
1241-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1242-
with:
1243-
tag: ${{ github.ref_name }}
1244-
config: .github/dotslash-zsh-config.json
1245-
12461254
- uses: facebook/dotslash-publish-release@9c9ec027515c34db9282a09a25a9cab5880b2c52 # v2
12471255
env:
12481256
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

scripts/codex_package/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,6 @@ The patched zsh fork used by `shell_zsh_fork` is fetched from the DotSlash
7373
manifest at `scripts/codex_package/codex-zsh` when the selected target has a
7474
matching prebuilt artifact. Downloaded archives are cached under
7575
`$TMPDIR/codex-package/<target>-zsh` and installed at
76-
`codex-resources/zsh/bin/zsh`.
76+
`codex-resources/zsh/bin/zsh`. Pass `--zsh-manifest` to use a different
77+
DotSlash manifest, such as the manifest published with a standalone zsh
78+
artifact release.

scripts/codex_package/cli.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,14 @@ def parse_args() -> argparse.Namespace:
9090
"targets, bwrap is built with Cargo."
9191
),
9292
)
93+
parser.add_argument(
94+
"--zsh-manifest",
95+
type=Path,
96+
help=(
97+
"Optional DotSlash manifest for the patched zsh fork instead of "
98+
"scripts/codex_package/codex-zsh."
99+
),
100+
)
93101
parser.add_argument(
94102
"--codex-command-runner-bin",
95103
type=Path,
@@ -160,7 +168,7 @@ def main() -> int:
160168
inputs = PackageInputs(
161169
entrypoint_bin=source_outputs.entrypoint_bin,
162170
rg_bin=resolve_rg_bin(spec, args.rg_bin),
163-
zsh_bin=resolve_zsh_bin(spec),
171+
zsh_bin=resolve_zsh_bin(spec, args.zsh_manifest),
164172
bwrap_bin=source_outputs.bwrap_bin,
165173
codex_command_runner_bin=source_outputs.codex_command_runner_bin,
166174
codex_windows_sandbox_setup_bin=source_outputs.codex_windows_sandbox_setup_bin,

scripts/codex_package/test_zsh.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env python3
2+
3+
import hashlib
4+
import json
5+
from pathlib import Path
6+
import sys
7+
import tarfile
8+
import tempfile
9+
import unittest
10+
from unittest.mock import patch
11+
12+
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
13+
14+
from codex_package.targets import TARGET_SPECS
15+
from codex_package.zsh import resolve_zsh_bin
16+
17+
18+
class ResolveZshBinTest(unittest.TestCase):
19+
def test_uses_manifest_override(self) -> None:
20+
with tempfile.TemporaryDirectory() as temp_dir:
21+
root = Path(temp_dir)
22+
archive = root / "codex-zsh.tar.gz"
23+
source = root / "zsh"
24+
source.write_bytes(b"standalone zsh")
25+
with tarfile.open(archive, "w:gz") as tar:
26+
tar.add(source, arcname="codex-zsh/bin/zsh")
27+
28+
manifest = root / "codex-zsh"
29+
manifest.write_text(
30+
json.dumps(
31+
{
32+
"platforms": {
33+
"linux-x86_64": {
34+
"size": archive.stat().st_size,
35+
"hash": "sha256",
36+
"digest": hashlib.sha256(
37+
archive.read_bytes()
38+
).hexdigest(),
39+
"format": "tar.gz",
40+
"path": "codex-zsh/bin/zsh",
41+
"providers": [{"url": archive.as_uri()}],
42+
}
43+
}
44+
}
45+
),
46+
encoding="utf-8",
47+
)
48+
49+
with patch(
50+
"codex_package.dotslash.default_cache_root",
51+
return_value=root / "cache",
52+
):
53+
zsh_bin = resolve_zsh_bin(
54+
TARGET_SPECS["x86_64-unknown-linux-musl"], manifest
55+
)
56+
57+
self.assertIsNotNone(zsh_bin)
58+
assert zsh_bin is not None
59+
self.assertEqual(zsh_bin.read_bytes(), b"standalone zsh")
60+
61+
62+
if __name__ == "__main__":
63+
unittest.main()

scripts/codex_package/zsh.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,13 @@
1111
ZSH_RESOURCE_PATH = Path("zsh") / "bin" / "zsh"
1212

1313

14-
def resolve_zsh_bin(spec: TargetSpec) -> Path | None:
14+
def resolve_zsh_bin(
15+
spec: TargetSpec,
16+
manifest_path: Path | None = None,
17+
) -> Path | None:
1518
return fetch_dotslash_executable(
1619
spec,
17-
manifest_path=ZSH_MANIFEST,
20+
manifest_path=manifest_path or ZSH_MANIFEST,
1821
artifact_label="codex-zsh",
1922
cache_key=f"{spec.target}-zsh",
2023
dest_name="zsh",

0 commit comments

Comments
 (0)