feat: add cross-platform packaging and release automation

- Add GitHub Actions workflow for automated releases
- Create .deb, .rpm, AppImage, .dmg, and .msi packages
- Generate shell completions and manpages in build.rs
- Add platform-specific icons from rustnet3.svg
- Include eBPF dependencies for Linux packages
- Support Windows 32-bit and 64-bit builds
- Extract shared CLI module to prevent duplication
This commit is contained in:
Marco Cadetg
2025-09-29 11:56:55 +02:00
parent b642205e38
commit eca0e6000d
20 changed files with 1244 additions and 60 deletions
+4 -2
View File
@@ -238,7 +238,7 @@ impl App {
}
// Log every 10000 packets or every 5 seconds
if packets_read % 10000 == 0
if packets_read.is_multiple_of(10000)
|| last_log.elapsed() > Duration::from_secs(5)
{
info!("Read {} packets so far", packets_read);
@@ -354,7 +354,9 @@ impl App {
.fetch_add(batch.len() as u64, Ordering::Relaxed);
// Log progress
if total_processed % 10000 == 0 || last_log.elapsed() > Duration::from_secs(5) {
if total_processed.is_multiple_of(10000)
|| last_log.elapsed() > Duration::from_secs(5)
{
debug!(
"Processor {}: {} packets processed ({} parsed)",
id, total_processed, parsed_count
+46
View File
@@ -0,0 +1,46 @@
use clap::{Arg, Command};
pub fn build_cli() -> Command {
Command::new("rustnet")
.version(env!("CARGO_PKG_VERSION"))
.author("Network Monitor")
.about("Cross-platform network monitoring tool")
.arg(
Arg::new("interface")
.short('i')
.long("interface")
.value_name("INTERFACE")
.help("Network interface to monitor")
.required(false),
)
.arg(
Arg::new("no-localhost")
.long("no-localhost")
.help("Filter out localhost connections")
.action(clap::ArgAction::SetTrue),
)
.arg(
Arg::new("refresh-interval")
.short('r')
.long("refresh-interval")
.value_name("MILLISECONDS")
.help("UI refresh interval in milliseconds")
.value_parser(clap::value_parser!(u64))
.default_value("1000")
.required(false),
)
.arg(
Arg::new("no-dpi")
.long("no-dpi")
.help("Disable deep packet inspection")
.action(clap::ArgAction::SetTrue),
)
.arg(
Arg::new("log-level")
.short('l')
.long("log-level")
.value_name("LEVEL")
.help("Set the log level (if not provided, no logging will be enabled)")
.required(false),
)
}
+1 -1
View File
@@ -1,6 +1,6 @@
//! RustNet Monitor Library
//!
//! A high-performance, cross-platform network monitoring library built with Rust.
//! A cross-platform network monitoring library built with Rust.
pub mod app;
pub mod config;
+7 -47
View File
@@ -1,6 +1,5 @@
use anyhow::Result;
use arboard::Clipboard;
use clap::{Arg, Command};
use log::{LevelFilter, debug, error, info};
use ratatui::prelude::CrosstermBackend;
use simplelog::{Config as LogConfig, WriteLogger};
@@ -10,59 +9,20 @@ use std::path::Path;
use std::time::Duration;
mod app;
mod cli;
mod filter;
mod network;
mod ui;
fn main() -> Result<()> {
// Parse command line arguments
let matches = Command::new("rustnet")
.version(env!("CARGO_PKG_VERSION"))
.author("Network Monitor")
.about("Cross-platform network monitoring tool")
.arg(
Arg::new("interface")
.short('i')
.long("interface")
.value_name("INTERFACE")
.help("Network interface to monitor")
.required(false),
)
.arg(
Arg::new("no-localhost")
.long("no-localhost")
.help("Filter out localhost connections")
.action(clap::ArgAction::SetTrue),
)
.arg(
Arg::new("refresh-interval")
.short('r')
.long("refresh-interval")
.value_name("MILLISECONDS")
.help("UI refresh interval in milliseconds")
.value_parser(clap::value_parser!(u64))
.default_value("1000")
.required(false),
)
.arg(
Arg::new("no-dpi")
.long("no-dpi")
.help("Disable deep packet inspection")
.action(clap::ArgAction::SetTrue),
)
.arg(
Arg::new("log-level")
.short('l')
.long("log-level")
.value_name("LEVEL")
.help("Set the log level (if not provided, no logging will be enabled)")
.value_parser(clap::value_parser!(LevelFilter))
.required(false),
)
.get_matches();
let matches = cli::build_cli().get_matches();
// Set up logging only if log-level was provided
if let Some(log_level) = matches.get_one::<LevelFilter>("log-level") {
setup_logging(*log_level)?;
if let Some(log_level_str) = matches.get_one::<String>("log-level") {
let log_level = log_level_str
.parse::<LevelFilter>()
.map_err(|_| anyhow::anyhow!("Invalid log level: {}", log_level_str))?;
setup_logging(log_level)?;
}
info!("Starting RustNet Monitor");