-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add functionality to sync org members on GitHub #91
base: master
Are you sure you want to change the base?
Conversation
Right now, the PR is incomplete, and I wanted to check in with you, @marcoieni, to see if I was going in the right direction. I made a new Diff against teams as suggested. Many thanks for the notes. They helped me understand the task well! I am not sure about the tests checking the debugging output, but I also took a stab at it. I would really appreciate your input and feedback :D |
@@ -219,6 +233,16 @@ impl GithubRead for GithubMock { | |||
.collect()) | |||
} | |||
|
|||
fn org_members(&self, org: &str) -> anyhow::Result<HashSet<u64>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
most of it, I took inspiration from org_owners
src/github/mod.rs
Outdated
.expect("Team Not Found"); | ||
team_org = github_team.org.clone(); | ||
} else { | ||
team_org = "rust_lang".to_string(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this value?
Should we report an error if the team doesn't have any associated org?
Also the rust org is called "rust-lang"
src/github/mod.rs
Outdated
|
||
for toml_team_member in toml_team_members { | ||
if gh_org_members.contains(&toml_team_member.github_id.clone()) { | ||
members_to_be_removed.insert(toml_team_member.github.clone()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't this remove all members from the org?
The general direction looks great 👍👍👍 |
src/github/mod.rs
Outdated
@@ -189,6 +196,48 @@ impl SyncGitHub { | |||
Ok(diffs) | |||
} | |||
|
|||
fn diff_toml_teams(&self) -> anyhow::Result<Vec<OrgMembershipDiff>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that it would be simpler and more robust implementation would be to do this instead:
- Go through all teams and gather a set of all team members for each org that we find (so essentially a
HashMap<Org, HashSet<u64>>
) - Go through each org, and do a set difference between its members and the team members found in 1). Users that come out of this operation (those that are not in the team) should be stored in the
OrgMembershipDiff
Hey Rohit, do you still plan to work on this? |
Hey @marcoieni ! Sorry for disappearing. I will work on it over the weekend and get it past the finish line :D Appreciate your patience ! |
No worries, thanks 😁 |
b657699
to
470218d
Compare
src/github/tests/mod.rs
Outdated
model.create_team(TeamData::new("team-1").gh_team("members-gh", &[user, user2])); | ||
let gh = model.gh_model(); | ||
|
||
// let gh_members = gh.org_members("rust-lang").unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not able to get the gh_members, it returns an empty hashset
470218d
to
17878b6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making the changes! Left a bunch of comments, mostly refactoring and some logic changes.
src/github/mod.rs
Outdated
.expect("Team Not Found"); | ||
team_org = github_team.org.clone(); | ||
} else { | ||
return Err(anyhow!( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be an error, some Rust teams simply don't have any GitHub team attached.
src/github/mod.rs
Outdated
// get the team github org through the corresponding github team | ||
if let Some(gh) = &team.github { | ||
let github_teams = &gh.teams; | ||
let github_team: &GitHubTeam = github_teams |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to go through all teams, not just ones that have the same name. You can see the structure here, take a look at the [[github]]
section. You can see how you can iterate through every GitHub tam in diff_teams
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback. I thought we have to go through all the toml teams first as per the notes by @marcoieni and then find the corresponding GitHubTeam and it's organisation through that.
I am not sure how to map the GitHub org to a respective toml team in a different way.
We could go through all the teams in TeamGitHub
but if there are no corresponding toml team with the same name, I don't think it helps to go through all the teams.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that this was an error in the original description. Note that TeamGithub
has nothing to do with the GitHub API. It's a representation of a GH team described in a TOML file. You can find that out easily from the fact that the corresponding data structure (TeamGitHub
) is from the rust_team_data::v1
module. Everything that comes from this module is derived from the TOML files.
The logic should be something like this:
- Go through all TOML teams (
v1::Team
) - For each TOML team, go through all its TOML GitHub teams (
GitHubTeam
) - For each TOML GitHub team, add its members to the corresponding organization in
org_team_members
src/github/mod.rs
Outdated
for (gh_org, toml_members_across_teams) in org_team_members.into_iter() { | ||
let gh_org_members = self.org_members.get(&gh_org).unwrap(); | ||
|
||
let mut members_to_be_removed = HashSet::new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about this?
let members_to_be_removed = (gh_org_members - &toml_members_across_teams)
.into_iter()
.map(|user| self.usernames_cache[&user].clone())
.collect::<HashSet<String>>();
src/github/tests/mod.rs
Outdated
.get_team("team-1") | ||
.remove_gh_member("members-gh", user); | ||
|
||
let gh_org_diff = model.diff_teams_gh_org(gh, gh_members); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function should only receive gh
, not any additional parameters. The logic here is not fully correct, as you're passing GH members, but the function should diff team
(TOML) members. The list of member should be taken from the GithubMock
.
Signed-off-by: Rohit Dandamudi <[email protected]>
17878b6
to
f2d7303
Compare
|
||
if let Some(gh) = &team.github { | ||
for toml_gh_team in &gh.teams { | ||
team_org = toml_gh_team.org.clone(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
team_org = toml_gh_team.org.clone(); | |
let team_org = toml_gh_team.org.clone(); |
No need to have the variable in the external scope now :)
for (gh_org, toml_members_across_teams) in org_team_members.into_iter() { | ||
let gh_org_members = self.org_members.get(&gh_org).unwrap(); | ||
|
||
let members_to_be_removed = (&toml_members_across_teams - gh_org_members) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the other way around, we want to remove users (from GitHub) that are currently on GitHub, but are not in the TOML teams.
let members_to_be_removed = (&toml_members_across_teams - gh_org_members) | |
let members_to_be_removed = (gh_org_members - &toml_members_across_teams) |
|
||
let org_team_members = sync.map_teams_to_org().unwrap(); | ||
|
||
sync.diff_teams_gh_org(org_team_members) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test won't work yet, because our test API is not finished yet and this uses the unfinished parts. We need to properly track GH users and GH org members in GithubMock
, which doesn't happen currently :( I will work on it and send a PR so that you can write the test and check it locally
Fixes #84
org
members and remove members from a GitHuborg
OrgMembershipDiff
to deal with difference on GitHub and toml members in teams.