ci: proper Rust+Python CI workflow; cargo fmt + clippy clean

Replace the stale Django CI template with a CI workflow that builds and
tests both codebases: cargo fmt/clippy/build/test for the hh client and
pytest across Python 3.10-3.12 for the server. Apply cargo fmt and fix
all clippy lints so the gates pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
leetcrypt
2026-06-01 00:52:20 -07:00
parent cf92b358c4
commit 8eacf4d27b
10 changed files with 498 additions and 175 deletions
+67 -22
View File
@@ -36,7 +36,10 @@ fn start_docker_daemon() -> Result<()> {
.context("running ensure-docker.sh")?;
if !out.status.success() {
let err = String::from_utf8_lossy(&out.stderr);
let last = err.lines().last().unwrap_or("could not start the docker daemon");
let last = err
.lines()
.last()
.unwrap_or("could not start the docker daemon");
anyhow::bail!("{last}");
}
Ok(())
@@ -93,16 +96,25 @@ pub fn prepare(backend: Backend, name: &str, image: &str, start_daemon: bool) ->
// Capture output so it can't bleed onto the TUI surface; surface
// the failure reason through the returned error instead.
let out = Command::new("multipass")
.args(["launch", "--name", name, "--cpus", "1", "--memory", "1G", "--disk", "5G", image])
.args([
"launch", "--name", name, "--cpus", "1", "--memory", "1G", "--disk", "5G",
image,
])
.output()
.context("multipass launch (is multipass installed?)")?;
if !out.status.success() {
let err = String::from_utf8_lossy(&out.stderr);
anyhow::bail!("multipass launch failed: {}", err.lines().last().unwrap_or("").trim());
anyhow::bail!(
"multipass launch failed: {}",
err.lines().last().unwrap_or("").trim()
);
}
} else {
let _ = Command::new("multipass").args(["start", name])
.stdout(Stdio::null()).stderr(Stdio::null()).status();
let _ = Command::new("multipass")
.args(["start", name])
.stdout(Stdio::null())
.stderr(Stdio::null())
.status();
}
Ok(())
}
@@ -120,17 +132,35 @@ pub fn prepare(backend: Backend, name: &str, image: &str, start_daemon: bool) ->
}
}
// Persistent container so we can exec in to provision users + shells.
let _ = Command::new("docker").args(["rm", "-f", name])
.stdout(Stdio::null()).stderr(Stdio::null()).status();
let _ = Command::new("docker")
.args(["rm", "-f", name])
.stdout(Stdio::null())
.stderr(Stdio::null())
.status();
// Capture output so a failure can't paint over the TUI; the reason is
// surfaced through the returned error (shown in the error popup).
let out = Command::new("docker")
.args(["run", "-d", "--name", name, "--hostname", name, "-w", "/root", image, "sleep", "infinity"])
.args([
"run",
"-d",
"--name",
name,
"--hostname",
name,
"-w",
"/root",
image,
"sleep",
"infinity",
])
.output()
.context("docker run (is docker installed?)")?;
if !out.status.success() {
let err = String::from_utf8_lossy(&out.stderr);
anyhow::bail!("docker run failed: {}", err.lines().last().unwrap_or("").trim());
anyhow::bail!(
"docker run failed: {}",
err.lines().last().unwrap_or("").trim()
);
}
Ok(())
}
@@ -142,12 +172,18 @@ pub fn prepare(backend: Backend, name: &str, image: &str, start_daemon: bool) ->
pub fn teardown(backend: Backend, name: &str) {
match backend {
Backend::Multipass => {
let _ = Command::new("multipass").args(["delete", name, "--purge"])
.stdout(Stdio::null()).stderr(Stdio::null()).status();
let _ = Command::new("multipass")
.args(["delete", name, "--purge"])
.stdout(Stdio::null())
.stderr(Stdio::null())
.status();
}
Backend::Docker => {
let _ = Command::new("docker").args(["rm", "-f", name])
.stdout(Stdio::null()).stderr(Stdio::null()).status();
let _ = Command::new("docker")
.args(["rm", "-f", name])
.stdout(Stdio::null())
.stderr(Stdio::null())
.status();
}
Backend::Local => {}
}
@@ -163,7 +199,11 @@ fn command_for(backend: Backend, name: &str, run_user: &str) -> CommandBuilder {
c
}
Backend::Docker => {
let user = if run_user.is_empty() { "root" } else { run_user };
let user = if run_user.is_empty() {
"root"
} else {
run_user
};
let mut c = CommandBuilder::new("docker");
c.args(["exec", "-it", "-u", user, name, "bash", "-il"]);
c
@@ -196,14 +236,20 @@ fn mp(name: &str, args: &[&str]) {
let mut a = vec!["exec", name, "--"];
a.extend_from_slice(args);
// Null stdio so provisioning chatter never bleeds onto the TUI surface.
let _ = Command::new("multipass").args(a)
.stdout(Stdio::null()).stderr(Stdio::null()).status();
let _ = Command::new("multipass")
.args(a)
.stdout(Stdio::null())
.stderr(Stdio::null())
.status();
}
fn dk(name: &str, args: &[&str]) {
let mut a = vec!["exec", name];
a.extend_from_slice(args);
let _ = Command::new("docker").args(a)
.stdout(Stdio::null()).stderr(Stdio::null()).status();
let _ = Command::new("docker")
.args(a)
.stdout(Stdio::null())
.stderr(Stdio::null())
.status();
}
/// Grant a Multipass user real *passwordless* sudo (group + sudoers.d drop-in)
@@ -362,8 +408,8 @@ mod tests {
#[test]
fn local_shell_pty_roundtrip() {
let (tx, rx) = mpsc::channel();
let mut sb = Sandbox::launch(Backend::Local, "test", "", 24, 80, tx)
.expect("launch local shell");
let mut sb =
Sandbox::launch(Backend::Local, "test", "", 24, 80, tx).expect("launch local shell");
sb.write_input(b"echo HELLO_PTY_42\n").unwrap();
let mut acc = String::new();
@@ -401,8 +447,7 @@ mod relay_tests {
use base64::Engine;
let (tx, rx) = mpsc::channel();
let mut sb = Sandbox::launch(Backend::Local, "test", "", 24, 80, tx)
.expect("launch");
let mut sb = Sandbox::launch(Backend::Local, "test", "", 24, 80, tx).expect("launch");
sb.write_input(b"echo RELAY_MARKER_7\n").unwrap();
// Remote client side: a vt100 parser fed from decoded data frames.