From 8254df9303e9455ac7e03665e9d336bcafd6a049 Mon Sep 17 00:00:00 2001 From: Tobias Markus Date: Wed, 12 Apr 2023 16:08:35 +0200 Subject: [PATCH] Add support for building only on a single system --- README.md | 13 +++ ofborg/src/commentparser.rs | 100 ++++++++++++++++++++---- ofborg/src/systems.rs | 2 +- ofborg/src/tasks/githubcommentfilter.rs | 30 +++++++ 4 files changed, 127 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index b3c35ba6..9effe85c 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,19 @@ the Nixpkgs checkout (see also "[How does ofborg call Builds will run on all allowed machines. For more information, see the "[Trusted Users](#trusted-users)" section. +### build_system + +``` +@ofborg build_system SYSTEM list of attrs +``` + +Same as [build](#build), but restricts building to only one platform specification +instead of attempting to build on all allowed and supported systems. +This can be helpful to reduce needless builds and noise when debugging a platform-specific issue. + +Only the currently supported Nixpkgs systems can be passed to `build_system`: +`x86_64-linux`, `aarch64-linux`, `x86_64-darwin`, and `aarch64-darwin`. + ## Multiple Commands You can use multiple commands in a variety ways. Here are some valid diff --git a/ofborg/src/commentparser.rs b/ofborg/src/commentparser.rs index e5d3a39a..f816165c 100644 --- a/ofborg/src/commentparser.rs +++ b/ofborg/src/commentparser.rs @@ -1,3 +1,4 @@ +use crate::systems::System; use nom::types::CompleteStr; use tracing::warn; @@ -24,32 +25,79 @@ named!( |s: CompleteStr| !s.0.eq_ignore_ascii_case("@grahamcofborg") ) ); + named!( - parse_line_impl(CompleteStr) -> Option>, + system(CompleteStr) -> System, alt!( - do_parse!( - res: ws!(many1!(ws!(preceded!( - alt!(tag_no_case!("@grahamcofborg") | tag_no_case!("@ofborg")), - alt!( - ws!(do_parse!( - tag!("build") >> + value!(System::X8664Linux, tag!("x86_64-linux")) | + value!(System::Aarch64Linux, tag!("aarch64-linux")) | + value!(System::X8664Darwin, tag!("x86_64-darwin")) | + value!(System::Aarch64Darwin, tag!("aarch64-darwin")) + ) +); + +named!( + invocation_prefix(CompleteStr) -> CompleteStr, + alt!(tag_no_case!("@ofborg") | tag_no_case!("@grahamcofborg")) +); + +enum Command { + Eval, + Build, + BuildSystem, + Test, +} + +named!( + command_str(CompleteStr) -> Option, + alt!( + value!(Some(Command::Eval), tag!("eval")) | + value!(Some(Command::BuildSystem), tag!("build_system")) | + value!(Some(Command::Build), tag!("build")) | + value!(Some(Command::Test), tag!("test")) | + + // TODO: Currently keeping previous behaviour of ignoring unknown commands. Maybe + // it would be better to return an error so that the caller would know one of the + // commands couldn't be handled? + value!(None, many_till!(take!(1), invocation_prefix)) + ) +); + +named!( + command(CompleteStr) -> Option, + preceded!( + ws!(invocation_prefix), + switch!( ws!(command_str), + Some(Command::Build) => + ws!(do_parse!( pkgs: ws!(many1!(map!(normal_token, |s| s.0.to_owned()))) >> (Some(Instruction::Build(Subset::Nixpkgs, pkgs))) )) | + Some(Command::BuildSystem) => + ws!(do_parse!( + system: ws!(system) >> + pkgs: ws!(many1!(map!(normal_token, |s| s.0.to_owned()))) >> + (Some(Instruction::BuildOnSystem(system, Subset::Nixpkgs, pkgs))) + )) | + Some(Command::Test) => ws!(do_parse!( - tag!("test") >> tests: ws!(many1!(map!(normal_token, |s| format!("nixosTests.{}", s.0)))) >> (Some(Instruction::Build(Subset::Nixpkgs, tests))) )) | - value!(Some(Instruction::Eval), tag!("eval")) | - // TODO: Currently keeping previous behaviour of ignoring unknown commands. Maybe - // it would be better to return an error so that the caller would know one of the - // commands couldn't be handled? - value!(None, many_till!(take!(1), tag_no_case!("@grahamcofborg"))) - ) - )))) >> eof!() - >> (Some(res.into_iter().flatten().collect())) - ) | value!(None) + Some(Command::Eval) => ws!(do_parse!( (Some(Instruction::Eval)) )) | + None => do_parse!( (None) ) + ) + ) +); + +named!( + parse_line_impl(CompleteStr) -> Option>, + opt!( + do_parse!( + res: ws!(many1!(ws!(command))) + >> eof!() + >> (res.into_iter().flatten().collect()) + ) ) ); @@ -68,6 +116,7 @@ pub fn parse_line(text: &str) -> Option> { pub enum Instruction { Build(Subset, Vec), Eval, + BuildOnSystem(System, Subset, Vec), } #[allow(clippy::upper_case_acronyms)] @@ -108,6 +157,23 @@ mod tests { assert_eq!(None, parse("@grahamcofborg build")); } + #[test] + fn build_system_comment() { + assert_eq!( + Some(vec![Instruction::BuildOnSystem( + System::X8664Linux, + Subset::Nixpkgs, + vec![String::from("foo")] + ),]), + parse("@ofborg build_system x86_64-linux foo") + ); + } + + #[test] + fn unknown_system_comment() { + assert_eq!(None, parse("@ofborg build_system x86_64-foolinux foo")); + } + #[test] fn eval_comment() { assert_eq!(Some(vec![Instruction::Eval]), parse("@grahamcofborg eval")); diff --git a/ofborg/src/systems.rs b/ofborg/src/systems.rs index b6460511..433911ce 100644 --- a/ofborg/src/systems.rs +++ b/ofborg/src/systems.rs @@ -1,4 +1,4 @@ -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum System { X8664Linux, Aarch64Linux, diff --git a/ofborg/src/tasks/githubcommentfilter.rs b/ofborg/src/tasks/githubcommentfilter.rs index 73121118..fd99b13c 100644 --- a/ofborg/src/tasks/githubcommentfilter.rs +++ b/ofborg/src/tasks/githubcommentfilter.rs @@ -141,6 +141,36 @@ impl worker::SimpleWorker for GitHubCommentWorker { }, )); } + commentparser::Instruction::BuildOnSystem(system, subset, attrs) => { + if !build_destinations.contains(&system) { + continue; + }; + if subset == commentparser::Subset::NixOS && !system.can_run_nixos_tests() { + continue; + }; + + let msg = buildjob::BuildJob::new( + repo_msg.clone(), + pr_msg.clone(), + subset, + attrs, + None, + None, + format!("{}", Uuid::new_v4()), + ); + + let (exchange, routingkey) = system.as_build_destination(); + response.push(worker::publish_serde_action(exchange, routingkey, &msg)); + + response.push(worker::publish_serde_action( + Some("build-results".to_string()), + None, + &buildjob::QueuedBuildJobs { + job: msg, + architectures: vec![system.to_string()], + }, + )); + } commentparser::Instruction::Eval => { let msg = evaluationjob::EvaluationJob { repo: repo_msg.clone(),