From 82e65975b27d92089654932f3f6698c1d08b690b Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Wed, 24 Sep 2025 09:15:03 -0700 Subject: [PATCH] fix: add tolerance for ambiguous behavior in `gh run list` (#4162) I am not sure what is going on, as https://github.com/openai/codex/pull/3660 introduced this new logic and I swear that CI was green before I merged that PR, but I am seeing failures in this CI job this morning. This feels like a non-backwards-compatible change in `gh`, but that feels unlikely... Nevertheless, this is what I currently see on my laptop: ``` $ gh --version gh version 2.76.2 (2025-07-30) https://github.com/cli/cli/releases/tag/v2.76.2 $ gh run list --workflow .github/workflows/rust-release.yml --branch rust-v0.40.0 --json workflowName,url,headSha --jq 'first(.[])' { "headSha": "5268705a69713752adcbd8416ef9e84a683f7aa3", "url": "https://github.com/openai/codex/actions/runs/17952349351", "workflowName": ".github/workflows/rust-release.yml" } ``` Looking at sample output from an old GitHub issue (https://github.com/cli/cli/issues/6678), it appears that, at least at one point in time, the `workflowName` was _not_ the path to the workflow. --- codex-cli/scripts/build_npm_package.py | 47 ++++++-------------------- 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/codex-cli/scripts/build_npm_package.py b/codex-cli/scripts/build_npm_package.py index 2b359990..0401f103 100755 --- a/codex-cli/scripts/build_npm_package.py +++ b/codex-cli/scripts/build_npm_package.py @@ -15,6 +15,11 @@ CODEX_CLI_ROOT = SCRIPT_DIR.parent REPO_ROOT = CODEX_CLI_ROOT.parent GITHUB_REPO = "openai/codex" +# The docs are not clear on what the expected value/format of +# workflow/workflowName is: +# https://cli.github.com/manual/gh_run_list +WORKFLOW_NAME = ".github/workflows/rust-release.yml" + def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description="Build or stage the Codex CLI npm package.") @@ -163,10 +168,8 @@ def install_native_binaries(staging_dir: Path, workflow_url: str | None) -> None def resolve_latest_alpha_workflow_url() -> str: version = determine_latest_alpha_version() - workflow_url = fetch_workflow_url_for_version(version) - if not workflow_url: - raise RuntimeError(f"Unable to locate workflow for version {version}.") - return workflow_url + workflow = resolve_release_workflow(version) + return workflow["url"] def determine_latest_alpha_version() -> str: @@ -205,36 +208,6 @@ def list_releases() -> list[dict]: return releases -def fetch_workflow_url_for_version(version: str) -> str | None: - ref = f"rust-v{version}" - stdout = subprocess.check_output( - [ - "gh", - "run", - "list", - "--branch", - ref, - "--limit", - "20", - "--json", - "workflowName,url", - ], - text=True, - ) - - try: - runs = json.loads(stdout or "[]") - except json.JSONDecodeError as exc: - raise RuntimeError("Unable to parse workflow run listing.") from exc - - for run in runs: - if run.get("workflowName") == "rust-release": - url = run.get("url") - if url: - return url - return None - - def resolve_release_workflow(version: str) -> dict: stdout = subprocess.check_output( [ @@ -245,12 +218,14 @@ def resolve_release_workflow(version: str) -> dict: f"rust-v{version}", "--json", "workflowName,url,headSha", + "--workflow", + WORKFLOW_NAME, "--jq", - 'first(.[] | select(.workflowName == "rust-release"))', + "first(.[])", ], text=True, ) - workflow = json.loads(stdout) + workflow = json.loads(stdout or "[]") if not workflow: raise RuntimeError(f"Unable to find rust-release workflow for version {version}.") return workflow