Merge pull request #306 from NixOS/send-queued-messages

Send queued Checks
This commit is contained in:
Graham Christensen 2019-01-24 19:42:43 -05:00 committed by GitHub
commit 8fffcd28e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 230 additions and 499 deletions

View file

@ -1,3 +1,5 @@
use ofborg::systems::System;
pub struct ACL {
trusted_users: Vec<String>,
known_users: Vec<String>,
@ -27,21 +29,29 @@ impl ACL {
self.repos.contains(&name.to_lowercase())
}
pub fn build_job_architectures_for_user_repo(&self, user: &str, repo: &str) -> Vec<System> {
if self.can_build_unrestricted(user, repo) {
vec![
System::X8664Darwin,
System::X8664Linux,
System::Aarch64Linux,
]
} else if self.can_build_restricted(user, repo) {
vec![System::X8664Linux, System::Aarch64Linux]
} else {
vec![]
}
}
pub fn build_job_destinations_for_user_repo(
&self,
user: &str,
repo: &str,
) -> Vec<(Option<String>, Option<String>)> {
if self.can_build_unrestricted(user, repo) {
vec![(Some("build-jobs".to_owned()), None)]
} else if self.can_build_restricted(user, repo) {
vec![
(None, Some("build-inputs-x86_64-linux".to_owned())),
(None, Some("build-inputs-aarch64-linux".to_owned())),
]
} else {
vec![]
}
self.build_job_architectures_for_user_repo(user, repo)
.iter()
.map(|system| system.as_build_destination())
.collect()
}
pub fn can_build_restricted(&self, user: &str, repo: &str) -> bool {

View file

@ -45,6 +45,7 @@ pub mod nix;
pub mod notifyworker;
pub mod outpathdiff;
pub mod stats;
pub mod systems;
pub mod tagger;
pub mod tasks;
pub mod test_scratch;
@ -69,6 +70,7 @@ pub mod ofborg {
pub use notifyworker;
pub use outpathdiff;
pub use stats;
pub use systems;
pub use tagger;
pub use tasks;
pub use test_scratch;

View file

@ -13,6 +13,12 @@ pub struct BuildJob {
pub statusreport: Option<ExchangeQueue>, // (Exchange, Routing Key)
}
#[derive(Serialize, Deserialize, Debug)]
pub struct QueuedBuildJobs {
pub job: BuildJob,
pub architectures: Vec<String>,
}
pub type ExchangeQueue = (Option<Exchange>, Option<RoutingKey>);
type Exchange = String;
type RoutingKey = String;

View file

@ -1,3 +1,4 @@
use hubcaps::checks::Conclusion;
use ofborg::message::{Pr, Repo};
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
@ -9,6 +10,30 @@ pub enum BuildStatus {
UnexpectedError { err: String },
}
impl From<BuildStatus> for String {
fn from(status: BuildStatus) -> String {
match status {
BuildStatus::Skipped => "No attempt".into(),
BuildStatus::Success => "Success".into(),
BuildStatus::Failure => "Failure".into(),
BuildStatus::TimedOut => "Timed out, unknown build status".into(),
BuildStatus::UnexpectedError { ref err } => format!("Unexpected error: {}", err),
}
}
}
impl From<BuildStatus> for Conclusion {
fn from(status: BuildStatus) -> Conclusion {
match status {
BuildStatus::Skipped => Conclusion::Neutral,
BuildStatus::Success => Conclusion::Success,
BuildStatus::Failure => Conclusion::Neutral,
BuildStatus::TimedOut => Conclusion::Neutral,
BuildStatus::UnexpectedError { .. } => Conclusion::Neutral,
}
}
}
pub struct LegacyBuildResult {
pub repo: Repo,
pub pr: Pr,

20
ofborg/src/systems.rs Normal file
View file

@ -0,0 +1,20 @@
#[derive(Clone, Debug)]
pub enum System {
X8664Linux,
Aarch64Linux,
X8664Darwin,
}
impl System {
pub fn to_string(&self) -> String {
match self {
System::X8664Linux => String::from("x86_64-linux"),
System::Aarch64Linux => String::from("aarch64-linux"),
System::X8664Darwin => String::from("x86_64-darwin"),
}
}
pub fn as_build_destination(&self) -> (Option<String>, Option<String>) {
(None, Some(format!("build-inputs-{}", self.to_string())))
}
}

View file

@ -55,7 +55,7 @@ impl worker::SimpleWorker for GitHubCommentWorker {
return vec![worker::Action::Ack];
}
let build_destinations = self.acl.build_job_destinations_for_user_repo(
let build_destinations = self.acl.build_job_architectures_for_user_repo(
&job.comment.user.login,
&job.repository.full_name,
);
@ -119,9 +119,23 @@ impl worker::SimpleWorker for GitHubCommentWorker {
format!("{}", Uuid::new_v4()),
);
for (exch, rk) in build_destinations.clone() {
response.push(worker::publish_serde_action(exch, rk, &msg));
for arch in build_destinations.iter() {
let (exchange, routingkey) = arch.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: build_destinations
.iter()
.cloned()
.map(|arch| arch.to_string())
.collect(),
},
));
}
commentparser::Instruction::Eval => {
let msg = massrebuildjob::MassRebuildJob {

View file

@ -7,7 +7,9 @@ use amqp::protocol::basic::{BasicProperties, Deliver};
use chrono::{DateTime, Utc};
use hubcaps;
use hubcaps::checks::{CheckRunOptions, CheckRunState, Conclusion, Output};
use message::buildjob::{BuildJob, QueuedBuildJobs};
use ofborg::message::buildresult::{BuildResult, BuildStatus, LegacyBuildResult};
use ofborg::message::Repo;
use ofborg::worker;
pub struct GitHubCommentPoster {
@ -20,8 +22,29 @@ impl GitHubCommentPoster {
}
}
pub enum PostableEvent {
BuildQueued(QueuedBuildJobs),
BuildFinished(BuildResult),
}
impl PostableEvent {
fn from(bytes: &[u8]) -> Result<PostableEvent, String> {
match serde_json::from_slice::<QueuedBuildJobs>(bytes) {
Ok(e) => Ok(PostableEvent::BuildQueued(e)),
Err(_) => match serde_json::from_slice::<BuildResult>(bytes) {
Ok(e) => Ok(PostableEvent::BuildFinished(e)),
Err(e) => Err(format!(
"Failed to deserialize PostableEvent: {:?}, err: {:}",
String::from_utf8_lossy(&bytes.to_vec()),
e
)),
},
}
}
}
impl worker::SimpleWorker for GitHubCommentPoster {
type J = BuildResult;
type J = PostableEvent;
fn msg_to_job(
&mut self,
@ -29,46 +52,79 @@ impl worker::SimpleWorker for GitHubCommentPoster {
_: &BasicProperties,
body: &[u8],
) -> Result<Self::J, String> {
match serde_json::from_slice(body) {
Ok(e) => Ok(e),
Err(e) => Err(format!(
"Failed to deserialize BuildResult: {:?}, err: {:}",
String::from_utf8_lossy(&body.to_vec()),
e
)),
}
PostableEvent::from(body)
}
fn consumer(&mut self, job: &BuildResult) -> worker::Actions {
let result = job.legacy();
let comment = hubcaps::comments::CommentOptions {
body: result_to_comment(&result),
};
let check = result_to_check(&result, Utc::now());
println!(":{:?}", check);
println!(":{:?}", comment);
fn consumer(&mut self, job: &PostableEvent) -> worker::Actions {
let mut checks: Vec<CheckRunOptions> = vec![];
let repo: Repo;
let check_create_attempt = self
.github
.repo(result.repo.owner.clone(), result.repo.name.clone())
.checkruns()
.create(&check);
match job {
PostableEvent::BuildQueued(queued_job) => {
repo = queued_job.job.repo.clone();
for architecture in queued_job.architectures.iter() {
checks.push(job_to_check(&queued_job.job, &architecture, Utc::now()));
}
}
PostableEvent::BuildFinished(finished_job) => {
let result = finished_job.legacy();
repo = result.repo.clone();
checks.push(result_to_check(&result, Utc::now()));
}
}
match check_create_attempt {
Ok(comment) => info!("Successfully sent {:?} to {}", comment, result.pr.number,),
Err(err) => info!("Failed to send check {:?} to {}", err, result.pr.number,),
for check in checks {
println!(":{:?}", check);
let check_create_attempt = self
.github
.repo(repo.owner.clone(), repo.name.clone())
.checkruns()
.create(&check);
match check_create_attempt {
Ok(_) => info!("Successfully sent."),
Err(err) => info!("Failed to send check {:?}", err),
}
}
vec![worker::Action::Ack]
}
}
fn job_to_check(job: &BuildJob, architecture: &str, timestamp: DateTime<Utc>) -> CheckRunOptions {
let mut all_attrs: Vec<String> = job.attrs.clone();
all_attrs.sort();
if all_attrs.is_empty() {
all_attrs = vec![String::from("(unknown attributes)")];
}
CheckRunOptions {
name: format!("{} on {}", all_attrs.join(", "), architecture),
actions: None,
completed_at: None,
started_at: Some(timestamp.to_rfc3339_opts(chrono::SecondsFormat::Secs, true)),
conclusion: None,
details_url: Some(format!(
"https://logs.nix.ci/?key={}/{}.{}",
&job.repo.owner.to_lowercase(),
&job.repo.name.to_lowercase(),
job.pr.number,
)),
external_id: None,
head_sha: job.pr.head_sha.clone(),
output: None,
status: Some(CheckRunState::Queued),
}
}
fn result_to_check(result: &LegacyBuildResult, timestamp: DateTime<Utc>) -> CheckRunOptions {
let mut all_attrs: Vec<String> =
vec![result.attempted_attrs.clone(), result.skipped_attrs.clone()]
.into_iter()
.map(|opt| opt.unwrap_or_else(|| vec![]))
.flat_map(|list| list.into_iter().map(|attr| format!("-A {}", attr)))
.flat_map(|list| list.into_iter())
.collect();
all_attrs.sort();
@ -76,13 +132,7 @@ fn result_to_check(result: &LegacyBuildResult, timestamp: DateTime<Utc>) -> Chec
all_attrs = vec![String::from("(unknown attributes)")];
}
let conclusion = match result.status {
BuildStatus::Skipped => Conclusion::Neutral,
BuildStatus::Success => Conclusion::Success,
BuildStatus::Failure => Conclusion::Neutral,
BuildStatus::TimedOut => Conclusion::Neutral,
BuildStatus::UnexpectedError { .. } => Conclusion::Neutral,
};
let conclusion: Conclusion = result.status.clone().into();
let mut summary: Vec<String> = vec![];
if let Some(ref attempted) = result.attempted_attrs {
@ -118,11 +168,7 @@ fn result_to_check(result: &LegacyBuildResult, timestamp: DateTime<Utc>) -> Chec
};
CheckRunOptions {
name: format!(
"nix-build {} --argstr system {}",
all_attrs.join(" "),
result.system
),
name: format!("{} on {}", all_attrs.join(", "), result.system),
actions: None,
completed_at: Some(timestamp.to_rfc3339_opts(chrono::SecondsFormat::Secs, true)),
started_at: None,
@ -142,68 +188,12 @@ fn result_to_check(result: &LegacyBuildResult, timestamp: DateTime<Utc>) -> Chec
images: None,
summary: summary.join("\n"),
text: Some(text),
title: "Build Results".to_string(),
title: result.status.clone().into(),
}),
status: Some(CheckRunState::Completed),
}
}
fn result_to_comment(result: &LegacyBuildResult) -> String {
let mut reply: Vec<String> = vec![];
let log_link = if !result.output.is_empty() {
format!(
" [(full log)](https://logs.nix.ci/?key={}/{}.{}&attempt_id={})",
&result.repo.owner.to_lowercase(),
&result.repo.name.to_lowercase(),
result.pr.number,
result.attempt_id,
)
} else {
"".to_owned()
};
reply.push(format!("<!--REQUEST_ID={}-->", result.request_id));
reply.push(format!(
"{} on {}{}",
(match result.status {
BuildStatus::Skipped => "No attempt".into(),
BuildStatus::Success => "Success".into(),
BuildStatus::Failure => "Failure".into(),
BuildStatus::TimedOut => "Timed out, unknown build status".into(),
BuildStatus::UnexpectedError { ref err } => format!("Unexpected error: {}", err),
}),
result.system,
log_link
));
reply.push("".to_owned());
if let Some(ref attempted) = result.attempted_attrs {
reply.extend(list_segment("Attempted", &attempted));
}
if let Some(ref skipped) = result.skipped_attrs {
reply.extend(list_segment(
&format!(
"The following builds were skipped because they don't evaluate on {}",
result.system
),
&skipped,
));
}
if !result.output.is_empty() {
reply.extend(partial_log_segment(&result.output));
reply.push("".to_owned());
reply.push("".to_owned());
} else {
reply.push("No partial log is available.".to_owned());
reply.push("".to_owned());
}
reply.join("\n")
}
fn list_segment(name: &str, things: &[String]) -> Vec<String> {
let mut reply: Vec<String> = vec![];
@ -215,19 +205,6 @@ fn list_segment(name: &str, things: &[String]) -> Vec<String> {
reply
}
fn partial_log_segment(output: &[String]) -> Vec<String> {
let mut reply: Vec<String> = vec![];
reply.push("<details><summary>Partial log (click to expand)</summary><p>".to_owned());
reply.push("".to_owned());
reply.push("```".to_owned());
reply.extend(output.to_vec());
reply.push("```".to_owned());
reply.push("</p></details>".to_owned());
reply
}
#[cfg(test)]
mod tests {
use super::*;
@ -235,8 +212,8 @@ mod tests {
use message::{Pr, Repo};
#[test]
pub fn test_passing_build() {
let result = LegacyBuildResult {
pub fn test_queued_build() {
let job = BuildJob {
repo: Repo {
clone_url: "https://github.com/nixos/nixpkgs.git".to_owned(),
full_name: "NixOS/nixpkgs".to_owned(),
@ -248,366 +225,29 @@ mod tests {
number: 2345,
target_branch: Some("master".to_owned()),
},
output: vec![
"make[2]: Entering directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'".to_owned(),
"make[2]: Nothing to be done for 'install'.".to_owned(),
"make[2]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'".to_owned(),
"make[1]: Nothing to be done for 'install-target'.".to_owned(),
"make[1]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1'".to_owned(),
"removed '/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1/share/info/bfd.info'".to_owned(),
"post-installation fixup".to_owned(),
"strip is /nix/store/5a88zk3jgimdmzg8rfhvm93kxib3njf9-cctools-binutils-darwin/bin/strip".to_owned(),
"patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1".to_owned(),
"/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1".to_owned(),
],
attempt_id: "neatattemptid".to_owned(),
logs: None,
statusreport: None,
subset: None,
request_id: "bogus-request-id".to_owned(),
system: "x86_64-linux".to_owned(),
attempted_attrs: Some(vec!["foo".to_owned()]),
skipped_attrs: Some(vec!["bar".to_owned()]),
status: BuildStatus::Success,
attrs: vec!["foo".to_owned(), "bar".to_owned()],
};
let timestamp = Utc.ymd(2023, 4, 20).and_hms(13, 37, 42);
assert_eq!(
&result_to_comment(&result),
"<!--REQUEST_ID=bogus-request-id-->
Success on x86_64-linux [(full log)](https://logs.nix.ci/?key=nixos/nixpkgs.2345&attempt_id=neatattemptid)
Attempted: foo
The following builds were skipped because they don't evaluate on x86_64-linux: bar
<details><summary>Partial log (click to expand)</summary><p>
```
make[2]: Entering directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'
make[1]: Nothing to be done for 'install-target'.
make[1]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1'
removed '/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1/share/info/bfd.info'
post-installation fixup
strip is /nix/store/5a88zk3jgimdmzg8rfhvm93kxib3njf9-cctools-binutils-darwin/bin/strip
patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1
/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1
```
</p></details>
"
);
}
#[test]
pub fn test_failing_build() {
let result = LegacyBuildResult {
repo: Repo {
clone_url: "https://github.com/nixos/nixpkgs.git".to_owned(),
full_name: "NixOS/nixpkgs".to_owned(),
owner: "NixOS".to_owned(),
name: "nixpkgs".to_owned(),
},
pr: Pr {
head_sha: "abc123".to_owned(),
number: 2345,
target_branch: Some("master".to_owned()),
},
output: vec![
"make[2]: Entering directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'".to_owned(),
"make[2]: Nothing to be done for 'install'.".to_owned(),
"make[2]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'".to_owned(),
"make[1]: Nothing to be done for 'install-target'.".to_owned(),
"make[1]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1'".to_owned(),
"removed '/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1/share/info/bfd.info'".to_owned(),
"post-installation fixup".to_owned(),
"strip is /nix/store/5a88zk3jgimdmzg8rfhvm93kxib3njf9-cctools-binutils-darwin/bin/strip".to_owned(),
"patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1".to_owned(),
"/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1".to_owned(),
],
attempt_id: "neatattemptid".to_owned(),
request_id: "bogus-request-id".to_owned(),
system: "x86_64-linux".to_owned(),
attempted_attrs: Some(vec!["foo".to_owned()]),
skipped_attrs: None,
status: BuildStatus::Failure,
};
assert_eq!(
&result_to_comment(&result),
"<!--REQUEST_ID=bogus-request-id-->
Failure on x86_64-linux [(full log)](https://logs.nix.ci/?key=nixos/nixpkgs.2345&attempt_id=neatattemptid)
Attempted: foo
<details><summary>Partial log (click to expand)</summary><p>
```
make[2]: Entering directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'
make[1]: Nothing to be done for 'install-target'.
make[1]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1'
removed '/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1/share/info/bfd.info'
post-installation fixup
strip is /nix/store/5a88zk3jgimdmzg8rfhvm93kxib3njf9-cctools-binutils-darwin/bin/strip
patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1
/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1
```
</p></details>
"
);
}
#[test]
pub fn test_timedout_build() {
let result = LegacyBuildResult {
repo: Repo {
clone_url: "https://github.com/nixos/nixpkgs.git".to_owned(),
full_name: "NixOS/nixpkgs".to_owned(),
owner: "NixOS".to_owned(),
name: "nixpkgs".to_owned(),
},
pr: Pr {
head_sha: "abc123".to_owned(),
number: 2345,
target_branch: Some("master".to_owned()),
},
output: vec![
"make[2]: Entering directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'".to_owned(),
"make[2]: Nothing to be done for 'install'.".to_owned(),
"make[2]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'".to_owned(),
"make[1]: Nothing to be done for 'install-target'.".to_owned(),
"make[1]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1'".to_owned(),
"removed '/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1/share/info/bfd.info'".to_owned(),
"post-installation fixup".to_owned(),
"building of '/nix/store/l1limh50lx2cx45yb2gqpv7k8xl1mik2-gdb-8.1.drv' timed out after 1 seconds".to_owned(),
"error: build of '/nix/store/l1limh50lx2cx45yb2gqpv7k8xl1mik2-gdb-8.1.drv' failed".to_owned(),
],
attempt_id: "neatattemptid".to_owned(),
request_id: "bogus-request-id".to_owned(),
system: "x86_64-linux".to_owned(),
attempted_attrs: Some(vec!["foo".to_owned()]),
skipped_attrs: None,
status: BuildStatus::TimedOut,
};
assert_eq!(
&result_to_comment(&result),
"<!--REQUEST_ID=bogus-request-id-->
Timed out, unknown build status on x86_64-linux [(full log)](https://logs.nix.ci/?key=nixos/nixpkgs.2345&attempt_id=neatattemptid)
Attempted: foo
<details><summary>Partial log (click to expand)</summary><p>
```
make[2]: Entering directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'
make[1]: Nothing to be done for 'install-target'.
make[1]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1'
removed '/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1/share/info/bfd.info'
post-installation fixup
building of '/nix/store/l1limh50lx2cx45yb2gqpv7k8xl1mik2-gdb-8.1.drv' timed out after 1 seconds
error: build of '/nix/store/l1limh50lx2cx45yb2gqpv7k8xl1mik2-gdb-8.1.drv' failed
```
</p></details>
"
);
}
#[test]
pub fn test_passing_build_unspecified_attributes() {
let result = LegacyBuildResult {
repo: Repo {
clone_url: "https://github.com/nixos/nixpkgs.git".to_owned(),
full_name: "NixOS/nixpkgs".to_owned(),
owner: "NixOS".to_owned(),
name: "nixpkgs".to_owned(),
},
pr: Pr {
head_sha: "abc123".to_owned(),
number: 2345,
target_branch: Some("master".to_owned()),
},
output: vec![
"make[2]: Entering directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'".to_owned(),
"make[2]: Nothing to be done for 'install'.".to_owned(),
"make[2]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'".to_owned(),
"make[1]: Nothing to be done for 'install-target'.".to_owned(),
"make[1]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1'".to_owned(),
"removed '/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1/share/info/bfd.info'".to_owned(),
"post-installation fixup".to_owned(),
"strip is /nix/store/5a88zk3jgimdmzg8rfhvm93kxib3njf9-cctools-binutils-darwin/bin/strip".to_owned(),
"patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1".to_owned(),
"/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1".to_owned(),
],
attempt_id: "neatattemptid".to_owned(),
request_id: "bogus-request-id".to_owned(),
system: "x86_64-linux".to_owned(),
attempted_attrs: None,
skipped_attrs: None,
status: BuildStatus::Success,
};
assert_eq!(
&result_to_comment(&result),
"<!--REQUEST_ID=bogus-request-id-->
Success on x86_64-linux [(full log)](https://logs.nix.ci/?key=nixos/nixpkgs.2345&attempt_id=neatattemptid)
<details><summary>Partial log (click to expand)</summary><p>
```
make[2]: Entering directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'
make[1]: Nothing to be done for 'install-target'.
make[1]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1'
removed '/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1/share/info/bfd.info'
post-installation fixup
strip is /nix/store/5a88zk3jgimdmzg8rfhvm93kxib3njf9-cctools-binutils-darwin/bin/strip
patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1
/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1
```
</p></details>
"
);
}
#[test]
pub fn test_failing_build_unspecified_attributes() {
let result = LegacyBuildResult {
repo: Repo {
clone_url: "https://github.com/nixos/nixpkgs.git".to_owned(),
full_name: "NixOS/nixpkgs".to_owned(),
owner: "NixOS".to_owned(),
name: "nixpkgs".to_owned(),
},
pr: Pr {
head_sha: "abc123".to_owned(),
number: 2345,
target_branch: Some("master".to_owned()),
},
output: vec![
"make[2]: Entering directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'".to_owned(),
"make[2]: Nothing to be done for 'install'.".to_owned(),
"make[2]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'".to_owned(),
"make[1]: Nothing to be done for 'install-target'.".to_owned(),
"make[1]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1'".to_owned(),
"removed '/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1/share/info/bfd.info'".to_owned(),
"post-installation fixup".to_owned(),
"strip is /nix/store/5a88zk3jgimdmzg8rfhvm93kxib3njf9-cctools-binutils-darwin/bin/strip".to_owned(),
"patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1".to_owned(),
"/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1".to_owned(),
],
attempt_id: "neatattemptid".to_owned(),
request_id: "bogus-request-id".to_owned(),
system: "x86_64-linux".to_owned(),
attempted_attrs: None,
skipped_attrs: None,
status: BuildStatus::Failure,
};
assert_eq!(
&result_to_comment(&result),
"<!--REQUEST_ID=bogus-request-id-->
Failure on x86_64-linux [(full log)](https://logs.nix.ci/?key=nixos/nixpkgs.2345&attempt_id=neatattemptid)
<details><summary>Partial log (click to expand)</summary><p>
```
make[2]: Entering directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1/readline'
make[1]: Nothing to be done for 'install-target'.
make[1]: Leaving directory '/private/tmp/nix-build-gdb-8.1.drv-0/gdb-8.1'
removed '/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1/share/info/bfd.info'
post-installation fixup
strip is /nix/store/5a88zk3jgimdmzg8rfhvm93kxib3njf9-cctools-binutils-darwin/bin/strip
patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1
/nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29-gdb-8.1
```
</p></details>
"
);
}
#[test]
pub fn test_no_attempt() {
let result = LegacyBuildResult {
repo: Repo {
clone_url: "https://github.com/nixos/nixpkgs.git".to_owned(),
full_name: "NixOS/nixpkgs".to_owned(),
owner: "NixOS".to_owned(),
name: "nixpkgs".to_owned(),
},
pr: Pr {
head_sha: "abc123".to_owned(),
number: 2345,
target_branch: Some("master".to_owned()),
},
output: vec!["foo".to_owned()],
attempt_id: "foo".to_owned(),
request_id: "bogus-request-id".to_owned(),
system: "x86_64-linux".to_owned(),
attempted_attrs: None,
skipped_attrs: Some(vec!["not-attempted".to_owned()]),
status: BuildStatus::Skipped,
};
assert_eq!(
&result_to_comment(&result),
"<!--REQUEST_ID=bogus-request-id-->
No attempt on x86_64-linux [(full log)](https://logs.nix.ci/?key=nixos/nixpkgs.2345&attempt_id=foo)
The following builds were skipped because they don't evaluate on x86_64-linux: not-attempted
<details><summary>Partial log (click to expand)</summary><p>
```
foo
```
</p></details>
"
);
}
#[test]
pub fn test_no_attempt_no_log() {
let result = LegacyBuildResult {
repo: Repo {
clone_url: "https://github.com/nixos/nixpkgs.git".to_owned(),
full_name: "NixOS/nixpkgs".to_owned(),
owner: "NixOS".to_owned(),
name: "nixpkgs".to_owned(),
},
pr: Pr {
head_sha: "abc123".to_owned(),
number: 2345,
target_branch: Some("master".to_owned()),
},
output: vec![],
attempt_id: "foo".to_owned(),
request_id: "bogus-request-id".to_owned(),
system: "x86_64-linux".to_owned(),
attempted_attrs: None,
skipped_attrs: Some(vec!["not-attempted".to_owned()]),
status: BuildStatus::Skipped,
};
assert_eq!(
&result_to_comment(&result),
"<!--REQUEST_ID=bogus-request-id-->
No attempt on x86_64-linux
The following builds were skipped because they don't evaluate on x86_64-linux: not-attempted
No partial log is available.
"
job_to_check(&job, "x86_64-linux", timestamp),
CheckRunOptions {
name: "bar, foo on x86_64-linux".to_string(),
actions: None,
started_at: Some("2023-04-20T13:37:42Z".to_string()),
completed_at: None,
status: Some(CheckRunState::Queued),
conclusion: None,
details_url: Some("https://logs.nix.ci/?key=nixos/nixpkgs.2345".to_string()),
external_id: None,
head_sha: "abc123".to_string(),
output: None,
}
);
}
@ -650,7 +290,7 @@ No partial log is available.
assert_eq!(
result_to_check(&result, timestamp),
CheckRunOptions {
name: "nix-build -A bar -A foo --argstr system x86_64-linux".to_string(),
name: "bar, foo on x86_64-linux".to_string(),
actions: None,
started_at: None,
completed_at: Some("2023-04-20T13:37:42Z".to_string()),
@ -663,7 +303,7 @@ No partial log is available.
external_id: Some("neatattemptid".to_string()),
head_sha: "abc123".to_string(),
output: Some(Output {
title: "Build Results".to_string(),
title: "Success".to_string(),
summary: "Attempted: foo
The following builds were skipped because they don't evaluate on x86_64-linux: bar
@ -732,7 +372,7 @@ patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29
assert_eq!(
result_to_check(&result, timestamp),
CheckRunOptions {
name: "nix-build -A foo --argstr system x86_64-linux".to_string(),
name: "foo on x86_64-linux".to_string(),
actions: None,
started_at: None,
completed_at: Some("2023-04-20T13:37:42Z".to_string()),
@ -745,7 +385,7 @@ patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29
external_id: Some("neatattemptid".to_string()),
head_sha: "abc123".to_string(),
output: Some(Output {
title: "Build Results".to_string(),
title: "Failure".to_string(),
summary: "Attempted: foo
"
.to_string(),
@ -811,7 +451,7 @@ patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29
assert_eq!(
result_to_check(&result, timestamp),
CheckRunOptions {
name: "nix-build -A foo --argstr system x86_64-linux".to_string(),
name: "foo on x86_64-linux".to_string(),
actions: None,
started_at: None,
completed_at: Some("2023-04-20T13:37:42Z".to_string()),
@ -824,7 +464,7 @@ patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29
external_id: Some("neatattemptid".to_string()),
head_sha: "abc123".to_string(),
output: Some(Output {
title: "Build Results".to_string(),
title: "Timed out, unknown build status".to_string(),
summary: "Attempted: foo
Build timed out."
@ -891,7 +531,7 @@ error: build of '/nix/store/l1limh50lx2cx45yb2gqpv7k8xl1mik2-gdb-8.1.drv' failed
assert_eq!(
result_to_check(&result, timestamp),
CheckRunOptions {
name: "nix-build (unknown attributes) --argstr system x86_64-linux".to_string(),
name: "(unknown attributes) on x86_64-linux".to_string(),
actions: None,
started_at: None,
completed_at: Some("2023-04-20T13:37:42Z".to_string()),
@ -904,7 +544,7 @@ error: build of '/nix/store/l1limh50lx2cx45yb2gqpv7k8xl1mik2-gdb-8.1.drv' failed
external_id: Some("neatattemptid".to_string()),
head_sha: "abc123".to_string(),
output: Some(Output {
title: "Build Results".to_string(),
title: "Success".to_string(),
summary: "".to_string(),
text: Some(
"## Partial log
@ -969,7 +609,7 @@ patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29
assert_eq!(
result_to_check(&result, timestamp),
CheckRunOptions {
name: "nix-build (unknown attributes) --argstr system x86_64-linux".to_string(),
name: "(unknown attributes) on x86_64-linux".to_string(),
actions: None,
started_at: None,
completed_at: Some("2023-04-20T13:37:42Z".to_string()),
@ -982,7 +622,7 @@ patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29
external_id: Some("neatattemptid".to_string()),
head_sha: "abc123".to_string(),
output: Some(Output {
title: "Build Results".to_string(),
title: "Failure".to_string(),
summary: "".to_string(),
text: Some(
"## Partial log
@ -1036,7 +676,7 @@ patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29
assert_eq!(
result_to_check(&result, timestamp),
CheckRunOptions {
name: "nix-build -A not-attempted --argstr system x86_64-linux".to_string(),
name: "not-attempted on x86_64-linux".to_string(),
actions: None,
started_at: None,
completed_at: Some("2023-04-20T13:37:42Z".to_string()),
@ -1046,7 +686,7 @@ patching script interpreter paths in /nix/store/pcja75y9isdvgz5i00pkrpif9rxzxc29
external_id: Some("neatattemptid".to_string()),
head_sha: "abc123".to_string(),
output: Some(Output {
title: "Build Results".to_string(),
title: "No attempt".to_string(),
summary: "The following builds were skipped because they don\'t evaluate on x86_64-linux: not-attempted
".to_string(),
text: Some("## Partial log
@ -1089,7 +729,7 @@ foo
assert_eq!(
result_to_check(&result, timestamp),
CheckRunOptions {
name: "nix-build -A not-attempted --argstr system x86_64-linux".to_string(),
name: "not-attempted on x86_64-linux".to_string(),
actions: None,
started_at: None,
completed_at: Some("2023-04-20T13:37:42Z".to_string()),
@ -1099,7 +739,7 @@ foo
external_id: Some("neatattemptid".to_string()),
head_sha: "abc123".to_string(),
output: Some(Output {
title: "Build Results".to_string(),
title: "No attempt".to_string(),
summary: "The following builds were skipped because they don\'t evaluate on x86_64-linux: not-attempted
".to_string(),
text: Some("No partial log is available.".to_string()),

View file

@ -18,6 +18,7 @@ use ofborg::nix;
use ofborg::outpathdiff::{OutPathDiff, OutPaths};
use ofborg::stats;
use ofborg::stats::Event;
use ofborg::systems;
use ofborg::tagger::{PathsTagger, PkgsAddedRemovedTagger, RebuildTagger, StdenvTagger};
use ofborg::worker;
use std::collections::HashMap;
@ -123,7 +124,7 @@ impl<E: stats::SysEvents + 'static> worker::SimpleWorker for MassRebuildWorker<E
let pull = pulls.get(job.pr.number);
let issue = repo.issue(job.pr.number);
let auto_schedule_build_archs: Vec<buildjob::ExchangeQueue>;
let auto_schedule_build_archs: Vec<systems::System>;
match issue.get() {
Ok(iss) => {
@ -136,9 +137,10 @@ impl<E: stats::SysEvents + 'static> worker::SimpleWorker for MassRebuildWorker<E
if issue_is_wip(&iss) {
auto_schedule_build_archs = vec![];
} else {
auto_schedule_build_archs = self
.acl
.build_job_destinations_for_user_repo(&iss.user.login, &job.repo.full_name);
auto_schedule_build_archs = self.acl.build_job_architectures_for_user_repo(
&iss.user.login,
&job.repo.full_name,
);
}
}
Err(e) => {
@ -464,9 +466,21 @@ impl<E: stats::SysEvents + 'static> worker::SimpleWorker for MassRebuildWorker<E
None,
format!("{}", Uuid::new_v4()),
);
for (dest, rk) in auto_schedule_build_archs {
response.push(worker::publish_serde_action(dest, rk, &msg));
for arch in auto_schedule_build_archs.iter() {
let (exchange, routingkey) = arch.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: auto_schedule_build_archs
.into_iter()
.map(|arch| arch.to_string())
.collect(),
},
));
}
}
Err(mut out) => {