release: use DotSlash zstd for package archives (#23752)

## Why

The Windows release job installed DotSlash successfully, but package
archive creation still failed while writing `codex-package-*.tar.zst`.
The Python archiver used `shutil.which("zstd")`, which does not reliably
find the extensionless DotSlash manifest at `.github/workflows/zstd`
from native Windows Python.

That left release packaging dependent on a command named exactly `zstd`
being discoverable on `PATH`, even though the repository already carries
a DotSlash wrapper for Windows runners.

## What changed

- Add `resolve_zstd_command()` to prefer a real `zstd` binary when
present.
- Fall back to invoking `dotslash .github/workflows/zstd` when `zstd` is
not on `PATH`.
- Keep the error explicit when neither `zstd` nor the DotSlash fallback
is available.
- Add unit coverage for direct `zstd`, DotSlash fallback, and
missing-tool error paths.

## Verification

- `python3 -m unittest discover -s scripts/codex_package -p 'test_*.py'`
- `python3 -m py_compile scripts/codex_package/*.py`
This commit is contained in:
Michael Bolin
2026-05-20 14:28:11 -07:00
committed by GitHub
Unverified
parent f6970214d2
commit f48be015d6
2 changed files with 76 additions and 4 deletions
+29 -4
View File
@@ -5,8 +5,14 @@ import subprocess
import tarfile
import tempfile
import zipfile
from collections.abc import Callable
from pathlib import Path
from .targets import REPO_ROOT
ZSTD_DOTSLASH = REPO_ROOT / ".github" / "workflows" / "zstd"
def write_archive(package_dir: Path, archive_path: Path, *, force: bool) -> None:
if is_relative_to(archive_path, package_dir):
@@ -63,14 +69,33 @@ def write_tar_archive(package_dir: Path, archive_path: Path, *, mode: str) -> No
def write_tar_zst_archive(package_dir: Path, archive_path: Path) -> None:
zstd = shutil.which("zstd")
if zstd is None:
raise RuntimeError("zstd is required to write .tar.zst archives.")
zstd_command = resolve_zstd_command()
with tempfile.TemporaryDirectory(prefix="codex-package-archive-") as temp_dir_str:
tar_path = Path(temp_dir_str) / "package.tar"
write_tar_archive(package_dir, tar_path, mode="w")
subprocess.check_call([zstd, "-T0", "-19", "-f", str(tar_path), "-o", str(archive_path)])
subprocess.check_call(
[*zstd_command, "-T0", "-19", "-f", str(tar_path), "-o", str(archive_path)]
)
def resolve_zstd_command(
*,
dotslash_manifest: Path = ZSTD_DOTSLASH,
which: Callable[[str], str | None] = shutil.which,
) -> list[str]:
zstd = which("zstd")
if zstd is not None:
return [zstd]
dotslash = which("dotslash")
if dotslash is not None and dotslash_manifest.is_file():
return [dotslash, str(dotslash_manifest)]
raise RuntimeError(
"zstd is required to write .tar.zst archives. Install zstd, or install "
f"DotSlash so the repository wrapper can run: {dotslash_manifest}"
)
def write_zip_archive(package_dir: Path, archive_path: Path) -> None: