diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 00000000..f9f17e63 --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: MPL-2.0 +name: Rust +# Build + test + clippy gate for the three standalone Rust crates. +# Added after a non-compiling crate (robot-repo-automaton) reached `main` +# unnoticed: the only prior Rust CI was CodeQL in build-mode `none` +# (buildless), so nothing actually compiled or tested these crates. +on: + push: + branches: [main] + pull_request: + branches: ['**'] +permissions: + contents: read +env: + CARGO_TERM_COLOR: always + # reqwest=rustls-tls, git2=vendored-openssl, gix=rust-tls. OPENSSL_NO_VENDOR + # makes openssl-sys link the runner's preinstalled system OpenSSL instead of + # recompiling the vendored copy (matches the documented local build). + OPENSSL_NO_VENDOR: '1' +jobs: + rust: + name: build · test · clippy + runs-on: ubuntu-latest + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + crate: [robot-repo-automaton, shared-context, dashboard] + defaults: + run: + working-directory: ${{ matrix.crate }} + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: Ensure clippy + rustfmt components + run: rustup component add clippy rustfmt + - name: Build (all targets) + run: cargo build --all-targets --verbose + - name: Test + run: cargo test --verbose + - name: Clippy (deny warnings) + run: cargo clippy --all-targets -- -D warnings + - name: Rustfmt check (informational) + # Pre-existing formatting drift is not yet gated; surfaced here so it + # stays visible without blocking. Flip to a hard gate after a dedicated + # `cargo fmt` pass lands. + run: cargo fmt --check + continue-on-error: true diff --git a/robot-repo-automaton/Cargo.toml b/robot-repo-automaton/Cargo.toml index fb24b843..326f0f65 100644 --- a/robot-repo-automaton/Cargo.toml +++ b/robot-repo-automaton/Cargo.toml @@ -42,7 +42,7 @@ reqwest = { version = "0.12.28", features = ["json", "rustls-tls"], default-feat # Serialization serde = { version = "1.0.228", features = ["derive"] } serde_json = "1.0.150" -toml = "1.1.2+spec-1.1.0" +toml = "1.1.2" # Git operations # Using vendored-openssl to avoid system OpenSSL dependency (libssl-dev) diff --git a/robot-repo-automaton/src/exclusion_registry.rs b/robot-repo-automaton/src/exclusion_registry.rs index 6b1abae4..ccf9c86f 100644 --- a/robot-repo-automaton/src/exclusion_registry.rs +++ b/robot-repo-automaton/src/exclusion_registry.rs @@ -135,11 +135,11 @@ impl ExclusionRegistry { e )) })?; - Self::from_str(&source) + Self::parse(&source) } /// Parse from an in-memory A2ML string. - pub fn from_str(source: &str) -> Result { + pub fn parse(source: &str) -> Result { let raw: RawRegistry = toml::from_str(source).map_err(|e| { crate::error::Error::Config(format!("failed to parse exclusion registry: {e}")) })?; @@ -270,7 +270,7 @@ impl ExclusionRegistry { } // Kill-switch check first — cheapest, catches everything. - if let Some(kill) = env::var("HYPATIA_AUTOMATION").ok() { + if let Ok(kill) = env::var("HYPATIA_AUTOMATION") { let k = kill.to_ascii_lowercase(); if matches!(k.as_str(), "off" | "disabled" | "0" | "false" | "halt") { return Decision::Deny { @@ -445,7 +445,7 @@ reason = "upstream homebrew" "#; fn registry() -> ExclusionRegistry { - ExclusionRegistry::from_str(FIXTURE).unwrap() + ExclusionRegistry::parse(FIXTURE).unwrap() } #[test] diff --git a/robot-repo-automaton/src/fixer.rs b/robot-repo-automaton/src/fixer.rs index 373b695e..7b55b274 100644 --- a/robot-repo-automaton/src/fixer.rs +++ b/robot-repo-automaton/src/fixer.rs @@ -618,7 +618,6 @@ impl Fixer { content .replace("gitbot-fleet", repo_name) - .replace("hyperpolymath", "hyperpolymath") .replace("{{LICENSE}}", "MPL-2.0") .replace("{{YEAR}}", &year) .replace("{{AUTHOR}}", "Jonathan D.A. Jewell") diff --git a/robot-repo-automaton/src/hypatia.rs b/robot-repo-automaton/src/hypatia.rs index 0ee3d8dd..e0ab4ba8 100644 --- a/robot-repo-automaton/src/hypatia.rs +++ b/robot-repo-automaton/src/hypatia.rs @@ -562,7 +562,7 @@ impl CicdHyperAClient { /// - Auto-approve rules that consistently produce successful fixes pub async fn report_results( &self, - repo_path: &PathBuf, + repo_path: &Path, results: &[RuleExecutionResult], ) -> crate::Result<()> { if !self.config.enable_feedback { diff --git a/robot-repo-automaton/src/main.rs b/robot-repo-automaton/src/main.rs index 822844c5..18077b07 100644 --- a/robot-repo-automaton/src/main.rs +++ b/robot-repo-automaton/src/main.rs @@ -20,7 +20,7 @@ use clap::{Parser, Subcommand}; use robot_repo_automaton::prelude::*; use robot_repo_automaton::github::{GitHubClient, CreatePullRequest}; use robot_repo_automaton::confidence::ThresholdConfig; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use tracing::{debug, error, info, warn}; use tracing_subscriber::EnvFilter; @@ -712,7 +712,7 @@ async fn cmd_hooks(_config: Option<&Config>, action: HookAction) -> anyhow::Resu } /// Inspect the error catalog. -fn cmd_catalog(path: &PathBuf, severity_filter: Option<&str>) -> anyhow::Result<()> { +fn cmd_catalog(path: &Path, severity_filter: Option<&str>) -> anyhow::Result<()> { let catalog = ErrorCatalog::from_file(path)?; println!( "Error Catalog: {} error types (v{})", diff --git a/robot-repo-automaton/src/registry_guard.rs b/robot-repo-automaton/src/registry_guard.rs index 37892993..9898c8ee 100644 --- a/robot-repo-automaton/src/registry_guard.rs +++ b/robot-repo-automaton/src/registry_guard.rs @@ -152,9 +152,7 @@ fn parse_full_name(url: &str) -> Option { for prefix in ["https://", "http://", "ssh://", "git://"] { if let Some(rest) = s.strip_prefix(prefix) { // Skip the host segment. - let mut parts = rest.splitn(2, '/'); - let _host = parts.next()?; - let path = parts.next()?; + let (_host, path) = rest.split_once('/')?; return Some(path.to_string()); } } diff --git a/shared-context/Cargo.toml b/shared-context/Cargo.toml index cf43dd42..b6036241 100644 --- a/shared-context/Cargo.toml +++ b/shared-context/Cargo.toml @@ -35,7 +35,7 @@ tokio = { version = "1.52.3", features = ["sync", "fs"] } notify = "8.2.0" # Bot exclusion registry (exclusion_registry + registry_guard modules) -toml = "1.1.2+spec-1.1.0" +toml = "1.1.2" glob = "0.3.3" git2 = { version = "0.21.0", default-features = false } diff --git a/shared-context/benches/fleet_benchmarks.rs b/shared-context/benches/fleet_benchmarks.rs index 411bd4be..82ffa20a 100644 --- a/shared-context/benches/fleet_benchmarks.rs +++ b/shared-context/benches/fleet_benchmarks.rs @@ -1,8 +1,9 @@ // SPDX-License-Identifier: MPL-2.0 //! Performance benchmarks for gitbot-fleet operations -use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; use gitbot_shared_context::{BotId, Context, Finding, Severity}; +use std::hint::black_box; use std::path::PathBuf; /// Benchmark context creation