ci: sync Bazel clippy lints and fix uncovered violations (#16351)

## Why

Follow-up to #16345, the Bazel clippy rollout in #15955, and the cleanup
pass in #16353.

`cargo clippy` was enforcing the workspace deny-list from
`codex-rs/Cargo.toml` because the member crates opt into `[lints]
workspace = true`, but Bazel clippy was only using `rules_rust` plus
`clippy.toml`. That left the Bazel lane vulnerable to drift:
`clippy.toml` can tune lint behavior, but it cannot set
allow/warn/deny/forbid levels.

This PR now closes both sides of the follow-up. It keeps `.bazelrc` in
sync with `[workspace.lints.clippy]`, and it fixes the real clippy
violations that the newly-synced Windows Bazel lane surfaced once that
deny-list started matching Cargo.

## What Changed

- added `.github/scripts/verify_bazel_clippy_lints.py`, a Python check
that parses `codex-rs/Cargo.toml` with `tomllib`, reads the Bazel
`build:clippy` `clippy_flag` entries from `.bazelrc`, and reports
missing, extra, or mismatched lint levels
- ran that verifier from the lightweight `ci.yml` workflow so the sync
check does not depend on a Rust toolchain being installed first
- expanded the `.bazelrc` comment to explain the Cargo `workspace =
true` linkage and why Bazel needs the deny-list duplicated explicitly
- fixed the Windows-only `codex-windows-sandbox` violations that Bazel
clippy reported after the sync, using the same style as #16353: inline
`format!` args, method references instead of trivial closures, removed
redundant clones, and replaced SID conversion `unwrap` and `expect`
calls with proper errors
- cleaned up the remaining cross-platform violations the Bazel lane
exposed in `codex-backend-client` and `core_test_support`

## Testing

Key new test introduced by this PR:

`python3 .github/scripts/verify_bazel_clippy_lints.py`
This commit is contained in:
Michael Bolin
2026-03-31 17:09:48 -07:00
committed by GitHub
parent ae057e0bb9
commit 2e942ce830
22 changed files with 347 additions and 61 deletions

View File

@@ -93,7 +93,7 @@ mod windows_impl {
} else {
cur.join(gitdir)
};
return resolved.parent().map(|p| p.to_path_buf()).or(Some(cur));
return resolved.parent().map(Path::to_path_buf).or(Some(cur));
}
return Some(cur);
}
@@ -270,17 +270,22 @@ mod windows_impl {
}
let caps = load_or_create_cap_sids(codex_home)?;
let (psid_to_use, cap_sids) = match &policy {
SandboxPolicy::ReadOnly { .. } => (
unsafe { convert_string_sid_to_sid(&caps.readonly).unwrap() },
vec![caps.readonly.clone()],
),
SandboxPolicy::WorkspaceWrite { .. } => (
unsafe { convert_string_sid_to_sid(&caps.workspace).unwrap() },
vec![
caps.workspace.clone(),
crate::cap::workspace_cap_sid_for_cwd(codex_home, cwd)?,
],
),
SandboxPolicy::ReadOnly { .. } => {
#[allow(clippy::unwrap_used)]
let psid = unsafe { convert_string_sid_to_sid(&caps.readonly).unwrap() };
(psid, vec![caps.readonly])
}
SandboxPolicy::WorkspaceWrite { .. } => {
#[allow(clippy::unwrap_used)]
let psid = unsafe { convert_string_sid_to_sid(&caps.workspace).unwrap() };
(
psid,
vec![
caps.workspace,
crate::cap::workspace_cap_sid_for_cwd(codex_home, cwd)?,
],
)
}
SandboxPolicy::DangerFullAccess | SandboxPolicy::ExternalSandbox { .. } => {
unreachable!("DangerFullAccess handled above")
}
@@ -302,7 +307,7 @@ mod windows_impl {
let runner_exe = find_runner_exe(codex_home, logs_base_dir);
let runner_cmdline = runner_exe
.to_str()
.map(|s| s.to_string())
.map(ToString::to_string)
.unwrap_or_else(|| "codex-command-runner.exe".to_string());
let runner_full_cmd = format!(
"{} {} {}",
@@ -365,7 +370,7 @@ mod windows_impl {
),
logs_base_dir,
);
return Err(anyhow::anyhow!("CreateProcessWithLogonW failed: {}", err));
return Err(anyhow::anyhow!("CreateProcessWithLogonW failed: {err}"));
}
if let Err(err) = connect_pipe(h_pipe_in) {
@@ -451,7 +456,7 @@ mod windows_impl {
if exit_code == 0 {
log_success(&command, logs_base_dir);
} else {
log_failure(&command, &format!("exit code {}", exit_code), logs_base_dir);
log_failure(&command, &format!("exit code {exit_code}"), logs_base_dir);
}
Ok(CaptureResult {