diff options
author | Pietro Albini <pietro@pietroalbini.org> | 2019-07-17 12:06:29 +0200 |
---|---|---|
committer | Pietro Albini <pietro@pietroalbini.org> | 2019-07-17 12:06:29 +0200 |
commit | 9c657f238d9a1354536dcb0a2e89adf5dd6cef4b (patch) | |
tree | a2269b492fe462fb09a09ee89e453a07f4c30b71 /src | |
parent | 732feec5e8db47846ae2fbfe69fbf028090a809d (diff) |
add github teams in the schema and the api
This will allow synchronization tools for GitHub teams to be built. No
teams are currently configured to be synchronized.
Diffstat (limited to 'src')
-rw-r--r-- | src/schema.rs | 26 | ||||
-rw-r--r-- | src/static_api.rs | 13 | ||||
-rw-r--r-- | src/validate.rs | 29 |
3 files changed, 68 insertions, 0 deletions
diff --git a/src/schema.rs b/src/schema.rs index 570b212..779e86c 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -7,12 +7,17 @@ use std::collections::HashSet; #[serde(deny_unknown_fields, rename_all = "kebab-case")] pub(crate) struct Config { allowed_mailing_lists_domains: HashSet<String>, + allowed_github_orgs: HashSet<String>, } impl Config { pub(crate) fn allowed_mailing_lists_domains(&self) -> &HashSet<String> { &self.allowed_mailing_lists_domains } + + pub(crate) fn allowed_github_orgs(&self) -> &HashSet<String> { + &self.allowed_github_orgs + } } // This is an enum to allow two kinds of values for the email field: @@ -108,6 +113,7 @@ pub(crate) struct Team { people: TeamPeople, #[serde(default)] permissions: Permissions, + github: Option<GitHubData>, rfcbot: Option<RfcbotData>, website: Option<WebsiteData>, #[serde(default)] @@ -213,6 +219,19 @@ impl Team { pub(crate) fn permissions(&self) -> &Permissions { &self.permissions } + + pub(crate) fn github_teams(&self) -> Vec<(&str, &str)> { + if let Some(github) = &self.github { + let name = github + .name + .as_ref() + .map(|n| n.as_str()) + .unwrap_or(&self.name); + github.orgs.iter().map(|org| (org.as_str(), name)).collect() + } else { + Vec::new() + } + } } #[derive(serde_derive::Deserialize, Debug)] @@ -228,6 +247,13 @@ struct TeamPeople { include_all_team_members: bool, } +#[derive(serde::Deserialize, Debug)] +#[serde(rename_all = "kebab-case", deny_unknown_fields)] +struct GitHubData { + name: Option<String>, + orgs: Vec<String>, +} + #[derive(serde_derive::Deserialize, Debug)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] pub(crate) struct RfcbotData { diff --git a/src/static_api.rs b/src/static_api.rs index 15e1dcd..3760b4e 100644 --- a/src/static_api.rs +++ b/src/static_api.rs @@ -48,6 +48,9 @@ impl<'a> Generator<'a> { members.sort_by_key(|member| member.github.to_lowercase()); members.sort_by_key(|member| !member.is_lead); + let mut github_teams = team.github_teams(); + github_teams.sort(); + let team_data = v1::Team { name: team.name().into(), kind: if team.is_wg() { @@ -57,6 +60,16 @@ impl<'a> Generator<'a> { }, subteam_of: team.subteam_of().map(|st| st.into()), members, + github: Some(v1::TeamGitHub { + teams: github_teams + .iter() + .map(|(org, name)| v1::GitHubTeam { + org: org.to_string(), + name: name.to_string(), + }) + .collect::<Vec<_>>(), + }) + .filter(|gh| !gh.teams.is_empty()), website_data: team.website_data().map(|ws| v1::TeamWebsite { name: ws.name().into(), description: ws.description().into(), diff --git a/src/validate.rs b/src/validate.rs index 4c4ebfb..e33f391 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -23,6 +23,7 @@ static CHECKS: &[fn(&Data, &mut Vec<String>)] = &[ validate_rfcbot_labels, validate_rfcbot_exclude_members, validate_team_names, + validate_github_teams, ]; static GITHUB_CHECKS: &[fn(&Data, &GitHubApi, &mut Vec<String>)] = &[validate_github_usernames]; @@ -381,6 +382,34 @@ fn validate_team_names(data: &Data, errors: &mut Vec<String>) { }); } +/// Ensure GitHub teams are unique and in the allowed orgs +fn validate_github_teams(data: &Data, errors: &mut Vec<String>) { + let mut found = HashMap::new(); + let allowed = data.config().allowed_github_orgs(); + wrapper(data.teams(), errors, |team, errors| { + wrapper(team.github_teams().into_iter(), errors, |(org, name), _| { + if !allowed.contains(&*org) { + bail!( + "GitHub organization `{}` isn't allowed (in team `{}`)", + org, + team.name() + ); + } + if let Some(other) = found.insert((org, name), team.name()) { + bail!( + "GitHub team `{}/{}` is defined for both the `{}` and `{}` teams", + org, + name, + team.name(), + other + ); + } + Ok(()) + }); + Ok(()) + }); +} + /// Ensure there are no misspelled GitHub account names fn validate_github_usernames(data: &Data, github: &GitHubApi, errors: &mut Vec<String>) { let people = data |