From 387adc6c4bc484aefb658a6006ad0a26fc45c79b Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Wed, 10 Jun 2026 13:15:43 -0700 Subject: [PATCH] [codex] reuse release artifacts for npm staging (#27312) The release job already downloads every workflow artifact into `dist`, but npm staging creates a new cache and downloads the six target artifacts again. Reuse `dist` as the staging script's artifact cache while preserving the existing download fallback for missing artifacts and standalone callers. The script retains ownership of temporary caches but does not delete a caller-provided directory. In https://github.com/openai/codex/actions/runs/27242495616, the duplicate download transferred 3.3 GiB and took 4 minutes 13 seconds. This should reduce total release time by about 4 minutes. --- .github/workflows/rust-release.yml | 1 + scripts/stage_npm_packages.py | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index b821700b4..22b873f7d 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -1204,6 +1204,7 @@ jobs: ./scripts/stage_npm_packages.py \ --release-version "$RELEASE_VERSION" \ --workflow-url "$workflow_url" \ + --artifacts-dir "${GITHUB_WORKSPACE}/dist" \ --package codex \ --package codex-responses-api-proxy \ --package codex-sdk diff --git a/scripts/stage_npm_packages.py b/scripts/stage_npm_packages.py index 2329d2ba6..38374f523 100755 --- a/scripts/stage_npm_packages.py +++ b/scripts/stage_npm_packages.py @@ -101,6 +101,11 @@ def parse_args() -> argparse.Namespace: "--workflow-url", help="Optional workflow URL to reuse for native artifacts.", ) + parser.add_argument( + "--artifacts-dir", + type=Path, + help="Directory containing previously downloaded workflow artifacts.", + ) parser.add_argument( "--output-dir", type=Path, @@ -496,6 +501,7 @@ def main() -> int: vendor_temp_roots: list[Path] = [] vendor_src_by_components: dict[tuple[str, ...], Path] = {} artifacts_temp_root: Path | None = None + remove_artifacts_temp_root = False resolved_head_sha: str | None = None final_messages = [] @@ -506,10 +512,15 @@ def main() -> int: args.release_version, args.workflow_url ) print(f"Using native artifacts from {workflow_url}", flush=True) - artifacts_temp_root = Path( - tempfile.mkdtemp(prefix="npm-native-artifacts-", dir=runner_temp) - ) - print(f"Caching downloaded artifacts in {artifacts_temp_root}", flush=True) + if args.artifacts_dir is not None: + artifacts_temp_root = args.artifacts_dir.resolve() + artifacts_temp_root.mkdir(parents=True, exist_ok=True) + else: + artifacts_temp_root = Path( + tempfile.mkdtemp(prefix="npm-native-artifacts-", dir=runner_temp) + ) + remove_artifacts_temp_root = True + print(f"Using artifact cache at {artifacts_temp_root}", flush=True) for components in native_component_sets: vendor_temp_root = Path( tempfile.mkdtemp(prefix="npm-native-", dir=runner_temp) @@ -570,7 +581,7 @@ def main() -> int: if not args.keep_staging_dirs: for vendor_temp_root in vendor_temp_roots: shutil.rmtree(vendor_temp_root, ignore_errors=True) - if artifacts_temp_root is not None: + if remove_artifacts_temp_root and artifacts_temp_root is not None: shutil.rmtree(artifacts_temp_root, ignore_errors=True) for msg in final_messages: