Skip to content

Commit

Permalink
Merge pull request #1730 from meysam81/master
Browse files Browse the repository at this point in the history
feat: validate proposed change(s) in triagebot.toml for PRs ✨
  • Loading branch information
ehuss authored Jan 22, 2024
2 parents 92c3399 + 252acb2 commit 7a497a0
Show file tree
Hide file tree
Showing 8 changed files with 231 additions and 15 deletions.
77 changes: 71 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ hex = "0.4"
parser = { path = "parser" }
rust_team_data = { git = "https://github.com/rust-lang/team" }
glob = "0.3.0"
toml = "0.5.1"
toml = "0.8.8"
hyper = { version = "0.14.4", features = ["server", "stream"]}
tokio = { version = "1.7.1", features = ["macros", "time", "rt"] }
futures = { version = "0.3", default-features = false, features = ["std"] }
Expand Down
36 changes: 34 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::sync::{Arc, RwLock};
use std::time::{Duration, Instant};
use tracing as log;

static CONFIG_FILE_NAME: &str = "triagebot.toml";
pub(crate) static CONFIG_FILE_NAME: &str = "triagebot.toml";
const REFRESH_EVERY: Duration = Duration::from_secs(2 * 60); // Every two minutes

lazy_static::lazy_static! {
Expand All @@ -17,6 +17,7 @@ lazy_static::lazy_static! {

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
pub(crate) struct Config {
pub(crate) relabel: Option<RelabelConfig>,
pub(crate) assign: Option<AssignConfig>,
Expand All @@ -35,9 +36,13 @@ pub(crate) struct Config {
pub(crate) note: Option<NoteConfig>,
pub(crate) mentions: Option<MentionsConfig>,
pub(crate) no_merges: Option<NoMergesConfig>,
// We want this validation to run even without the entry in the config file
#[serde(default = "ValidateConfig::default")]
pub(crate) validate_config: Option<ValidateConfig>,
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct NominateConfig {
// team name -> label
pub(crate) teams: HashMap<String, String>,
Expand Down Expand Up @@ -68,6 +73,7 @@ impl PingConfig {
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct PingTeamConfig {
pub(crate) message: String,
#[serde(default)]
Expand All @@ -76,6 +82,7 @@ pub(crate) struct PingTeamConfig {
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct AssignConfig {
/// If `true`, then posts a warning comment if the PR is opened against a
/// different branch than the default (usually master or main).
Expand Down Expand Up @@ -105,6 +112,7 @@ impl AssignConfig {
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct NoMergesConfig {
/// No action will be taken on PRs with these substrings in the title.
#[serde(default)]
Expand All @@ -121,6 +129,7 @@ pub(crate) struct NoMergesConfig {
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct NoteConfig {
#[serde(default)]
_empty: (),
Expand All @@ -133,6 +142,7 @@ pub(crate) struct MentionsConfig {
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct MentionsPathConfig {
pub(crate) message: Option<String>,
#[serde(default)]
Expand All @@ -141,22 +151,34 @@ pub(crate) struct MentionsPathConfig {

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
pub(crate) struct RelabelConfig {
#[serde(default)]
pub(crate) allow_unauthenticated: Vec<String>,
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct ShortcutConfig {
#[serde(default)]
_empty: (),
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct PrioritizeConfig {
pub(crate) label: String,
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
pub(crate) struct ValidateConfig {}

impl ValidateConfig {
fn default() -> Option<Self> {
Some(ValidateConfig {})
}
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
pub(crate) struct AutolabelConfig {
#[serde(flatten)]
Expand All @@ -176,6 +198,7 @@ impl AutolabelConfig {
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct AutolabelLabelConfig {
#[serde(default)]
pub(crate) trigger_labels: Vec<String>,
Expand All @@ -196,6 +219,7 @@ pub(crate) struct NotifyZulipConfig {
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct NotifyZulipLabelConfig {
pub(crate) zulip_stream: u64,
pub(crate) topic: String,
Expand All @@ -208,6 +232,7 @@ pub(crate) struct NotifyZulipLabelConfig {
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct MajorChangeConfig {
/// A username (typically a group, e.g. T-lang) to ping on Zulip for newly
/// opened proposals.
Expand Down Expand Up @@ -243,18 +268,22 @@ impl MajorChangeConfig {
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct GlacierConfig {}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct CloseConfig {}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct ReviewSubmittedConfig {
pub(crate) review_labels: Vec<String>,
pub(crate) reviewed_label: String,
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct ReviewRequestedConfig {
pub(crate) remove_labels: Vec<String>,
pub(crate) add_labels: Vec<String>,
Expand All @@ -280,6 +309,7 @@ pub(crate) async fn get(

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
pub(crate) struct GitHubReleasesConfig {
pub(crate) format: ChangelogFormat,
pub(crate) project_name: String,
Expand Down Expand Up @@ -307,7 +337,8 @@ async fn get_fresh_config(
.await
.map_err(|e| ConfigurationError::Http(Arc::new(e)))?
.ok_or(ConfigurationError::Missing)?;
let config = Arc::new(toml::from_slice::<Config>(&contents).map_err(ConfigurationError::Toml)?);
let contents = String::from_utf8_lossy(&*contents);
let config = Arc::new(toml::from_str::<Config>(&contents).map_err(ConfigurationError::Toml)?);
log::debug!("fresh configuration for {}: {:?}", repo.full_name, config);
Ok(config)
}
Expand Down Expand Up @@ -431,6 +462,7 @@ mod tests {
review_requested: None,
mentions: None,
no_merges: None,
validate_config: Some(ValidateConfig {}),
}
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/github.rs
Original file line number Diff line number Diff line change
Expand Up @@ -999,7 +999,7 @@ struct PullRequestEventFields {}

#[derive(Clone, Debug, serde::Deserialize)]
pub struct CommitBase {
sha: String,
pub sha: String,
#[serde(rename = "ref")]
pub git_ref: String,
pub repo: Repository,
Expand Down
2 changes: 2 additions & 0 deletions src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ mod rfc_helper;
pub mod rustc_commits;
mod shortcut;
pub mod types_planning_updates;
mod validate_config;

pub async fn handle(ctx: &Context, event: &Event) -> Vec<HandlerError> {
let config = config::get(&ctx.github, event.repo()).await;
Expand Down Expand Up @@ -166,6 +167,7 @@ issue_handlers! {
no_merges,
notify_zulip,
review_requested,
validate_config,
}

macro_rules! command_handlers {
Expand Down
8 changes: 4 additions & 4 deletions src/handlers/assign/tests/tests_candidates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use super::super::*;

/// Basic test function for testing `candidate_reviewers_from_names`.
fn test_from_names(
teams: Option<toml::Value>,
config: toml::Value,
teams: Option<toml::Table>,
config: toml::Table,
issue: serde_json::Value,
names: &[&str],
expected: Result<&[&str], FindReviewerError>,
Expand All @@ -32,8 +32,8 @@ fn test_from_names(

/// Convert the simplified input in preparation for `candidate_reviewers_from_names`.
fn convert_simplified(
teams: Option<toml::Value>,
config: toml::Value,
teams: Option<toml::Table>,
config: toml::Table,
issue: serde_json::Value,
) -> (Teams, AssignConfig, Issue) {
// Convert the simplified team config to a real team config.
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/assign/tests/tests_from_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::config::AssignConfig;
use crate::github::parse_diff;
use std::fmt::Write;

fn test_from_diff(diff: &str, config: toml::Value, expected: &[&str]) {
fn test_from_diff(diff: &str, config: toml::Table, expected: &[&str]) {
let files = parse_diff(diff);
let aconfig: AssignConfig = config.try_into().unwrap();
assert_eq!(
Expand Down
Loading

0 comments on commit 7a497a0

Please sign in to comment.