Reorganizing GitHub Teams
This is old. See GitHub Access & Team Structure for updates.
This is a proposal for pruning & renaming many of the 180+ teams in the openedx GitHub org.
Timeline
2022-10-13: @Kyle McCormick created GitHub Access & Team Structure and asked for feedback.
2022-12-06: This document is created by @Kyle McCormick and shared.
2023-04-26: Specific cleanup spreadsheet shared with 2U engineering leadership, to be filled in.
2023-06-01: Cleanup sheet freezed.
2023-06-15: Cleanup applied to GH org.
Overview
Axim will make a spreadsheet enumerating all GitHub teams. We will ask people to vouch for the teams that they actually use, and suggest a good new name for the teams based on this naming guide. All teams without vouchers will be deleted.
Background
We have two main uses for teams today:
Mentioning groups of people on PRs or issues. Examples:
Mentions in a PR: “@openedx/blah-devs, please review this change.”
Automatically request a review from a team on PRs, notably via .github/CODEOWNERS or upgrade-python-requirements.yml.
@openedx/cla-problems is used to alert a couple Axim employees about CLA checker issues.
@openedx/axim-oncall is used to alert the Axim on-call engineer to incoming requests.
Conferring permissions on one or more repository to one or more person.
Example:
push-pull-all
currently grandfathers in write access to edX developers for edX-contributed repos.Example:
Most of the current openedx org teams were copied over from the edx GitHub org in Jan 2022. Various people have the ability to make teams and rename them, so they have grown and changed a bit since then.
There is currently no naming scheme or process for keeping them up-to-date.
Exception: the runbooks for onboarding and offboarding Coding Core Contributors specify a team name and structure for granting CCs commit rights in a consistent way:
@openedx/ccp-committer-USERNAME
.
Axim recently tried making a plan to rename all existing teams based on [Moved] Renaming all of the GitHub Teamsarchived , but without cleaning up the list of teams first, it seemed to risky and time-consuming.
Problem
Since teams were copied over from the edx org, many of the names are 2U/edX specific, but are not prefixed with “2U” or “edX”. This is confusing for the community.
Example: @openedx/ecommerce refers to 2U/edX employees working on ecommerce, not a general Open edX e-commerce guild/group.
Team membership and names are often out-of-date. The teams names often refer to real-life teams that no longer exist. This is both confusing for the community and concerning from an access control standpoint.
Example: @openedx/community-engineering was disbanded in 2021.
Several “read access” teams now have no effect whatsoever because the vast majority of openedx repositories are public, whereas the edx org had many private repositories.
Example: @openedx/analytics-pull just grants read access to a public repository.
Plan
We propose a plan to delete unused teams and update the names of the remaining ones. Completing all steps will involve small amounts of work over a 6+ week period.
Step 1: List all teams and ask for vouchers
Axim will make a spreadsheet listing every remaining team in the org, structured like this:
Team | Grants access? | Member count | Voucher | Proposed name | Other notes |
---|---|---|---|---|---|
analytics-pull | N | 1 |
|
| probably safe to delete -J |
backstage-maintainers | Y | 3 | Feanil Patel | project-backstage |
|
community-engineering | Y | 2 |
|
|
|
solutions-team | Y | 10 |
|
| @bob what do you think? -K |
axim-engineering | Y | 5 | Kyle McCormick | axim-engineering |
|
… |
|
|
|
|
|
Axim will circulate the spreadsheet and ask folks to fill out the Voucher and Proposed Name columns:
Team will show the team slug (that is: the team name in lowercase, with special characters replaced with dashes).
Grants Access? will indicate whether the teams actually grants anyone access to anything. Granting read access to public repositories does not count.
Member count will indicate the number members.
Voucher will initially be empty. Folks should fill their name in if they would like to “vouch” that a team is useful. We plan to delete any teams that do not have a voucher.
Proposed name will initially be empty. If a repo is vouched for, the voucher can fill in a proposed name for the team based on GitHub Access & Team Structure . If they don’t, Axim will choose a name. If the original name meets the naming conventions, then it can be used as the proposed name.
Other notes for any other conversation. Keep in mind that, no matter what the notes say, the team will be deleted if there is no voucher.
Axim will provide a two week waiting period to allow folks to vouch for teams.
Step 2: Circulate final plan
We will make sure each team with a voucher has a proposed name that fits GitHub Access & Team Structure , and will mark each team without a voucher as TO BE DELETED. We will circulate a finalized version of the spreadsheet, again with a two week waiting period for folks to get ready to make any downstream updates. Changes that should be prepared:
Change | Assignee | Notes |
---|---|---|
Create team backup | @Kyle McCormick | Back-up existing team names, membership, and permissions into a JSON document so that we can restore them if anything goes awry. |
CODEOWNERS | @Kyle McCormick | Some repos have CODEOWNERS files which reference teams by their names. We should open PRs against each CODEOWNER file in order to apply the team name updates. |
upgrade-python-requirements | ?? | Most repos have a |
…. |
|
|
(Add any more known downstream changes as rows) |
|
|
Step 3: Deleted un-vouched teams
Axim will delete unvouched teams. We will wait two more weeks to allow any issues to surface.
Step 4: Rename remaining teams
Axim will rename the existing teams based on the “Proposed Name” column.
Open Questions
Are there downstream effects of the plan that we’re not accounting for? (see Step 2)
Should we do something about “team maintainers” (the GitHub feature, not the Open edX thing)? A “team maintainer” is someone on a team who is able to rename the team and add/remove members. Currently they’re assigned in a fairly arbitrary way.
Notes
Here’s the Python script we used to generate the initial spreadsheet. We ran this, copied its output, and pasted it into the spreadsheet.
Requires ghapi and Python ~3.7+
#!/usr/bin/env python3
import json, subprocess
query='''\
query($endCursor: String) {
organization(login: "openedx") {
teams(first:100, after: $endCursor) {
nodes {
name
url
description
members {
totalCount
}
repositories {
edges {
permission
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}'''
def call_query(end_cursor):
args = ['gh', 'api', 'graphql', '-f', f'query={query}']
if end_cursor:
args += ['-F', f'endCursor={end_cursor}']
output = subprocess.run(args=args, capture_output=True)
return json.loads(output.stdout)
end_cursor = None
teams = []
while True:
response = call_query(end_cursor)
end_cursor = response['data']['organization']['teams']["pageInfo"].get("endCursor")
teams += response['data']['organization']['teams']['nodes']
if not end_cursor:
break
for team in teams:
url = team['url']
name = team['name']
description = team['description']
num_members = team['members']['totalCount']
perms = [
repo_perm['permission']
for repo_perm in team['repositories']['edges']
]
num_admin_repos = len([1 for perm in perms if perm == 'ADMIN'])
num_maintain_repos = len([1 for perm in perms if perm == 'MAINTAIN'])
num_write_repos = len([1 for perm in perms if perm == 'WRITE'])
num_triage_repos = len([1 for perm in perms if perm == 'TRIAGE'])
print(
f'=hyperlink("{url}", "{name}")',
f'"{description}"',
f'"{num_members}"',
f'"{num_admin_repos}"',
f'"{num_maintain_repos}"',
f'"{num_write_repos}"',
f'"{num_triage_repos}"',
sep='\t',
)