diff --git a/.github/actions/linux-code-sign/action.yml b/.github/actions/linux-code-sign/action.yml index 9eea95dfe..12e521187 100644 --- a/.github/actions/linux-code-sign/action.yml +++ b/.github/actions/linux-code-sign/action.yml @@ -12,7 +12,7 @@ runs: using: composite steps: - name: Install cosign - uses: sigstore/cosign-installer@v3.7.0 + uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0 - name: Cosign Linux artifacts shell: bash diff --git a/.github/actions/setup-bazel-ci/action.yml b/.github/actions/setup-bazel-ci/action.yml index a7e3b322c..7c605c60b 100644 --- a/.github/actions/setup-bazel-ci/action.yml +++ b/.github/actions/setup-bazel-ci/action.yml @@ -18,7 +18,7 @@ runs: steps: - name: Set up Node.js for js_repl tests if: inputs.install-test-prereqs == 'true' - uses: actions/setup-node@v6 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 with: node-version-file: codex-rs/node-version.txt @@ -26,7 +26,7 @@ runs: # See https://github.com/openai/codex/pull/7617. - name: Install DotSlash if: inputs.install-test-prereqs == 'true' - uses: facebook/install-dotslash@v2 + uses: facebook/install-dotslash@1e4e7b3e07eaca387acb98f1d4720e0bee8dbb6a # v2 - name: Make DotSlash available in PATH (Unix) if: inputs.install-test-prereqs == 'true' && runner.os != 'Windows' @@ -39,7 +39,7 @@ runs: run: Copy-Item (Get-Command dotslash).Source -Destination "$env:LOCALAPPDATA\Microsoft\WindowsApps\dotslash.exe" - name: Set up Bazel - uses: bazelbuild/setup-bazelisk@v3 + uses: bazelbuild/setup-bazelisk@b39c379c82683a5f25d34f0d062761f62693e0b2 # v3 - name: Configure Bazel repository cache id: configure_bazel_repository_cache diff --git a/.github/actions/setup-rusty-v8-musl/action.yml b/.github/actions/setup-rusty-v8-musl/action.yml new file mode 100644 index 000000000..871c73a26 --- /dev/null +++ b/.github/actions/setup-rusty-v8-musl/action.yml @@ -0,0 +1,49 @@ +name: setup-rusty-v8-musl +description: Download and verify musl rusty_v8 artifacts for Cargo builds. +inputs: + target: + description: Rust musl target triple. + required: true + +runs: + using: composite + steps: + - name: Configure musl rusty_v8 artifact overrides and verify checksums + shell: bash + env: + TARGET: ${{ inputs.target }} + run: | + set -euo pipefail + + case "${TARGET}" in + x86_64-unknown-linux-musl|aarch64-unknown-linux-musl) + ;; + *) + echo "Unsupported musl rusty_v8 target: ${TARGET}" >&2 + exit 1 + ;; + esac + + version="$(python3 "${GITHUB_WORKSPACE}/.github/scripts/rusty_v8_bazel.py" resolved-v8-crate-version)" + release_tag="rusty-v8-v${version}" + base_url="https://github.com/openai/codex/releases/download/${release_tag}" + binding_dir="${RUNNER_TEMP}/rusty_v8" + archive_path="${binding_dir}/librusty_v8_release_${TARGET}.a.gz" + binding_path="${binding_dir}/src_binding_release_${TARGET}.rs" + checksums_path="${binding_dir}/rusty_v8_release_${TARGET}.sha256" + checksums_source="${GITHUB_WORKSPACE}/third_party/v8/rusty_v8_${version//./_}.sha256" + + mkdir -p "${binding_dir}" + curl -fsSL "${base_url}/librusty_v8_release_${TARGET}.a.gz" -o "${archive_path}" + curl -fsSL "${base_url}/src_binding_release_${TARGET}.rs" -o "${binding_path}" + grep -E " (librusty_v8_release_${TARGET}[.]a[.]gz|src_binding_release_${TARGET}[.]rs)$" \ + "${checksums_source}" > "${checksums_path}" + + if [[ "$(wc -l < "${checksums_path}")" -ne 2 ]]; then + echo "Expected exactly two checksums for ${TARGET} in ${checksums_source}" >&2 + exit 1 + fi + + (cd "${binding_dir}" && sha256sum -c "${checksums_path}") + echo "RUSTY_V8_ARCHIVE=${archive_path}" >> "${GITHUB_ENV}" + echo "RUSTY_V8_SRC_BINDING_PATH=${binding_path}" >> "${GITHUB_ENV}" diff --git a/.github/actions/windows-code-sign/action.yml b/.github/actions/windows-code-sign/action.yml index f6cf73791..b79c790f1 100644 --- a/.github/actions/windows-code-sign/action.yml +++ b/.github/actions/windows-code-sign/action.yml @@ -27,14 +27,14 @@ runs: using: composite steps: - name: Azure login for Trusted Signing (OIDC) - uses: azure/login@v2 + uses: azure/login@a457da9ea143d694b1b9c7c869ebb04ebe844ef5 # v2 with: client-id: ${{ inputs.client-id }} tenant-id: ${{ inputs.tenant-id }} subscription-id: ${{ inputs.subscription-id }} - name: Sign Windows binaries with Azure Trusted Signing - uses: azure/trusted-signing-action@v0 + uses: azure/trusted-signing-action@1d365fec12862c4aa68fcac418143d73f0cea293 # v0 with: endpoint: ${{ inputs.endpoint }} trusted-signing-account-name: ${{ inputs.account-name }} diff --git a/.github/scripts/rusty_v8_bazel.py b/.github/scripts/rusty_v8_bazel.py index c11e67263..ec73e0e5a 100644 --- a/.github/scripts/rusty_v8_bazel.py +++ b/.github/scripts/rusty_v8_bazel.py @@ -4,6 +4,7 @@ from __future__ import annotations import argparse import gzip +import hashlib import re import shutil import subprocess @@ -12,8 +13,16 @@ import tempfile import tomllib from pathlib import Path +from rusty_v8_module_bazel import ( + RustyV8ChecksumError, + check_module_bazel, + update_module_bazel, +) + ROOT = Path(__file__).resolve().parents[2] +MODULE_BAZEL = ROOT / "MODULE.bazel" +RUSTY_V8_CHECKSUMS_DIR = ROOT / "third_party" / "v8" MUSL_RUNTIME_ARCHIVE_LABELS = [ "@llvm//runtimes/libcxx:libcxx.static", "@llvm//runtimes/libcxx:libcxxabi.static", @@ -146,6 +155,24 @@ def resolved_v8_crate_version() -> str: return matches[0] +def rusty_v8_checksum_manifest_path(version: str) -> Path: + return RUSTY_V8_CHECKSUMS_DIR / f"rusty_v8_{version.replace('.', '_')}.sha256" + + +def command_version(version: str | None) -> str: + if version is not None: + return version + return resolved_v8_crate_version() + + +def command_manifest_path(manifest: Path | None, version: str) -> Path: + if manifest is None: + return rusty_v8_checksum_manifest_path(version) + if manifest.is_absolute(): + return manifest + return ROOT / manifest + + def staged_archive_name(target: str, source_path: Path) -> str: if source_path.suffix == ".lib": return f"rusty_v8_release_{target}.lib.gz" @@ -244,8 +271,18 @@ def stage_release_pair( shutil.copyfile(binding_path, staged_binding) + staged_checksums = output_dir / f"rusty_v8_release_{target}.sha256" + with staged_checksums.open("w", encoding="utf-8") as checksums: + for path in [staged_library, staged_binding]: + digest = hashlib.sha256() + with path.open("rb") as artifact: + for chunk in iter(lambda: artifact.read(1024 * 1024), b""): + digest.update(chunk) + checksums.write(f"{digest.hexdigest()} {path.name}\n") + print(staged_library) print(staged_binding) + print(staged_checksums) def parse_args() -> argparse.Namespace: @@ -264,6 +301,24 @@ def parse_args() -> argparse.Namespace: subparsers.add_parser("resolved-v8-crate-version") + check_module_bazel_parser = subparsers.add_parser("check-module-bazel") + check_module_bazel_parser.add_argument("--version") + check_module_bazel_parser.add_argument("--manifest", type=Path) + check_module_bazel_parser.add_argument( + "--module-bazel", + type=Path, + default=MODULE_BAZEL, + ) + + update_module_bazel_parser = subparsers.add_parser("update-module-bazel") + update_module_bazel_parser.add_argument("--version") + update_module_bazel_parser.add_argument("--manifest", type=Path) + update_module_bazel_parser.add_argument( + "--module-bazel", + type=Path, + default=MODULE_BAZEL, + ) + return parser.parse_args() @@ -280,6 +335,22 @@ def main() -> int: if args.command == "resolved-v8-crate-version": print(resolved_v8_crate_version()) return 0 + if args.command == "check-module-bazel": + version = command_version(args.version) + manifest_path = command_manifest_path(args.manifest, version) + try: + check_module_bazel(args.module_bazel, manifest_path, version) + except RustyV8ChecksumError as exc: + raise SystemExit(str(exc)) from exc + return 0 + if args.command == "update-module-bazel": + version = command_version(args.version) + manifest_path = command_manifest_path(args.manifest, version) + try: + update_module_bazel(args.module_bazel, manifest_path, version) + except RustyV8ChecksumError as exc: + raise SystemExit(str(exc)) from exc + return 0 raise SystemExit(f"unsupported command: {args.command}") diff --git a/.github/scripts/rusty_v8_module_bazel.py b/.github/scripts/rusty_v8_module_bazel.py new file mode 100644 index 000000000..7f474fc5d --- /dev/null +++ b/.github/scripts/rusty_v8_module_bazel.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python3 + +from __future__ import annotations + +import re +from dataclasses import dataclass +from pathlib import Path + + +SHA256_RE = re.compile(r"[0-9a-f]{64}") +HTTP_FILE_BLOCK_RE = re.compile(r"(?ms)^http_file\(\n.*?^\)\n?") + + +class RustyV8ChecksumError(ValueError): + pass + + +@dataclass(frozen=True) +class RustyV8HttpFile: + start: int + end: int + block: str + name: str + downloaded_file_path: str + sha256: str | None + + +def parse_checksum_manifest(path: Path) -> dict[str, str]: + try: + lines = path.read_text(encoding="utf-8").splitlines() + except FileNotFoundError as exc: + raise RustyV8ChecksumError(f"missing checksum manifest: {path}") from exc + + checksums: dict[str, str] = {} + for line_number, line in enumerate(lines, 1): + if not line.strip(): + continue + parts = line.split() + if len(parts) != 2: + raise RustyV8ChecksumError( + f"{path}:{line_number}: expected ' '" + ) + checksum, filename = parts + if not SHA256_RE.fullmatch(checksum): + raise RustyV8ChecksumError( + f"{path}:{line_number}: invalid SHA-256 digest for {filename}" + ) + if not filename or filename in {".", ".."} or "/" in filename: + raise RustyV8ChecksumError( + f"{path}:{line_number}: expected a bare artifact filename" + ) + if filename in checksums: + raise RustyV8ChecksumError( + f"{path}:{line_number}: duplicate checksum for {filename}" + ) + checksums[filename] = checksum + + if not checksums: + raise RustyV8ChecksumError(f"empty checksum manifest: {path}") + return checksums + + +def string_field(block: str, field: str) -> str | None: + # Matches one-line string fields inside http_file blocks, e.g. `sha256 = "...",`. + match = re.search(rf'^\s*{re.escape(field)}\s*=\s*"([^"]+)",\s*$', block, re.M) + if match: + return match.group(1) + return None + + +def rusty_v8_http_files(module_bazel: str, version: str) -> list[RustyV8HttpFile]: + version_slug = version.replace(".", "_") + name_prefix = f"rusty_v8_{version_slug}_" + entries = [] + for match in HTTP_FILE_BLOCK_RE.finditer(module_bazel): + block = match.group(0) + name = string_field(block, "name") + if not name or not name.startswith(name_prefix): + continue + downloaded_file_path = string_field(block, "downloaded_file_path") + if not downloaded_file_path: + raise RustyV8ChecksumError( + f"MODULE.bazel {name} is missing downloaded_file_path" + ) + entries.append( + RustyV8HttpFile( + start=match.start(), + end=match.end(), + block=block, + name=name, + downloaded_file_path=downloaded_file_path, + sha256=string_field(block, "sha256"), + ) + ) + return entries + + +def module_entry_set_errors( + entries: list[RustyV8HttpFile], + checksums: dict[str, str], + version: str, +) -> list[str]: + errors = [] + if not entries: + errors.append(f"MODULE.bazel has no rusty_v8 http_file entries for {version}") + return errors + + module_files: dict[str, RustyV8HttpFile] = {} + duplicate_files = set() + for entry in entries: + if entry.downloaded_file_path in module_files: + duplicate_files.add(entry.downloaded_file_path) + module_files[entry.downloaded_file_path] = entry + + for filename in sorted(duplicate_files): + errors.append(f"MODULE.bazel has duplicate http_file entries for {filename}") + + for filename in sorted(set(module_files) - set(checksums)): + entry = module_files[filename] + errors.append(f"MODULE.bazel {entry.name} has no checksum in the manifest") + + for filename in sorted(set(checksums) - set(module_files)): + errors.append(f"manifest has {filename}, but MODULE.bazel has no http_file") + + return errors + + +def module_checksum_errors( + entries: list[RustyV8HttpFile], + checksums: dict[str, str], +) -> list[str]: + errors = [] + for entry in entries: + expected = checksums.get(entry.downloaded_file_path) + if expected is None: + continue + if entry.sha256 is None: + errors.append(f"MODULE.bazel {entry.name} is missing sha256") + elif entry.sha256 != expected: + errors.append( + f"MODULE.bazel {entry.name} has sha256 {entry.sha256}, " + f"expected {expected}" + ) + return errors + + +def raise_checksum_errors(message: str, errors: list[str]) -> None: + if errors: + formatted_errors = "\n".join(f"- {error}" for error in errors) + raise RustyV8ChecksumError(f"{message}:\n{formatted_errors}") + + +def check_module_bazel_text( + module_bazel: str, + checksums: dict[str, str], + version: str, +) -> None: + entries = rusty_v8_http_files(module_bazel, version) + errors = [ + *module_entry_set_errors(entries, checksums, version), + *module_checksum_errors(entries, checksums), + ] + raise_checksum_errors("rusty_v8 MODULE.bazel checksum drift", errors) + + +def block_with_sha256(block: str, checksum: str) -> str: + sha256_line_re = re.compile(r'(?m)^(\s*)sha256\s*=\s*"[0-9a-f]+",\s*$') + if sha256_line_re.search(block): + return sha256_line_re.sub( + lambda match: f'{match.group(1)}sha256 = "{checksum}",', + block, + count=1, + ) + + downloaded_file_path_match = re.search( + r'(?m)^(\s*)downloaded_file_path\s*=\s*"[^"]+",\n', + block, + ) + if not downloaded_file_path_match: + raise RustyV8ChecksumError("http_file block is missing downloaded_file_path") + insert_at = downloaded_file_path_match.end() + indent = downloaded_file_path_match.group(1) + return f'{block[:insert_at]}{indent}sha256 = "{checksum}",\n{block[insert_at:]}' + + +def update_module_bazel_text( + module_bazel: str, + checksums: dict[str, str], + version: str, +) -> str: + entries = rusty_v8_http_files(module_bazel, version) + errors = module_entry_set_errors(entries, checksums, version) + raise_checksum_errors("cannot update rusty_v8 MODULE.bazel checksums", errors) + + updated = [] + previous_end = 0 + for entry in entries: + updated.append(module_bazel[previous_end : entry.start]) + updated.append( + block_with_sha256(entry.block, checksums[entry.downloaded_file_path]) + ) + previous_end = entry.end + updated.append(module_bazel[previous_end:]) + return "".join(updated) + + +def check_module_bazel( + module_bazel_path: Path, + manifest_path: Path, + version: str, +) -> None: + checksums = parse_checksum_manifest(manifest_path) + module_bazel = module_bazel_path.read_text(encoding="utf-8") + check_module_bazel_text(module_bazel, checksums, version) + print(f"{module_bazel_path} rusty_v8 {version} checksums match {manifest_path}") + + +def update_module_bazel( + module_bazel_path: Path, + manifest_path: Path, + version: str, +) -> None: + checksums = parse_checksum_manifest(manifest_path) + module_bazel = module_bazel_path.read_text(encoding="utf-8") + updated_module_bazel = update_module_bazel_text(module_bazel, checksums, version) + if updated_module_bazel == module_bazel: + print(f"{module_bazel_path} rusty_v8 {version} checksums are already current") + return + module_bazel_path.write_text(updated_module_bazel, encoding="utf-8") + print(f"updated {module_bazel_path} rusty_v8 {version} checksums") diff --git a/.github/scripts/test_rusty_v8_bazel.py b/.github/scripts/test_rusty_v8_bazel.py new file mode 100644 index 000000000..e86e82e8b --- /dev/null +++ b/.github/scripts/test_rusty_v8_bazel.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 + +from __future__ import annotations + +import textwrap +import unittest + +import rusty_v8_module_bazel + + +class RustyV8BazelTest(unittest.TestCase): + def test_update_module_bazel_replaces_and_inserts_sha256(self) -> None: + module_bazel = textwrap.dedent( + """\ + http_file( + name = "rusty_v8_146_4_0_x86_64_unknown_linux_gnu_archive", + downloaded_file_path = "librusty_v8_release_x86_64-unknown-linux-gnu.a.gz", + sha256 = "0000000000000000000000000000000000000000000000000000000000000000", + urls = [ + "https://example.test/librusty_v8_release_x86_64-unknown-linux-gnu.a.gz", + ], + ) + + http_file( + name = "rusty_v8_146_4_0_x86_64_unknown_linux_musl_binding", + downloaded_file_path = "src_binding_release_x86_64-unknown-linux-musl.rs", + urls = [ + "https://example.test/src_binding_release_x86_64-unknown-linux-musl.rs", + ], + ) + + http_file( + name = "rusty_v8_145_0_0_x86_64_unknown_linux_gnu_archive", + downloaded_file_path = "librusty_v8_release_x86_64-unknown-linux-gnu.a.gz", + sha256 = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + urls = [ + "https://example.test/old.gz", + ], + ) + """ + ) + checksums = { + "librusty_v8_release_x86_64-unknown-linux-gnu.a.gz": ( + "1111111111111111111111111111111111111111111111111111111111111111" + ), + "src_binding_release_x86_64-unknown-linux-musl.rs": ( + "2222222222222222222222222222222222222222222222222222222222222222" + ), + } + + updated = rusty_v8_module_bazel.update_module_bazel_text( + module_bazel, + checksums, + "146.4.0", + ) + + self.assertEqual( + textwrap.dedent( + """\ + http_file( + name = "rusty_v8_146_4_0_x86_64_unknown_linux_gnu_archive", + downloaded_file_path = "librusty_v8_release_x86_64-unknown-linux-gnu.a.gz", + sha256 = "1111111111111111111111111111111111111111111111111111111111111111", + urls = [ + "https://example.test/librusty_v8_release_x86_64-unknown-linux-gnu.a.gz", + ], + ) + + http_file( + name = "rusty_v8_146_4_0_x86_64_unknown_linux_musl_binding", + downloaded_file_path = "src_binding_release_x86_64-unknown-linux-musl.rs", + sha256 = "2222222222222222222222222222222222222222222222222222222222222222", + urls = [ + "https://example.test/src_binding_release_x86_64-unknown-linux-musl.rs", + ], + ) + + http_file( + name = "rusty_v8_145_0_0_x86_64_unknown_linux_gnu_archive", + downloaded_file_path = "librusty_v8_release_x86_64-unknown-linux-gnu.a.gz", + sha256 = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + urls = [ + "https://example.test/old.gz", + ], + ) + """ + ), + updated, + ) + rusty_v8_module_bazel.check_module_bazel_text(updated, checksums, "146.4.0") + + def test_check_module_bazel_rejects_manifest_drift(self) -> None: + module_bazel = textwrap.dedent( + """\ + http_file( + name = "rusty_v8_146_4_0_x86_64_unknown_linux_gnu_archive", + downloaded_file_path = "librusty_v8_release_x86_64-unknown-linux-gnu.a.gz", + sha256 = "1111111111111111111111111111111111111111111111111111111111111111", + urls = [ + "https://example.test/librusty_v8_release_x86_64-unknown-linux-gnu.a.gz", + ], + ) + """ + ) + checksums = { + "librusty_v8_release_x86_64-unknown-linux-gnu.a.gz": ( + "1111111111111111111111111111111111111111111111111111111111111111" + ), + "orphan.gz": ( + "2222222222222222222222222222222222222222222222222222222222222222" + ), + } + + with self.assertRaisesRegex( + rusty_v8_module_bazel.RustyV8ChecksumError, + "manifest has orphan.gz", + ): + rusty_v8_module_bazel.check_module_bazel_text( + module_bazel, + checksums, + "146.4.0", + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 2e1418480..ee277a13e 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -51,6 +51,13 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - name: Check rusty_v8 MODULE.bazel checksums + if: matrix.os == 'ubuntu-24.04' && matrix.target == 'x86_64-unknown-linux-gnu' + shell: bash + run: | + python3 .github/scripts/rusty_v8_bazel.py check-module-bazel + python3 -m unittest discover -s .github/scripts -p test_rusty_v8_bazel.py + - name: Set up Bazel CI id: setup_bazel uses: ./.github/actions/setup-bazel-ci @@ -65,7 +72,7 @@ jobs: - name: Restore bazel repository cache id: cache_bazel_repository_restore continue-on-error: true - uses: actions/cache/restore@v5 + uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 with: path: ${{ steps.setup_bazel.outputs.repository-cache-path }} key: bazel-cache-${{ matrix.target }}-${{ hashFiles('MODULE.bazel', 'codex-rs/Cargo.lock', 'codex-rs/Cargo.toml') }} @@ -168,7 +175,7 @@ jobs: - name: Restore bazel repository cache id: cache_bazel_repository_restore continue-on-error: true - uses: actions/cache/restore@v5 + uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 with: path: ${{ steps.setup_bazel.outputs.repository-cache-path }} key: bazel-cache-${{ matrix.target }}-${{ hashFiles('MODULE.bazel', 'codex-rs/Cargo.lock', 'codex-rs/Cargo.toml') }} diff --git a/.github/workflows/rust-ci-full.yml b/.github/workflows/rust-ci-full.yml index 97fa33283..a39c38857 100644 --- a/.github/workflows/rust-ci-full.yml +++ b/.github/workflows/rust-ci-full.yml @@ -43,6 +43,9 @@ jobs: argument_comment_lint_package: name: Argument comment lint package runs-on: ubuntu-24.04 + env: + CARGO_DYLINT_VERSION: 5.0.0 + DYLINT_LINK_VERSION: 5.0.0 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0 @@ -59,10 +62,13 @@ jobs: ~/.cargo/registry/index ~/.cargo/registry/cache ~/.cargo/git/db - key: argument-comment-lint-${{ runner.os }}-${{ hashFiles('tools/argument-comment-lint/Cargo.lock', 'tools/argument-comment-lint/rust-toolchain', '.github/workflows/rust-ci.yml', '.github/workflows/rust-ci-full.yml') }} + key: argument-comment-lint-${{ runner.os }}-${{ env.CARGO_DYLINT_VERSION }}-${{ env.DYLINT_LINK_VERSION }}-${{ hashFiles('tools/argument-comment-lint/Cargo.lock', 'tools/argument-comment-lint/rust-toolchain', '.github/workflows/rust-ci.yml', '.github/workflows/rust-ci-full.yml') }} - name: Install cargo-dylint tooling if: ${{ steps.cargo_dylint_cache.outputs.cache-hit != 'true' }} - run: cargo install --locked cargo-dylint dylint-link + shell: bash + run: | + cargo install --locked cargo-dylint --version "$CARGO_DYLINT_VERSION" + cargo install --locked dylint-link --version "$DYLINT_LINK_VERSION" - name: Check Python wrapper syntax run: python3 -m py_compile tools/argument-comment-lint/wrapper_common.py tools/argument-comment-lint/run.py tools/argument-comment-lint/run-prebuilt-linter.py tools/argument-comment-lint/test_wrapper_common.py - name: Test Python wrapper helpers @@ -415,22 +421,10 @@ jobs: echo "CXXFLAGS=${cxxflags}" >> "$GITHUB_ENV" - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl' }} - name: Configure musl rusty_v8 artifact overrides - env: - TARGET: ${{ matrix.target }} - shell: bash - run: | - set -euo pipefail - version="$(python3 "${GITHUB_WORKSPACE}/.github/scripts/rusty_v8_bazel.py" resolved-v8-crate-version)" - release_tag="rusty-v8-v${version}" - base_url="https://github.com/openai/codex/releases/download/${release_tag}" - archive="https://github.com/openai/codex/releases/download/rusty-v8-v${version}/librusty_v8_release_${TARGET}.a.gz" - binding_dir="${RUNNER_TEMP}/rusty_v8" - binding_path="${binding_dir}/src_binding_release_${TARGET}.rs" - mkdir -p "${binding_dir}" - curl -fsSL "${base_url}/src_binding_release_${TARGET}.rs" -o "${binding_path}" - echo "RUSTY_V8_ARCHIVE=${archive}" >> "$GITHUB_ENV" - echo "RUSTY_V8_SRC_BINDING_PATH=${binding_path}" >> "$GITHUB_ENV" + name: Configure musl rusty_v8 artifact overrides and verify checksums + uses: ./.github/actions/setup-rusty-v8-musl + with: + target: ${{ matrix.target }} - name: Install cargo-chef if: ${{ matrix.profile == 'release' }} diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 3a9eadc8b..4da750b7e 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -90,6 +90,9 @@ jobs: runs-on: ubuntu-24.04 needs: changed if: ${{ needs.changed.outputs.argument_comment_lint_package == 'true' }} + env: + CARGO_DYLINT_VERSION: 5.0.0 + DYLINT_LINK_VERSION: 5.0.0 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0 @@ -113,10 +116,13 @@ jobs: ~/.cargo/registry/index ~/.cargo/registry/cache ~/.cargo/git/db - key: argument-comment-lint-${{ runner.os }}-${{ hashFiles('tools/argument-comment-lint/Cargo.lock', 'tools/argument-comment-lint/rust-toolchain', '.github/workflows/rust-ci.yml', '.github/workflows/rust-ci-full.yml') }} + key: argument-comment-lint-${{ runner.os }}-${{ env.CARGO_DYLINT_VERSION }}-${{ env.DYLINT_LINK_VERSION }}-${{ hashFiles('tools/argument-comment-lint/Cargo.lock', 'tools/argument-comment-lint/rust-toolchain', '.github/workflows/rust-ci.yml', '.github/workflows/rust-ci-full.yml') }} - name: Install cargo-dylint tooling if: ${{ steps.cargo_dylint_cache.outputs.cache-hit != 'true' }} - run: cargo install --locked cargo-dylint dylint-link + shell: bash + run: | + cargo install --locked cargo-dylint --version "$CARGO_DYLINT_VERSION" + cargo install --locked dylint-link --version "$DYLINT_LINK_VERSION" - name: Check Python wrapper syntax run: python3 -m py_compile tools/argument-comment-lint/wrapper_common.py tools/argument-comment-lint/run.py tools/argument-comment-lint/run-prebuilt-linter.py tools/argument-comment-lint/test_wrapper_common.py - name: Test Python wrapper helpers diff --git a/.github/workflows/rust-release-argument-comment-lint.yml b/.github/workflows/rust-release-argument-comment-lint.yml index a6e88d8d3..ba0d147d4 100644 --- a/.github/workflows/rust-release-argument-comment-lint.yml +++ b/.github/workflows/rust-release-argument-comment-lint.yml @@ -19,6 +19,9 @@ jobs: name: Build - ${{ matrix.runner }} - ${{ matrix.target }} runs-on: ${{ matrix.runs_on || matrix.runner }} timeout-minutes: 60 + env: + CARGO_DYLINT_VERSION: 5.0.0 + DYLINT_LINK_VERSION: 5.0.0 strategy: fail-fast: false @@ -65,8 +68,8 @@ jobs: shell: bash run: | install_root="${RUNNER_TEMP}/argument-comment-lint-tools" - cargo install --locked cargo-dylint --root "$install_root" - cargo install --locked dylint-link + cargo install --locked cargo-dylint --version "$CARGO_DYLINT_VERSION" --root "$install_root" + cargo install --locked dylint-link --version "$DYLINT_LINK_VERSION" echo "INSTALL_ROOT=$install_root" >> "$GITHUB_ENV" - name: Cargo build diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index 30e16c417..efd3dd11e 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -211,22 +211,10 @@ jobs: echo "CXXFLAGS=${cxxflags}" >> "$GITHUB_ENV" - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl' }} - name: Configure musl rusty_v8 artifact overrides - env: - TARGET: ${{ matrix.target }} - shell: bash - run: | - set -euo pipefail - version="$(python3 "${GITHUB_WORKSPACE}/.github/scripts/rusty_v8_bazel.py" resolved-v8-crate-version)" - release_tag="rusty-v8-v${version}" - base_url="https://github.com/openai/codex/releases/download/${release_tag}" - archive="https://github.com/openai/codex/releases/download/rusty-v8-v${version}/librusty_v8_release_${TARGET}.a.gz" - binding_dir="${RUNNER_TEMP}/rusty_v8" - binding_path="${binding_dir}/src_binding_release_${TARGET}.rs" - mkdir -p "${binding_dir}" - curl -fsSL "${base_url}/src_binding_release_${TARGET}.rs" -o "${binding_path}" - echo "RUSTY_V8_ARCHIVE=${archive}" >> "$GITHUB_ENV" - echo "RUSTY_V8_SRC_BINDING_PATH=${binding_path}" >> "$GITHUB_ENV" + name: Configure musl rusty_v8 artifact overrides and verify checksums + uses: ./.github/actions/setup-rusty-v8-musl + with: + target: ${{ matrix.target }} - name: Cargo build shell: bash diff --git a/.github/workflows/rusty-v8-release.yml b/.github/workflows/rusty-v8-release.yml index d06fe0ae8..29e7b3b1a 100644 --- a/.github/workflows/rusty-v8-release.yml +++ b/.github/workflows/rusty-v8-release.yml @@ -78,7 +78,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Bazel - uses: bazelbuild/setup-bazelisk@6ecf4fd8b7d1f9721785f1dd656a689acf9add47 # v3 + uses: bazelbuild/setup-bazelisk@b39c379c82683a5f25d34f0d062761f62693e0b2 # v3 - name: Set up Python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 diff --git a/.github/workflows/v8-canary.yml b/.github/workflows/v8-canary.yml index 0dc7dc005..f5aa1d7c6 100644 --- a/.github/workflows/v8-canary.yml +++ b/.github/workflows/v8-canary.yml @@ -75,7 +75,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Bazel - uses: bazelbuild/setup-bazelisk@6ecf4fd8b7d1f9721785f1dd656a689acf9add47 # v3 + uses: bazelbuild/setup-bazelisk@b39c379c82683a5f25d34f0d062761f62693e0b2 # v3 - name: Set up Python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 diff --git a/MODULE.bazel b/MODULE.bazel index 42875b40f..04c5c69eb 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -423,6 +423,7 @@ http_archive( http_file( name = "rusty_v8_146_4_0_aarch64_apple_darwin_archive", downloaded_file_path = "librusty_v8_release_aarch64-apple-darwin.a.gz", + sha256 = "bfe2c9be32a56c28546f0f965825ee68fbf606405f310cc4e17b448a568cf98a", urls = [ "https://github.com/denoland/rusty_v8/releases/download/v146.4.0/librusty_v8_release_aarch64-apple-darwin.a.gz", ], @@ -431,6 +432,7 @@ http_file( http_file( name = "rusty_v8_146_4_0_aarch64_unknown_linux_gnu_archive", downloaded_file_path = "librusty_v8_release_aarch64-unknown-linux-gnu.a.gz", + sha256 = "dbf165b07c81bdb054bc046b43d23e69fcf7bcc1a4c1b5b4776983a71062ecd8", urls = [ "https://github.com/denoland/rusty_v8/releases/download/v146.4.0/librusty_v8_release_aarch64-unknown-linux-gnu.a.gz", ], @@ -439,6 +441,7 @@ http_file( http_file( name = "rusty_v8_146_4_0_aarch64_pc_windows_msvc_archive", downloaded_file_path = "rusty_v8_release_aarch64-pc-windows-msvc.lib.gz", + sha256 = "ed13363659c6d08583ac8fdc40493445c5767d8b94955a4d5d7bb8d5a81f6bf8", urls = [ "https://github.com/denoland/rusty_v8/releases/download/v146.4.0/rusty_v8_release_aarch64-pc-windows-msvc.lib.gz", ], @@ -447,6 +450,7 @@ http_file( http_file( name = "rusty_v8_146_4_0_x86_64_apple_darwin_archive", downloaded_file_path = "librusty_v8_release_x86_64-apple-darwin.a.gz", + sha256 = "630cd240f1bbecdb071417dc18387ab81cf67c549c1c515a0b4fcf9eba647bb7", urls = [ "https://github.com/denoland/rusty_v8/releases/download/v146.4.0/librusty_v8_release_x86_64-apple-darwin.a.gz", ], @@ -455,6 +459,7 @@ http_file( http_file( name = "rusty_v8_146_4_0_x86_64_unknown_linux_gnu_archive", downloaded_file_path = "librusty_v8_release_x86_64-unknown-linux-gnu.a.gz", + sha256 = "e64b4d99e4ae293a2e846244a89b80178ba10382c13fb591c1fa6968f5291153", urls = [ "https://github.com/denoland/rusty_v8/releases/download/v146.4.0/librusty_v8_release_x86_64-unknown-linux-gnu.a.gz", ], @@ -463,6 +468,7 @@ http_file( http_file( name = "rusty_v8_146_4_0_x86_64_pc_windows_msvc_archive", downloaded_file_path = "rusty_v8_release_x86_64-pc-windows-msvc.lib.gz", + sha256 = "90a9a2346acd3685a355e98df85c24dbe406cb124367d16259a4b5d522621862", urls = [ "https://github.com/denoland/rusty_v8/releases/download/v146.4.0/rusty_v8_release_x86_64-pc-windows-msvc.lib.gz", ], @@ -471,6 +477,7 @@ http_file( http_file( name = "rusty_v8_146_4_0_aarch64_unknown_linux_musl_archive", downloaded_file_path = "librusty_v8_release_aarch64-unknown-linux-musl.a.gz", + sha256 = "27a08ed26c34297bfd93e514692ccc44b85f8b15c6aa39cf34e784f84fb37e8e", urls = [ "https://github.com/openai/codex/releases/download/rusty-v8-v146.4.0/librusty_v8_release_aarch64-unknown-linux-musl.a.gz", ], @@ -479,6 +486,7 @@ http_file( http_file( name = "rusty_v8_146_4_0_aarch64_unknown_linux_musl_binding", downloaded_file_path = "src_binding_release_aarch64-unknown-linux-musl.rs", + sha256 = "09f8900ced8297c229246c7a50b2e0ec23c54d0a554f369619cc29863f38dd1a", urls = [ "https://github.com/openai/codex/releases/download/rusty-v8-v146.4.0/src_binding_release_aarch64-unknown-linux-musl.rs", ], @@ -487,6 +495,7 @@ http_file( http_file( name = "rusty_v8_146_4_0_x86_64_unknown_linux_musl_archive", downloaded_file_path = "librusty_v8_release_x86_64-unknown-linux-musl.a.gz", + sha256 = "20d8271ad712323d352c1383c36e3c4b755abc41ece35819c49c75ec7134d2f8", urls = [ "https://github.com/openai/codex/releases/download/rusty-v8-v146.4.0/librusty_v8_release_x86_64-unknown-linux-musl.a.gz", ], @@ -495,6 +504,7 @@ http_file( http_file( name = "rusty_v8_146_4_0_x86_64_unknown_linux_musl_binding", downloaded_file_path = "src_binding_release_x86_64-unknown-linux-musl.rs", + sha256 = "09f8900ced8297c229246c7a50b2e0ec23c54d0a554f369619cc29863f38dd1a", urls = [ "https://github.com/openai/codex/releases/download/rusty-v8-v146.4.0/src_binding_release_x86_64-unknown-linux-musl.rs", ], diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 0e2232fcb..2dfb03c3d 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -903,8 +903,8 @@ "git+https://github.com/juberti-oai/rust-sdks.git?rev=e2d1d1d230c6fc9df171ccb181423f957bb3c1f0#e2d1d1d230c6fc9df171ccb181423f957bb3c1f0_livekit-runtime": "{\"dependencies\":[{\"default_features\":true,\"features\":[],\"name\":\"async-io\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"async-std\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"async-task\",\"optional\":true},{\"name\":\"futures\",\"optional\":true},{\"default_features\":false,\"features\":[\"net\",\"rt\",\"rt-multi-thread\",\"time\"],\"name\":\"tokio\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"tokio-stream\",\"optional\":true}],\"features\":{\"async\":[\"dep:async-std\",\"dep:futures\",\"dep:async-io\"],\"default\":[\"tokio\"],\"dispatcher\":[\"dep:futures\",\"dep:async-io\",\"dep:async-std\",\"dep:async-task\"],\"tokio\":[\"dep:tokio\",\"dep:tokio-stream\"]},\"strip_prefix\":\"livekit-runtime\"}", "git+https://github.com/juberti-oai/rust-sdks.git?rev=e2d1d1d230c6fc9df171ccb181423f957bb3c1f0#e2d1d1d230c6fc9df171ccb181423f957bb3c1f0_webrtc-sys": "{\"dependencies\":[{\"name\":\"cxx\"},{\"name\":\"log\"},{\"kind\":\"build\",\"name\":\"cc\"},{\"kind\":\"build\",\"name\":\"cxx-build\"},{\"kind\":\"build\",\"name\":\"glob\"},{\"kind\":\"build\",\"name\":\"pkg-config\"},{\"default_features\":true,\"features\":[],\"kind\":\"build\",\"name\":\"webrtc-sys-build\",\"optional\":false}],\"features\":{\"default\":[]},\"strip_prefix\":\"webrtc-sys\"}", "git+https://github.com/juberti-oai/rust-sdks.git?rev=e2d1d1d230c6fc9df171ccb181423f957bb3c1f0#e2d1d1d230c6fc9df171ccb181423f957bb3c1f0_webrtc-sys-build": "{\"dependencies\":[{\"name\":\"anyhow\"},{\"name\":\"fs2\"},{\"name\":\"regex\"},{\"default_features\":false,\"features\":[\"rustls-tls-native-roots\",\"blocking\"],\"name\":\"reqwest\",\"optional\":false},{\"name\":\"scratch\"},{\"name\":\"semver\"},{\"name\":\"zip\"}],\"features\":{},\"strip_prefix\":\"webrtc-sys/build\"}", - "git+https://github.com/nornagon/crossterm?branch=nornagon%2Fcolor-query#87db8bfa6dc99427fd3b071681b07fc31c6ce995_crossterm": "{\"dependencies\":[{\"default_features\":true,\"features\":[],\"name\":\"bitflags\",\"optional\":false},{\"default_features\":false,\"features\":[],\"name\":\"futures-core\",\"optional\":true},{\"name\":\"parking_lot\"},{\"default_features\":true,\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"filedescriptor\",\"optional\":true,\"target\":\"cfg(unix)\"},{\"default_features\":false,\"features\":[],\"name\":\"libc\",\"optional\":true,\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[\"os-poll\"],\"name\":\"mio\",\"optional\":true,\"target\":\"cfg(unix)\"},{\"default_features\":false,\"features\":[\"std\",\"stdio\",\"termios\"],\"name\":\"rustix\",\"optional\":false,\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[],\"name\":\"signal-hook\",\"optional\":true,\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[\"support-v1_0\"],\"name\":\"signal-hook-mio\",\"optional\":true,\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[],\"name\":\"crossterm_winapi\",\"optional\":true,\"target\":\"cfg(windows)\"},{\"default_features\":true,\"features\":[\"winuser\",\"winerror\"],\"name\":\"winapi\",\"optional\":true,\"target\":\"cfg(windows)\"}],\"features\":{\"bracketed-paste\":[],\"default\":[\"bracketed-paste\",\"windows\",\"events\"],\"event-stream\":[\"dep:futures-core\",\"events\"],\"events\":[\"dep:mio\",\"dep:signal-hook\",\"dep:signal-hook-mio\"],\"serde\":[\"dep:serde\",\"bitflags/serde\"],\"use-dev-tty\":[\"filedescriptor\",\"rustix/process\"],\"windows\":[\"dep:winapi\",\"dep:crossterm_winapi\"]},\"strip_prefix\":\"\"}", - "git+https://github.com/nornagon/ratatui?branch=nornagon-v0.29.0-patch#9b2ad1298408c45918ee9f8241a6f95498cdbed2_ratatui": "{\"dependencies\":[{\"name\":\"bitflags\"},{\"name\":\"cassowary\"},{\"name\":\"compact_str\"},{\"default_features\":true,\"features\":[],\"name\":\"crossterm\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"document-features\",\"optional\":true},{\"name\":\"indoc\"},{\"name\":\"instability\"},{\"name\":\"itertools\"},{\"name\":\"lru\"},{\"default_features\":true,\"features\":[],\"name\":\"palette\",\"optional\":true},{\"name\":\"paste\"},{\"default_features\":true,\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true},{\"default_features\":true,\"features\":[\"derive\"],\"name\":\"strum\",\"optional\":false},{\"default_features\":true,\"features\":[],\"name\":\"termwiz\",\"optional\":true},{\"default_features\":true,\"features\":[\"local-offset\"],\"name\":\"time\",\"optional\":true},{\"name\":\"unicode-segmentation\"},{\"name\":\"unicode-truncate\"},{\"name\":\"unicode-width\"},{\"default_features\":true,\"features\":[],\"name\":\"termion\",\"optional\":true,\"target\":\"cfg(not(windows))\"}],\"features\":{\"all-widgets\":[\"widget-calendar\"],\"crossterm\":[\"dep:crossterm\"],\"default\":[\"crossterm\",\"underline-color\"],\"macros\":[],\"palette\":[\"dep:palette\"],\"scrolling-regions\":[],\"serde\":[\"dep:serde\",\"bitflags/serde\",\"compact_str/serde\"],\"termion\":[\"dep:termion\"],\"termwiz\":[\"dep:termwiz\"],\"underline-color\":[\"dep:crossterm\"],\"unstable\":[\"unstable-rendered-line-info\",\"unstable-widget-ref\",\"unstable-backend-writer\"],\"unstable-backend-writer\":[],\"unstable-rendered-line-info\":[],\"unstable-widget-ref\":[],\"widget-calendar\":[\"dep:time\"]},\"strip_prefix\":\"\"}", + "git+https://github.com/nornagon/crossterm?rev=87db8bfa6dc99427fd3b071681b07fc31c6ce995#87db8bfa6dc99427fd3b071681b07fc31c6ce995_crossterm": "{\"dependencies\":[{\"default_features\":true,\"features\":[],\"name\":\"bitflags\",\"optional\":false},{\"default_features\":false,\"features\":[],\"name\":\"futures-core\",\"optional\":true},{\"name\":\"parking_lot\"},{\"default_features\":true,\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"filedescriptor\",\"optional\":true,\"target\":\"cfg(unix)\"},{\"default_features\":false,\"features\":[],\"name\":\"libc\",\"optional\":true,\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[\"os-poll\"],\"name\":\"mio\",\"optional\":true,\"target\":\"cfg(unix)\"},{\"default_features\":false,\"features\":[\"std\",\"stdio\",\"termios\"],\"name\":\"rustix\",\"optional\":false,\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[],\"name\":\"signal-hook\",\"optional\":true,\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[\"support-v1_0\"],\"name\":\"signal-hook-mio\",\"optional\":true,\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[],\"name\":\"crossterm_winapi\",\"optional\":true,\"target\":\"cfg(windows)\"},{\"default_features\":true,\"features\":[\"winuser\",\"winerror\"],\"name\":\"winapi\",\"optional\":true,\"target\":\"cfg(windows)\"}],\"features\":{\"bracketed-paste\":[],\"default\":[\"bracketed-paste\",\"windows\",\"events\"],\"event-stream\":[\"dep:futures-core\",\"events\"],\"events\":[\"dep:mio\",\"dep:signal-hook\",\"dep:signal-hook-mio\"],\"serde\":[\"dep:serde\",\"bitflags/serde\"],\"use-dev-tty\":[\"filedescriptor\",\"rustix/process\"],\"windows\":[\"dep:winapi\",\"dep:crossterm_winapi\"]},\"strip_prefix\":\"\"}", + "git+https://github.com/nornagon/ratatui?rev=9b2ad1298408c45918ee9f8241a6f95498cdbed2#9b2ad1298408c45918ee9f8241a6f95498cdbed2_ratatui": "{\"dependencies\":[{\"name\":\"bitflags\"},{\"name\":\"cassowary\"},{\"name\":\"compact_str\"},{\"default_features\":true,\"features\":[],\"name\":\"crossterm\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"document-features\",\"optional\":true},{\"name\":\"indoc\"},{\"name\":\"instability\"},{\"name\":\"itertools\"},{\"name\":\"lru\"},{\"default_features\":true,\"features\":[],\"name\":\"palette\",\"optional\":true},{\"name\":\"paste\"},{\"default_features\":true,\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true},{\"default_features\":true,\"features\":[\"derive\"],\"name\":\"strum\",\"optional\":false},{\"default_features\":true,\"features\":[],\"name\":\"termwiz\",\"optional\":true},{\"default_features\":true,\"features\":[\"local-offset\"],\"name\":\"time\",\"optional\":true},{\"name\":\"unicode-segmentation\"},{\"name\":\"unicode-truncate\"},{\"name\":\"unicode-width\"},{\"default_features\":true,\"features\":[],\"name\":\"termion\",\"optional\":true,\"target\":\"cfg(not(windows))\"}],\"features\":{\"all-widgets\":[\"widget-calendar\"],\"crossterm\":[\"dep:crossterm\"],\"default\":[\"crossterm\",\"underline-color\"],\"macros\":[],\"palette\":[\"dep:palette\"],\"scrolling-regions\":[],\"serde\":[\"dep:serde\",\"bitflags/serde\",\"compact_str/serde\"],\"termion\":[\"dep:termion\"],\"termwiz\":[\"dep:termwiz\"],\"underline-color\":[\"dep:crossterm\"],\"unstable\":[\"unstable-rendered-line-info\",\"unstable-widget-ref\",\"unstable-backend-writer\"],\"unstable-backend-writer\":[],\"unstable-rendered-line-info\":[],\"unstable-widget-ref\":[],\"widget-calendar\":[\"dep:time\"]},\"strip_prefix\":\"\"}", "git+https://github.com/openai-oss-forks/tokio-tungstenite?rev=132f5b39c862e3a970f731d709608b3e6276d5f6#132f5b39c862e3a970f731d709608b3e6276d5f6_tokio-tungstenite": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"sink\",\"std\"],\"name\":\"futures-util\",\"optional\":false},{\"name\":\"log\"},{\"default_features\":true,\"features\":[],\"name\":\"native-tls-crate\",\"optional\":true,\"package\":\"native-tls\"},{\"default_features\":false,\"features\":[],\"name\":\"rustls\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"rustls-native-certs\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"rustls-pki-types\",\"optional\":true},{\"default_features\":false,\"features\":[\"io-util\"],\"name\":\"tokio\",\"optional\":false},{\"default_features\":true,\"features\":[],\"name\":\"tokio-native-tls\",\"optional\":true},{\"default_features\":false,\"features\":[],\"name\":\"tokio-rustls\",\"optional\":true},{\"default_features\":false,\"features\":[],\"name\":\"tungstenite\",\"optional\":false},{\"default_features\":true,\"features\":[],\"name\":\"webpki-roots\",\"optional\":true}],\"features\":{\"__rustls-tls\":[\"rustls\",\"rustls-pki-types\",\"tokio-rustls\",\"stream\",\"tungstenite/__rustls-tls\",\"handshake\"],\"connect\":[\"stream\",\"tokio/net\",\"handshake\"],\"default\":[\"connect\",\"handshake\"],\"handshake\":[\"tungstenite/handshake\"],\"native-tls\":[\"native-tls-crate\",\"tokio-native-tls\",\"stream\",\"tungstenite/native-tls\",\"handshake\"],\"native-tls-vendored\":[\"native-tls\",\"native-tls-crate/vendored\",\"tungstenite/native-tls-vendored\"],\"proxy\":[\"tungstenite/proxy\",\"tokio/net\",\"handshake\"],\"rustls-tls-native-roots\":[\"__rustls-tls\",\"rustls-native-certs\"],\"rustls-tls-webpki-roots\":[\"__rustls-tls\",\"webpki-roots\"],\"stream\":[],\"url\":[\"tungstenite/url\"]},\"strip_prefix\":\"\"}", "git+https://github.com/openai-oss-forks/tungstenite-rs?rev=9200079d3b54a1ff51072e24d81fd354f085156f#9200079d3b54a1ff51072e24d81fd354f085156f_tungstenite": "{\"dependencies\":[{\"name\":\"bytes\"},{\"default_features\":true,\"features\":[],\"name\":\"data-encoding\",\"optional\":true},{\"default_features\":false,\"features\":[\"zlib\"],\"name\":\"flate2\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"headers\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"http\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"httparse\",\"optional\":true},{\"name\":\"log\"},{\"default_features\":true,\"features\":[],\"name\":\"native-tls-crate\",\"optional\":true,\"package\":\"native-tls\"},{\"name\":\"rand\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"rustls\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"rustls-native-certs\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"rustls-pki-types\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"sha1\",\"optional\":true},{\"name\":\"thiserror\"},{\"default_features\":true,\"features\":[],\"name\":\"url\",\"optional\":true},{\"name\":\"utf-8\"},{\"default_features\":true,\"features\":[],\"name\":\"webpki-roots\",\"optional\":true}],\"features\":{\"__rustls-tls\":[\"rustls\",\"rustls-pki-types\"],\"default\":[\"handshake\"],\"deflate\":[\"headers\",\"flate2\"],\"handshake\":[\"data-encoding\",\"headers\",\"httparse\",\"sha1\"],\"headers\":[\"http\",\"dep:headers\"],\"native-tls\":[\"native-tls-crate\"],\"native-tls-vendored\":[\"native-tls\",\"native-tls-crate/vendored\"],\"proxy\":[\"handshake\"],\"rustls-tls-native-roots\":[\"__rustls-tls\",\"rustls-native-certs\"],\"rustls-tls-webpki-roots\":[\"__rustls-tls\",\"webpki-roots\"],\"url\":[\"dep:url\"]},\"strip_prefix\":\"\"}", "git+https://github.com/rust-lang/rust-clippy?rev=20ce69b9a63bcd2756cd906fe0964d1e901e042a#20ce69b9a63bcd2756cd906fe0964d1e901e042a_clippy_utils": "{\"dependencies\":[{\"default_features\":false,\"features\":[],\"name\":\"arrayvec\",\"optional\":false},{\"name\":\"itertools\"},{\"name\":\"rustc_apfloat\"},{\"default_features\":true,\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":false}],\"features\":{},\"strip_prefix\":\"clippy_utils\"}", diff --git a/codex-rs/.cargo/audit.toml b/codex-rs/.cargo/audit.toml index 143e64163..425997f6a 100644 --- a/codex-rs/.cargo/audit.toml +++ b/codex-rs/.cargo/audit.toml @@ -1,6 +1,9 @@ [advisories] +# Reviewed 2026-04-11. Keep this list in sync with ../deny.toml. ignore = [ "RUSTSEC-2024-0388", # derivative 2.2.0 via starlark; upstream crate is unmaintained "RUSTSEC-2025-0057", # fxhash 0.2.1 via starlark_map; upstream crate is unmaintained "RUSTSEC-2024-0436", # paste 1.0.15 via starlark/ratatui; upstream crate is unmaintained + "RUSTSEC-2024-0320", # yaml-rust via syntect; remove when syntect drops or updates it + "RUSTSEC-2025-0141", # bincode via syntect; remove when syntect drops or updates it ] diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index 854da178d..8f3681468 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -3536,7 +3536,7 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossterm" version = "0.28.1" -source = "git+https://github.com/nornagon/crossterm?branch=nornagon%2Fcolor-query#87db8bfa6dc99427fd3b071681b07fc31c6ce995" +source = "git+https://github.com/nornagon/crossterm?rev=87db8bfa6dc99427fd3b071681b07fc31c6ce995#87db8bfa6dc99427fd3b071681b07fc31c6ce995" dependencies = [ "bitflags 2.10.0", "crossterm_winapi", @@ -8463,7 +8463,7 @@ dependencies = [ [[package]] name = "ratatui" version = "0.29.0" -source = "git+https://github.com/nornagon/ratatui?branch=nornagon-v0.29.0-patch#9b2ad1298408c45918ee9f8241a6f95498cdbed2" +source = "git+https://github.com/nornagon/ratatui?rev=9b2ad1298408c45918ee9f8241a6f95498cdbed2#9b2ad1298408c45918ee9f8241a6f95498cdbed2" dependencies = [ "bitflags 2.10.0", "cassowary", diff --git a/codex-rs/Cargo.toml b/codex-rs/Cargo.toml index d29c8d4a2..007c57e97 100644 --- a/codex-rs/Cargo.toml +++ b/codex-rs/Cargo.toml @@ -429,8 +429,8 @@ opt-level = 0 [patch.crates-io] # Uncomment to debug local changes. # ratatui = { path = "../../ratatui" } -crossterm = { git = "https://github.com/nornagon/crossterm", branch = "nornagon/color-query" } -ratatui = { git = "https://github.com/nornagon/ratatui", branch = "nornagon-v0.29.0-patch" } +crossterm = { git = "https://github.com/nornagon/crossterm", rev = "87db8bfa6dc99427fd3b071681b07fc31c6ce995" } +ratatui = { git = "https://github.com/nornagon/ratatui", rev = "9b2ad1298408c45918ee9f8241a6f95498cdbed2" } tokio-tungstenite = { git = "https://github.com/openai-oss-forks/tokio-tungstenite", rev = "132f5b39c862e3a970f731d709608b3e6276d5f6" } tungstenite = { git = "https://github.com/openai-oss-forks/tungstenite-rs", rev = "9200079d3b54a1ff51072e24d81fd354f085156f" } diff --git a/codex-rs/deny.toml b/codex-rs/deny.toml index dd59ccc2d..088cda0ba 100644 --- a/codex-rs/deny.toml +++ b/codex-rs/deny.toml @@ -70,16 +70,11 @@ feature-depth = 1 # A list of advisory IDs to ignore. Note that ignored advisories will still # output a note when they are encountered. ignore = [ + # Reviewed 2026-04-11. Keep this list in sync with .cargo/audit.toml. + # Each exception must identify the dependency path and removal condition. { id = "RUSTSEC-2024-0388", reason = "derivative is unmaintained; pulled in via starlark v0.13.0 used by execpolicy/cli/core; no fixed release yet" }, { id = "RUSTSEC-2025-0057", reason = "fxhash is unmaintained; pulled in via starlark_map/starlark v0.13.0 used by execpolicy/cli/core; no fixed release yet" }, { id = "RUSTSEC-2024-0436", reason = "paste is unmaintained; pulled in via ratatui/rmcp/starlark used by tui/execpolicy; no fixed release yet" }, - # TODO: remove these exceptions once the workspace updates aws-lc-rs/aws-lc-sys past the affected releases. - { id = "RUSTSEC-2026-0044", reason = "aws-lc-rs/aws-lc-sys are pulled in transitively via rustls stack dependencies; upgrade will be handled separately from this hooks PR" }, - { id = "RUSTSEC-2026-0045", reason = "aws-lc-rs/aws-lc-sys are pulled in transitively via rustls stack dependencies; upgrade will be handled separately from this hooks PR" }, - { id = "RUSTSEC-2026-0046", reason = "aws-lc-rs/aws-lc-sys are pulled in transitively via rustls stack dependencies; upgrade will be handled separately from this hooks PR" }, - { id = "RUSTSEC-2026-0047", reason = "aws-lc-rs/aws-lc-sys are pulled in transitively via rustls stack dependencies; upgrade will be handled separately from this hooks PR" }, - { id = "RUSTSEC-2026-0048", reason = "aws-lc-rs/aws-lc-sys are pulled in transitively via rustls stack dependencies; upgrade will be handled separately from this hooks PR" }, - { id = "RUSTSEC-2026-0049", reason = "aws-lc-rs/aws-lc-sys are pulled in transitively via rustls stack dependencies; upgrade will be handled separately from this hooks PR" }, # TODO(fcoury): remove this exception when syntect drops yaml-rust and bincode, or updates to versions that have fixed the vulnerabilities. { id = "RUSTSEC-2024-0320", reason = "yaml-rust is unmaintained; pulled in via syntect v5.3.0 used by codex-tui for syntax highlighting; no fixed release yet" }, { id = "RUSTSEC-2025-0141", reason = "bincode is unmaintained; pulled in via syntect v5.3.0 used by codex-tui for syntax highlighting; no fixed release yet" }, @@ -267,20 +262,29 @@ skip-tree = [ [sources] # Lint level for what to happen when a crate from a crate registry that is not # in the allow list is encountered -unknown-registry = "warn" +unknown-registry = "deny" # Lint level for what to happen when a crate from a git repository that is not # in the allow list is encountered -unknown-git = "warn" +unknown-git = "deny" +# Git sources must be pinned to immutable revisions. +required-git-spec = "rev" # List of URLs for allowed crate registries. Defaults to the crates.io index # if not specified. If it is specified but empty, no registries are allowed. allow-registry = ["https://github.com/rust-lang/crates.io-index"] # List of URLs for allowed Git repositories -allow-git = [] +allow-git = [ + "https://github.com/dzbarsky/rules_rust", + "https://github.com/helix-editor/nucleo.git", + "https://github.com/juberti-oai/rust-sdks.git", + "https://github.com/nornagon/crossterm", + "https://github.com/nornagon/ratatui", + "https://github.com/openai-oss-forks/tokio-tungstenite", + "https://github.com/openai-oss-forks/tungstenite-rs", +] [sources.allow-org] # github.com organizations to allow git sources for github = [ - "nornagon", # ratatui and crossterm forks ] # gitlab.com organizations to allow git sources for gitlab = [] diff --git a/third_party/v8/README.md b/third_party/v8/README.md index 9ad37c6f0..6b85ba66c 100644 --- a/third_party/v8/README.md +++ b/third_party/v8/README.md @@ -16,6 +16,18 @@ Current pinned versions: - Rust crate: `v8 = =146.4.0` - Embedded upstream V8 source for musl release builds: `14.6.202.9` +When bumping the Rust crate version, keep the checked-in checksum manifest and +`MODULE.bazel` in sync: + +```bash +python3 .github/scripts/rusty_v8_bazel.py update-module-bazel +python3 .github/scripts/rusty_v8_bazel.py check-module-bazel +``` + +The commands read `third_party/v8/rusty_v8_.sha256` by default +and validate every matching `rusty_v8_` `http_file` entry. +CI runs the check command to block checksum drift. + The consumer-facing selectors are: - `//third_party/v8:rusty_v8_archive_for_target` diff --git a/third_party/v8/rusty_v8_146_4_0.sha256 b/third_party/v8/rusty_v8_146_4_0.sha256 new file mode 100644 index 000000000..09b3e1b0b --- /dev/null +++ b/third_party/v8/rusty_v8_146_4_0.sha256 @@ -0,0 +1,10 @@ +bfe2c9be32a56c28546f0f965825ee68fbf606405f310cc4e17b448a568cf98a librusty_v8_release_aarch64-apple-darwin.a.gz +dbf165b07c81bdb054bc046b43d23e69fcf7bcc1a4c1b5b4776983a71062ecd8 librusty_v8_release_aarch64-unknown-linux-gnu.a.gz +ed13363659c6d08583ac8fdc40493445c5767d8b94955a4d5d7bb8d5a81f6bf8 rusty_v8_release_aarch64-pc-windows-msvc.lib.gz +630cd240f1bbecdb071417dc18387ab81cf67c549c1c515a0b4fcf9eba647bb7 librusty_v8_release_x86_64-apple-darwin.a.gz +e64b4d99e4ae293a2e846244a89b80178ba10382c13fb591c1fa6968f5291153 librusty_v8_release_x86_64-unknown-linux-gnu.a.gz +90a9a2346acd3685a355e98df85c24dbe406cb124367d16259a4b5d522621862 rusty_v8_release_x86_64-pc-windows-msvc.lib.gz +27a08ed26c34297bfd93e514692ccc44b85f8b15c6aa39cf34e784f84fb37e8e librusty_v8_release_aarch64-unknown-linux-musl.a.gz +09f8900ced8297c229246c7a50b2e0ec23c54d0a554f369619cc29863f38dd1a src_binding_release_aarch64-unknown-linux-musl.rs +20d8271ad712323d352c1383c36e3c4b755abc41ece35819c49c75ec7134d2f8 librusty_v8_release_x86_64-unknown-linux-musl.a.gz +09f8900ced8297c229246c7a50b2e0ec23c54d0a554f369619cc29863f38dd1a src_binding_release_x86_64-unknown-linux-musl.rs