mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Check root Python script formatting in CI (#25165)
## Why Python files under `scripts/` were not covered by the repository formatting recipe or the CI formatting job, so formatting drift could merge unnoticed. ## What - Add a dedicated `scripts/pyproject.toml` and `scripts/uv.lock` so root-script formatting uses a locked Ruff version. - Extend `just fmt` to format root Python scripts and add `fmt-scripts-check` for CI. - Run `just fmt-scripts-check` from `.github/workflows/ci.yml`, installing `uv` through SHA-pinned `astral-sh/setup-uv` while retaining the `uv` `0.11.3` pin. - Apply Ruff formatting to the root Python scripts, including `scripts/just-shell.py`, and extend `sdk/python/tests/test_artifact_workflow_and_binaries.py` to cover the root formatting recipe. - Update `AGENTS.md` so agents run `just fmt` after code changes anywhere in the repository. ## Validation - Extended the existing Python SDK workflow test to assert that `just fmt` includes root Python scripts.
This commit is contained in:
committed by
GitHub
Unverified
parent
c3cdf3c007
commit
281b416c44
@@ -74,5 +74,15 @@ jobs:
|
||||
- name: Check root README ToC
|
||||
run: python3 scripts/readme_toc.py README.md
|
||||
|
||||
- uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2.62.49
|
||||
with:
|
||||
tool: just
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
||||
with:
|
||||
version: "0.11.3"
|
||||
- name: Ruff format Python scripts (run `just fmt` to fix)
|
||||
run: just fmt-scripts-check
|
||||
|
||||
- name: Prettier (run `pnpm run format:fix` to fix)
|
||||
run: pnpm run format
|
||||
|
||||
@@ -55,7 +55,7 @@ In the codex-rs folder where the rust code lives:
|
||||
trivial; prefer new modules/files and keep `chatwidget.rs` focused on orchestration.
|
||||
- When running Rust commands (e.g. `just fix` or `just test`) be patient with the command and never try to kill them using the PID. Rust lock can make the execution slow, this is expected.
|
||||
|
||||
Run `just fmt` (in `codex-rs` directory) automatically after you have finished making Rust code changes; do not ask for approval to run it. Additionally, run the tests:
|
||||
Run `just fmt` (in the `codex-rs` directory) automatically after you have finished making code changes anywhere in this repository; do not ask for approval to run it. Additionally, run the tests:
|
||||
|
||||
1. Do not run `cargo test` directly. Use `just test` so test execution follows the repo defaults.
|
||||
2. Run the test for the specific project that was changed. For example, if changes were made in `codex-rs/tui`, run `just test -p codex-tui`.
|
||||
|
||||
@@ -36,11 +36,16 @@ app-server-test-client *args:
|
||||
cargo build -p codex-cli
|
||||
cargo run -p codex-app-server-test-client -- --codex-bin ./target/debug/codex {args}
|
||||
|
||||
# Format Rust and Python SDK code.
|
||||
# Format Rust, Python SDK code, and Python scripts.
|
||||
fmt:
|
||||
cargo fmt -- --config imports_granularity=Item {stderr-null}
|
||||
uv run --frozen --project ../sdk/python --extra dev ruff check --fix --fix-only ../sdk/python
|
||||
uv run --frozen --project ../sdk/python --extra dev ruff format ../sdk/python
|
||||
# Root scripts have their own locked Ruff environment.
|
||||
uv run --frozen --project ../scripts ruff format ../scripts
|
||||
|
||||
fmt-scripts-check:
|
||||
uv run --frozen --project ../scripts ruff format --check ../scripts
|
||||
|
||||
fix *args:
|
||||
cargo clippy --fix --tests --allow-dirty {args}
|
||||
|
||||
@@ -75,7 +75,9 @@ def blob_size(commit: str, path: str) -> int:
|
||||
return int(run_git("cat-file", "-s", f"{commit}:{path}").strip())
|
||||
|
||||
|
||||
def collect_changed_blobs(base: str, head: str, allowlist: set[str]) -> list[ChangedBlob]:
|
||||
def collect_changed_blobs(
|
||||
base: str, head: str, allowlist: set[str]
|
||||
) -> list[ChangedBlob]:
|
||||
blobs: list[ChangedBlob] = []
|
||||
for path in get_changed_paths(base, head):
|
||||
blobs.append(
|
||||
@@ -137,7 +139,9 @@ def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Fail if changed blobs exceed the configured size budget."
|
||||
)
|
||||
parser.add_argument("--base", required=True, help="Base git revision to diff against.")
|
||||
parser.add_argument(
|
||||
"--base", required=True, help="Base git revision to diff against."
|
||||
)
|
||||
parser.add_argument("--head", required=True, help="Head git revision to inspect.")
|
||||
parser.add_argument(
|
||||
"--max-bytes",
|
||||
@@ -156,7 +160,9 @@ def main() -> int:
|
||||
allowlist = load_allowlist(args.allowlist)
|
||||
blobs = collect_changed_blobs(args.base, args.head, allowlist)
|
||||
violations = [
|
||||
blob for blob in blobs if blob.size_bytes > args.max_bytes and not blob.is_allowlisted
|
||||
blob
|
||||
for blob in blobs
|
||||
if blob.size_bytes > args.max_bytes and not blob.is_allowlisted
|
||||
]
|
||||
|
||||
write_step_summary(args.max_bytes, blobs, violations)
|
||||
@@ -165,7 +171,9 @@ def main() -> int:
|
||||
print("No changed files were detected.")
|
||||
return 0
|
||||
|
||||
print(f"Checked {len(blobs)} changed file(s) against the {args.max_bytes}-byte limit.")
|
||||
print(
|
||||
f"Checked {len(blobs)} changed file(s) against the {args.max_bytes}-byte limit."
|
||||
)
|
||||
for blob in blobs:
|
||||
status = "allowlisted" if blob.is_allowlisted else "ok"
|
||||
if blob in violations:
|
||||
|
||||
@@ -99,7 +99,9 @@ def resolve_zstd_command(
|
||||
|
||||
|
||||
def write_zip_archive(package_dir: Path, archive_path: Path) -> None:
|
||||
with zipfile.ZipFile(archive_path, "w", compression=zipfile.ZIP_DEFLATED) as archive:
|
||||
with zipfile.ZipFile(
|
||||
archive_path, "w", compression=zipfile.ZIP_DEFLATED
|
||||
) as archive:
|
||||
for path in package_entries(package_dir):
|
||||
relative_path = path.relative_to(package_dir)
|
||||
if path.is_dir():
|
||||
@@ -109,4 +111,7 @@ def write_zip_archive(package_dir: Path, archive_path: Path) -> None:
|
||||
|
||||
|
||||
def package_entries(package_dir: Path) -> list[Path]:
|
||||
return sorted(package_dir.rglob("*"), key=lambda path: path.relative_to(package_dir).as_posix())
|
||||
return sorted(
|
||||
package_dir.rglob("*"),
|
||||
key=lambda path: path.relative_to(package_dir).as_posix(),
|
||||
)
|
||||
|
||||
@@ -44,8 +44,7 @@ def build_source_binaries(
|
||||
variant,
|
||||
build_entrypoint=entrypoint_bin is None,
|
||||
build_bwrap=spec.is_linux and bwrap_bin is None,
|
||||
build_codex_command_runner=spec.is_windows
|
||||
and codex_command_runner_bin is None,
|
||||
build_codex_command_runner=spec.is_windows and codex_command_runner_bin is None,
|
||||
build_codex_windows_sandbox_setup=spec.is_windows
|
||||
and codex_windows_sandbox_setup_bin is None,
|
||||
)
|
||||
@@ -138,7 +137,9 @@ def validate_prebuilt_resource_inputs(
|
||||
)
|
||||
|
||||
|
||||
def resolve_output_path(explicit_path: Path | None, default_path: Path | None) -> Path | None:
|
||||
def resolve_output_path(
|
||||
explicit_path: Path | None, default_path: Path | None
|
||||
) -> Path | None:
|
||||
if explicit_path is not None:
|
||||
return explicit_path.resolve()
|
||||
|
||||
|
||||
@@ -44,8 +44,7 @@ def parse_args() -> argparse.Namespace:
|
||||
type=Path,
|
||||
default=argparse.SUPPRESS,
|
||||
help=(
|
||||
"Output directory to create as the package root. Defaults to a new "
|
||||
"temporary directory."
|
||||
"Output directory to create as the package root. Defaults to a new temporary directory."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
@@ -72,8 +71,7 @@ def parse_args() -> argparse.Namespace:
|
||||
"--cargo-profile",
|
||||
default="dev-small",
|
||||
help=(
|
||||
"Cargo profile for source-built package artifacts. Use release for "
|
||||
"release packages."
|
||||
"Cargo profile for source-built package artifacts. Use release for release packages."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
@@ -169,7 +167,9 @@ def main() -> int:
|
||||
)
|
||||
prepare_package_dir(package_dir, force=args.force)
|
||||
build_package_dir(package_dir, version, variant, spec, inputs)
|
||||
validate_package_dir(package_dir, variant, spec, include_zsh=inputs.zsh_bin is not None)
|
||||
validate_package_dir(
|
||||
package_dir, variant, spec, include_zsh=inputs.zsh_bin is not None
|
||||
)
|
||||
|
||||
for archive_output in args.archive_output:
|
||||
archive_path = archive_output.resolve()
|
||||
|
||||
@@ -17,7 +17,9 @@ LAYOUT_VERSION = 1
|
||||
def prepare_package_dir(package_dir: Path, *, force: bool) -> None:
|
||||
if package_dir.exists():
|
||||
if not package_dir.is_dir():
|
||||
raise RuntimeError(f"Package output exists and is not a directory: {package_dir}")
|
||||
raise RuntimeError(
|
||||
f"Package output exists and is not a directory: {package_dir}"
|
||||
)
|
||||
if any(package_dir.iterdir()):
|
||||
if not force:
|
||||
raise RuntimeError(
|
||||
|
||||
@@ -27,7 +27,9 @@ class SourceBinariesForTargetTest(unittest.TestCase):
|
||||
[],
|
||||
)
|
||||
|
||||
def test_linux_package_with_prebuilt_entrypoint_and_bwrap_builds_nothing(self) -> None:
|
||||
def test_linux_package_with_prebuilt_entrypoint_and_bwrap_builds_nothing(
|
||||
self,
|
||||
) -> None:
|
||||
self.assertEqual(
|
||||
source_binaries_for_target(
|
||||
TARGET_SPECS["x86_64-unknown-linux-musl"],
|
||||
@@ -40,7 +42,9 @@ class SourceBinariesForTargetTest(unittest.TestCase):
|
||||
[],
|
||||
)
|
||||
|
||||
def test_windows_package_with_prebuilt_entrypoint_and_helpers_builds_nothing(self) -> None:
|
||||
def test_windows_package_with_prebuilt_entrypoint_and_helpers_builds_nothing(
|
||||
self,
|
||||
) -> None:
|
||||
self.assertEqual(
|
||||
source_binaries_for_target(
|
||||
TARGET_SPECS["x86_64-pc-windows-msvc"],
|
||||
|
||||
+18
-11
@@ -43,8 +43,7 @@ def resolve_codex_v8_cargo_env(
|
||||
return {}
|
||||
if archive_override or binding_override:
|
||||
raise RuntimeError(
|
||||
"Cargo package builds need RUSTY_V8_ARCHIVE and "
|
||||
"RUSTY_V8_SRC_BINDING_PATH set together."
|
||||
"Cargo package builds need RUSTY_V8_ARCHIVE and RUSTY_V8_SRC_BINDING_PATH set together."
|
||||
)
|
||||
|
||||
artifacts = fetch_codex_v8_artifacts(spec, cache_root=cache_root)
|
||||
@@ -61,12 +60,13 @@ def fetch_codex_v8_artifacts(
|
||||
cache_root: Path | None = None,
|
||||
) -> RustyV8ArtifactPair:
|
||||
if spec.is_windows:
|
||||
raise RuntimeError(f"No Codex-built V8 release artifacts for target: {spec.target}")
|
||||
raise RuntimeError(
|
||||
f"No Codex-built V8 release artifacts for target: {spec.target}"
|
||||
)
|
||||
|
||||
version = version or resolved_v8_crate_version()
|
||||
release_url = (
|
||||
"https://github.com/openai/codex/releases/download/"
|
||||
f"rusty-v8-v{version}"
|
||||
f"https://github.com/openai/codex/releases/download/rusty-v8-v{version}"
|
||||
)
|
||||
target = spec.target
|
||||
cache_dir = (cache_root or default_cache_root()) / f"rusty-v8-{version}-{target}"
|
||||
@@ -98,7 +98,9 @@ def resolved_v8_crate_version() -> str:
|
||||
}
|
||||
)
|
||||
if len(versions) != 1:
|
||||
raise RuntimeError(f"Expected exactly one resolved v8 version, found: {versions}")
|
||||
raise RuntimeError(
|
||||
f"Expected exactly one resolved v8 version, found: {versions}"
|
||||
)
|
||||
return versions[0]
|
||||
|
||||
|
||||
@@ -111,18 +113,21 @@ def load_checksums(checksums_path: Path, artifact_names: set[str]) -> dict[str,
|
||||
lines = checksums_path.read_text(encoding="utf-8").splitlines()
|
||||
if len(lines) != len(artifact_names):
|
||||
raise RuntimeError(
|
||||
f"Expected {len(artifact_names)} V8 checksums in {checksums_path}, "
|
||||
f"found {len(lines)}."
|
||||
f"Expected {len(artifact_names)} V8 checksums in {checksums_path}, found {len(lines)}."
|
||||
)
|
||||
|
||||
for line in lines:
|
||||
parts = line.split(maxsplit=1)
|
||||
if len(parts) != 2:
|
||||
raise RuntimeError(f"Invalid V8 checksum line in {checksums_path}: {line!r}")
|
||||
raise RuntimeError(
|
||||
f"Invalid V8 checksum line in {checksums_path}: {line!r}"
|
||||
)
|
||||
|
||||
digest, artifact_name = parts[0], parts[1].strip()
|
||||
if len(digest) != 64 or any(char not in "0123456789abcdef" for char in digest):
|
||||
raise RuntimeError(f"Invalid V8 checksum digest in {checksums_path}: {digest}")
|
||||
raise RuntimeError(
|
||||
f"Invalid V8 checksum digest in {checksums_path}: {digest}"
|
||||
)
|
||||
if artifact_name not in artifact_names:
|
||||
raise RuntimeError(
|
||||
f"Unexpected V8 checksum artifact in {checksums_path}: {artifact_name}"
|
||||
@@ -146,7 +151,9 @@ def ensure_valid_artifact(artifact: Path, checksum: str, url: str) -> None:
|
||||
return
|
||||
|
||||
artifact.unlink(missing_ok=True)
|
||||
raise RuntimeError(f"Codex-built V8 artifact {artifact} failed checksum validation.")
|
||||
raise RuntimeError(
|
||||
f"Codex-built V8 artifact {artifact} failed checksum validation."
|
||||
)
|
||||
|
||||
|
||||
def has_checksum(path: Path, expected: str) -> bool:
|
||||
|
||||
@@ -16,7 +16,7 @@ import sys
|
||||
ARGS_TOKEN = "{args}"
|
||||
STDERR_NULL_TOKEN = "{stderr-null}"
|
||||
POWERSHELL_ARGS = "@($args | Select-Object -Skip 1)"
|
||||
POWERSHELL_STDERR_NULL = '2>$null; exit $LASTEXITCODE'
|
||||
POWERSHELL_STDERR_NULL = "2>$null; exit $LASTEXITCODE"
|
||||
SH_ARGS = '"$@"'
|
||||
SH_STDERR_NULL = "2>/dev/null"
|
||||
|
||||
|
||||
@@ -44,13 +44,23 @@ def _event_response_done() -> dict[str, Any]:
|
||||
|
||||
|
||||
def _event_response_completed(response_id: str) -> dict[str, Any]:
|
||||
return {"type": "response.completed", "response": {"id": response_id, "usage": _default_usage()}}
|
||||
return {
|
||||
"type": "response.completed",
|
||||
"response": {"id": response_id, "usage": _default_usage()},
|
||||
}
|
||||
|
||||
|
||||
def _event_function_call(call_id: str, name: str, arguments_json: str) -> dict[str, Any]:
|
||||
def _event_function_call(
|
||||
call_id: str, name: str, arguments_json: str
|
||||
) -> dict[str, Any]:
|
||||
return {
|
||||
"type": "response.output_item.done",
|
||||
"item": {"type": "function_call", "call_id": call_id, "name": name, "arguments": arguments_json},
|
||||
"item": {
|
||||
"type": "function_call",
|
||||
"call_id": call_id,
|
||||
"name": name,
|
||||
"arguments": arguments_json,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +85,7 @@ def _print_request(prefix: str, payload: Any) -> None:
|
||||
sys.stdout.write(f"{prefix} {_utc_iso()}\n{pretty}\n")
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
async def _handle_connection(
|
||||
websocket: Any,
|
||||
*,
|
||||
@@ -91,7 +102,9 @@ async def _handle_connection(
|
||||
|
||||
path_no_qs = path.split("?", 1)[0] if path != "(unknown)" else path
|
||||
if path_no_qs != "(unknown)" and path_no_qs != expected_path:
|
||||
sys.stdout.write(f"[conn] {_utc_iso()} rejecting unexpected path (expected {expected_path})\n")
|
||||
sys.stdout.write(
|
||||
f"[conn] {_utc_iso()} rejecting unexpected path (expected {expected_path})\n"
|
||||
)
|
||||
sys.stdout.flush()
|
||||
await websocket.close(code=1008, reason="unexpected websocket path")
|
||||
return
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
[project]
|
||||
name = "codex-scripts"
|
||||
version = "0.0.0"
|
||||
requires-python = ">=3.10"
|
||||
dependencies = ["ruff>=0.15.8"]
|
||||
|
||||
[tool.uv]
|
||||
exclude-newer = "7 days"
|
||||
index-strategy = "first-index"
|
||||
@@ -88,7 +88,7 @@ def check_or_fix(readme_path: Path, fix: bool) -> int:
|
||||
current_block = lines[begin_idx + 1 : end_idx]
|
||||
current = [l for l in current_block if l.lstrip().startswith("- [")]
|
||||
# generate expected ToC from content without current ToC
|
||||
toc_content = lines[:begin_idx] + lines[end_idx+1:]
|
||||
toc_content = lines[:begin_idx] + lines[end_idx + 1 :]
|
||||
expected = generate_toc_lines("\n".join(toc_content))
|
||||
if current == expected:
|
||||
return 0
|
||||
@@ -109,7 +109,7 @@ def check_or_fix(readme_path: Path, fix: bool) -> int:
|
||||
return 1
|
||||
# rebuild file with updated ToC
|
||||
prefix = lines[: begin_idx + 1]
|
||||
suffix = lines[end_idx+1:]
|
||||
suffix = lines[end_idx + 1 :]
|
||||
new_lines = prefix + [""] + expected + [""] + suffix
|
||||
readme_path.write_text("\n".join(new_lines) + "\n", encoding="utf-8")
|
||||
print(f"Updated ToC in {readme_path}.")
|
||||
|
||||
@@ -37,7 +37,9 @@ _SPEC.loader.exec_module(_BUILD_MODULE)
|
||||
PACKAGE_NATIVE_COMPONENTS = getattr(_BUILD_MODULE, "PACKAGE_NATIVE_COMPONENTS", {})
|
||||
PACKAGE_EXPANSIONS = getattr(_BUILD_MODULE, "PACKAGE_EXPANSIONS", {})
|
||||
CODEX_PLATFORM_PACKAGES = getattr(_BUILD_MODULE, "CODEX_PLATFORM_PACKAGES", {})
|
||||
CODEX_PACKAGE_COMPONENT = getattr(_BUILD_MODULE, "CODEX_PACKAGE_COMPONENT", "codex-package")
|
||||
CODEX_PACKAGE_COMPONENT = getattr(
|
||||
_BUILD_MODULE, "CODEX_PACKAGE_COMPONENT", "codex-package"
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -159,7 +161,9 @@ def resolve_release_workflow(version: str) -> dict:
|
||||
)
|
||||
workflow = json.loads(stdout or "null")
|
||||
if not workflow:
|
||||
raise RuntimeError(f"Unable to find rust-release workflow for version {version}.")
|
||||
raise RuntimeError(
|
||||
f"Unable to find rust-release workflow for version {version}."
|
||||
)
|
||||
return workflow
|
||||
|
||||
|
||||
@@ -386,13 +390,17 @@ def install_single_binary(
|
||||
component: BinaryComponent,
|
||||
) -> Path:
|
||||
artifact_subdir = artifact_dir_for_target(artifacts_dir, target)
|
||||
archive_path = binary_archive_path(artifact_subdir, component.artifact_prefix, target)
|
||||
archive_path = binary_archive_path(
|
||||
artifact_subdir, component.artifact_prefix, target
|
||||
)
|
||||
|
||||
dest_dir = vendor_dir / target / component.dest_dir
|
||||
dest_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
binary_name = (
|
||||
f"{component.binary_basename}.exe" if "windows" in target else component.binary_basename
|
||||
f"{component.binary_basename}.exe"
|
||||
if "windows" in target
|
||||
else component.binary_basename
|
||||
)
|
||||
dest = dest_dir / binary_name
|
||||
dest.unlink(missing_ok=True)
|
||||
@@ -405,14 +413,18 @@ def install_single_binary(
|
||||
def binary_archive_path(artifact_dir: Path, artifact_prefix: str, target: str) -> Path:
|
||||
archive_names = [archive_name_for_target(artifact_prefix, target)]
|
||||
if artifact_dir.name == f"{target}-unsigned":
|
||||
archive_names.append(archive_name_for_target(artifact_prefix, f"{target}-unsigned"))
|
||||
archive_names.append(
|
||||
archive_name_for_target(artifact_prefix, f"{target}-unsigned")
|
||||
)
|
||||
|
||||
for archive_name in archive_names:
|
||||
archive_path = artifact_dir / archive_name
|
||||
if archive_path.exists():
|
||||
return archive_path
|
||||
|
||||
raise FileNotFoundError(f"Expected artifact not found: {artifact_dir / archive_names[0]}")
|
||||
raise FileNotFoundError(
|
||||
f"Expected artifact not found: {artifact_dir / archive_names[0]}"
|
||||
)
|
||||
|
||||
|
||||
def archive_name_for_target(artifact_prefix: str, target: str) -> str:
|
||||
@@ -434,7 +446,9 @@ def extract_zstd_archive(archive_path: Path, dest: Path) -> None:
|
||||
dest.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
output_path = archive_path.parent / dest.name
|
||||
subprocess.check_call(["zstd", "-f", "-d", str(archive_path), "-o", str(output_path)])
|
||||
subprocess.check_call(
|
||||
["zstd", "-f", "-d", str(archive_path), "-o", str(output_path)]
|
||||
)
|
||||
shutil.move(str(output_path), dest)
|
||||
|
||||
|
||||
@@ -497,7 +511,9 @@ def main() -> int:
|
||||
)
|
||||
print(f"Caching downloaded artifacts in {artifacts_temp_root}", flush=True)
|
||||
for components in native_component_sets:
|
||||
vendor_temp_root = Path(tempfile.mkdtemp(prefix="npm-native-", dir=runner_temp))
|
||||
vendor_temp_root = Path(
|
||||
tempfile.mkdtemp(prefix="npm-native-", dir=runner_temp)
|
||||
)
|
||||
vendor_temp_roots.append(vendor_temp_root)
|
||||
print(
|
||||
"Installing native components "
|
||||
@@ -517,8 +533,12 @@ def main() -> int:
|
||||
print(f"should `git checkout {resolved_head_sha}`", flush=True)
|
||||
|
||||
for package in packages:
|
||||
staging_dir = Path(tempfile.mkdtemp(prefix=f"npm-stage-{package}-", dir=runner_temp))
|
||||
pack_output = output_dir / tarball_name_for_package(package, args.release_version)
|
||||
staging_dir = Path(
|
||||
tempfile.mkdtemp(prefix=f"npm-stage-{package}-", dir=runner_temp)
|
||||
)
|
||||
pack_output = output_dir / tarball_name_for_package(
|
||||
package, args.release_version
|
||||
)
|
||||
print(f"Staging {package} in {staging_dir}", flush=True)
|
||||
|
||||
cmd = [
|
||||
@@ -533,7 +553,9 @@ def main() -> int:
|
||||
str(pack_output),
|
||||
]
|
||||
|
||||
vendor_src = vendor_src_by_components.get(native_components_for_package(package))
|
||||
vendor_src = vendor_src_by_components.get(
|
||||
native_components_for_package(package)
|
||||
)
|
||||
if vendor_src is not None:
|
||||
cmd.extend(["--vendor-src", str(vendor_src)])
|
||||
|
||||
|
||||
Generated
+43
@@ -0,0 +1,43 @@
|
||||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.10"
|
||||
|
||||
[options]
|
||||
exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values.
|
||||
exclude-newer-span = "P7D"
|
||||
|
||||
[[package]]
|
||||
name = "codex-scripts"
|
||||
version = "0.0.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "ruff" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "ruff", specifier = ">=0.15.8" }]
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.15.13"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/24/21/a7d5c126d5b557715ef81098f3db2fe20f622a039ff2e626af28d674ab80/ruff-0.15.13.tar.gz", hash = "sha256:f9d89f17f7ba7fb2ed42921f0df75da797a9a5d71bc39049e2c687cf2baf44b7", size = 4678180, upload-time = "2026-05-14T13:44:37.869Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/61/11d458dc6ac22504fd8e237b29dfd40504c7fbbcc8930402cfe51a8e63ed/ruff-0.15.13-py3-none-linux_armv6l.whl", hash = "sha256:444b580fc72fd6887e650acd3e575e18cdc79dbcf42fb4030b491057921f61f8", size = 10738279, upload-time = "2026-05-14T13:44:18.7Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/ca/caa871ee7be718c45256fada4e16a218ee3e33f0c4a46b729a60a24912e6/ruff-0.15.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6590d009e7cb7ebf36f83dbdd44a3fa48a0994ff6f1cdc1b08006abe58f98dc7", size = 11124798, upload-time = "2026-05-14T13:44:06.427Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/19/43f5f2e568dddde567fc41f8471f9432c09563e19d3e617a48cfa52f8f0a/ruff-0.15.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1c26d2f66163deeb6e08d8b39fbbe983ce3c71cea06a6d7591cfd1421793c629", size = 10460761, upload-time = "2026-05-14T13:44:04.375Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/df/cf938cd6de3003178f03ad7c1ea2a6c099468c03a35037985070b37e76be/ruff-0.15.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dbd6f94b434f896308e4d57fb7bfde0d02b99f7a64b3bdab0fdfa6a864203a5", size = 10804451, upload-time = "2026-05-14T13:44:25.221Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/7d/5d0973129b154ded2225729169d7068f26b467760b146493fde138415f23/ruff-0.15.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf3259f3be4d181bda591da5db2571aed6853c6a048157756448020bc6c5cd22", size = 10534285, upload-time = "2026-05-14T13:44:08.888Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/e3/6b999bbc66cd51e5f073842bc2a3995e99c5e0e72e16b15e7261f7abf57a/ruff-0.15.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae9c17e5eb4430c154e76abc25d79a318190f5a997f38fb6b114416c5319ffc9", size = 11312063, upload-time = "2026-05-14T13:44:11.274Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/5a/642639e9f5db04f1e97fbd6e091c6fd20725bdf072fb114d00eefb9e6eb8/ruff-0.15.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e2e39bff6c341f4b577a21b801326fab0b11847f48fcaa83f00a113c9b3cb55", size = 12183079, upload-time = "2026-05-14T13:44:01.634Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/4c/7585735f6b53b0f12de13618b2f7d250a844f018822efc899df2e7b8295f/ruff-0.15.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e8d9a8e08013542e94d3220bc5b62cc3e5ef87c5f74bff367d3fac14fab013e6", size = 11440833, upload-time = "2026-05-14T13:43:59.043Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/31/bf1a0803d077e679cfeee5f2f67290a0fa79c7385b5d9a8c17b9db2c48f0/ruff-0.15.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc411dfebe5eebe55ce041c6ae080eb7668955e866daa2fbb16692a784f1c4ca", size = 11434486, upload-time = "2026-05-14T13:44:27.761Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/4e/62c9b999875d4f14db80f277c030578f5e249c9852d65b7ac7ad0b43c041/ruff-0.15.13-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:768494eb08b9cee54e2fd27969966f74db5a57f6eaa7a90fcb3306af34dfc4bd", size = 11385189, upload-time = "2026-05-14T13:44:13.704Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/89/7e959047a104df3eb12863447c110140191fc5b6c4f379ea2e803fcdb0e4/ruff-0.15.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:fb75f9a3a7e42ffe117d734494e6c5e5cb3565d66e12612cb63d0e572a41a5b6", size = 10781380, upload-time = "2026-05-14T13:43:56.734Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/52/5fd18f3b88cab63e88aa11516b3b4e1e5f720e5c330f8dbe5c26210f41f8/ruff-0.15.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8cb74dd33bb2f6613faf7fc03b660053b5ac4f80e706d5788c6335e2a8048d51", size = 10540605, upload-time = "2026-05-14T13:44:20.748Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/e0/9e35f338990d3e41a82875ff7053ffe97541dae81c9d02143177f381d572/ruff-0.15.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:7ef823f817fcd191dc934e984be9cf4094f808effa16f2542ad8e821ba02bbf2", size = 11036554, upload-time = "2026-05-14T13:44:16.256Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/13/070fb048c24080fba188f66371e2a92785be257ad02242066dc7255ac6e9/ruff-0.15.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f345a13937bd7f09f6f5d19fa0721b0c103e00e7f62bc67089a8e5e037719e0b", size = 11528133, upload-time = "2026-05-14T13:44:22.808Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/8c/b1e1666aef7fc6555094d73ae6cd981701781ae85b97ceefc0eebd0b4668/ruff-0.15.13-py3-none-win32.whl", hash = "sha256:4044f94208b3b05ba0fc4a4abd0558cf4d6459bd18325eead7fd8cc66f909b41", size = 10721455, upload-time = "2026-05-14T13:44:35.697Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/a6/870a3e8a50590bb92be184ad928c2922f088b00d9dc5c5ec7b924ee08c22/ruff-0.15.13-py3-none-win_amd64.whl", hash = "sha256:7064884d442b7d477b4e7473d12da7f08851d2b1982763c5d3f388a19468a1a4", size = 11900409, upload-time = "2026-05-14T13:44:30.389Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/36/9c015cd052fca743dae8cb2aeb16b551444787467db42ceab0fc968865af/ruff-0.15.13-py3-none-win_arm64.whl", hash = "sha256:2471da9bd1068c8c064b5fd9c0c4b6dddffd6369cb1cd68b29993b1709ff1b21", size = 11179336, upload-time = "2026-05-14T13:44:33.026Z" },
|
||||
]
|
||||
@@ -68,8 +68,8 @@ def test_generation_has_single_maintenance_entrypoint_script() -> None:
|
||||
assert scripts == ["update_sdk_artifacts.py"]
|
||||
|
||||
|
||||
def test_root_fmt_recipe_formats_rust_and_python_sdk() -> None:
|
||||
"""The repo fmt command should work from Rust and Python SDK directories."""
|
||||
def test_root_fmt_recipe_formats_rust_python_sdk_and_scripts() -> None:
|
||||
"""The repo fmt command should format Rust, the Python SDK, and scripts."""
|
||||
justfile = ROOT.parents[1] / "justfile"
|
||||
lines = justfile.read_text().splitlines()
|
||||
fmt_index = lines.index("fmt:")
|
||||
@@ -88,16 +88,18 @@ def test_root_fmt_recipe_formats_rust_and_python_sdk() -> None:
|
||||
}
|
||||
expected = {
|
||||
"working_directory": 'set working-directory := "codex-rs"',
|
||||
"previous_comment": "# Format Rust and Python SDK code.",
|
||||
"previous_comment": "# Format Rust, Python SDK code, and Python scripts.",
|
||||
"commands": [
|
||||
"cargo fmt -- --config imports_granularity=Item {stderr-null}",
|
||||
"uv run --frozen --project ../sdk/python --extra dev ruff check --fix --fix-only ../sdk/python",
|
||||
"uv run --frozen --project ../sdk/python --extra dev ruff format ../sdk/python",
|
||||
"# Root scripts have their own locked Ruff environment.",
|
||||
"uv run --frozen --project ../scripts ruff format ../scripts",
|
||||
],
|
||||
}
|
||||
|
||||
assert actual == expected, (
|
||||
"The root `just fmt` recipe must run Rust fmt and Python SDK Ruff. "
|
||||
"The root `just fmt` recipe must run Rust fmt and Ruff for Python SDK code and scripts. "
|
||||
"Fix the `fmt` recipe in `justfile`, then run `just fmt`.\n"
|
||||
f"Expected: {json.dumps(expected, indent=2)}\n"
|
||||
f"Actual: {json.dumps(actual, indent=2)}"
|
||||
|
||||
Reference in New Issue
Block a user