summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPietro Albini <pietro@pietroalbini.org>2019-07-17 12:06:29 +0200
committerPietro Albini <pietro@pietroalbini.org>2019-07-17 12:06:29 +0200
commit9c657f238d9a1354536dcb0a2e89adf5dd6cef4b (patch)
treea2269b492fe462fb09a09ee89e453a07f4c30b71 /src
parent732feec5e8db47846ae2fbfe69fbf028090a809d (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.rs26
-rw-r--r--src/static_api.rs13
-rw-r--r--src/validate.rs29
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