diff --git a/src/bin/pr-metadata-validator.rs b/src/bin/pr-metadata-validator.rs
index f0cc5f0..e468bba 100644
--- a/src/bin/pr-metadata-validator.rs
+++ b/src/bin/pr-metadata-validator.rs
@@ -1,5 +1,6 @@
use std::{collections::BTreeMap, process::exit};
+use anyhow::{Context, anyhow};
use chrono::NaiveDate;
use indexmap::IndexMap;
use maplit::btreemap;
@@ -8,7 +9,7 @@ use regex::Regex;
use trainee_tracker::{
Error,
config::{CourseSchedule, CourseScheduleWithRegisterSheetId},
- course::match_prs_to_assignments,
+ course::{get_descriptor_id_for_pr, match_prs_to_assignments},
newtypes::Region,
octocrab::octocrab_for_token,
prs::get_prs,
@@ -84,6 +85,8 @@ async fn main() {
&format!("{}{}", BAD_TITLE_COMMENT_PREFIX, reason)
}
ValidationResult::UnknownRegion => UNKNOWN_REGION_COMMENT,
+ ValidationResult::WrongFiles { files } => &format!("{}{}`", WRONG_FILES, files),
+ ValidationResult::NoFiles => NO_FILES,
};
let full_message = format!(
@@ -138,12 +141,24 @@ const UNKNOWN_REGION_COMMENT: &str = r#"Your PR's title didn't contain a known r
Please check the expected title format, and make sure your region is in the correct place and spelled correctly."#;
+const WRONG_FILES: &str = r#"The changed files in this PR don't match what is expected for this task.
+
+Please check that you committed the right files for the task, and that there are no accidentally committed files from other sprints.
+
+Please review the changed files tab at the top of the page, we are only expecting changes in this directory: `"#;
+
+const NO_FILES: &str = r#"This PR is missing any submitted files.
+
+Please check that you committed the right files and pushed to the repository"#;
+
enum ValidationResult {
Ok,
BodyTemplateNotFilledOut,
CouldNotMatch,
BadTitleFormat { reason: String },
UnknownRegion,
+ WrongFiles { files: String },
+ NoFiles,
}
async fn validate_pr(
@@ -166,7 +181,7 @@ async fn validate_pr(
.iter()
.find(|pr| pr.number == pr_number)
.ok_or_else(|| {
- anyhow::anyhow!(
+ anyhow!(
"Failed to find PR {} in list of PRs for module {}",
pr_number,
module_name
@@ -234,9 +249,80 @@ async fn validate_pr(
return Ok(ValidationResult::BodyTemplateNotFilledOut);
}
+ let pr_assignment_descriptor_id = get_descriptor_id_for_pr(matched.sprints, pr_number);
+
+ match check_pr_file_changes(
+ octocrab,
+ github_org_name,
+ module_name,
+ pr_number,
+ pr_assignment_descriptor_id,
+ )
+ .await
+ {
+ Ok(Some(problem)) => return Ok(problem),
+ Ok(None) => (),
+ Err(e) => {
+ let _ = anyhow!(e);
+ }
+ }
+
Ok(ValidationResult::Ok)
}
+// Check the changed files in a pull request match what is expected for that sprint task
+async fn check_pr_file_changes(
+ octocrab: &Octocrab,
+ org_name: &str,
+ module_name: &str,
+ pr_number: u64,
+ task_issue_number: u64,
+) -> Result