mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 21:40:12 +01:00
143 lines
3.8 KiB
Python
143 lines
3.8 KiB
Python
"""Updates the contributors-with-label-access team.
|
|
|
|
This team exists because we need a team to manage triage access to repos;
|
|
GitHub doesn't allow the org to be set to triage access, only read/write. It
|
|
will be updated to include all members of the carbon-language organization.
|
|
"""
|
|
|
|
__copyright__ = """
|
|
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
Exceptions. See /LICENSE for license information.
|
|
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
"""
|
|
|
|
import argparse
|
|
|
|
# https://github.com/PyGithub/PyGithub
|
|
# GraphQL is preferred, but falling back to pygithub for unsupported mutations.
|
|
import github
|
|
|
|
from carbon.github_tools import github_helpers
|
|
|
|
# The organization to mirror members from.
|
|
_ORG = "carbon-language"
|
|
|
|
# The team to mirror to.
|
|
_TEAM = "contributors"
|
|
|
|
# Accounts in the org to skip mirroring.
|
|
_IGNORE_ACCOUNTS = ("CarbonLangInfra", "google-admin", "googlebot")
|
|
|
|
# Queries organization members.
|
|
_ORG_MEMBER_QUERY = """
|
|
query {
|
|
organization(login: "%s") {
|
|
membersWithRole(first: 100%%(cursor)s) {
|
|
nodes {
|
|
login
|
|
}
|
|
%%(pagination)s
|
|
}
|
|
}
|
|
}
|
|
"""
|
|
|
|
# The path for nodes in _ORG_MEMBER_QUERY.
|
|
_ORG_MEMBER_PATH = ("organization", "membersWithRole")
|
|
|
|
# Queries team members.
|
|
_TEAM_MEMBER_QUERY = """
|
|
query {
|
|
organization(login: "%s") {
|
|
team(slug: "%s") {
|
|
members(first: 100%%(cursor)s) {
|
|
nodes {
|
|
login
|
|
}
|
|
%%(pagination)s
|
|
}
|
|
}
|
|
}
|
|
}
|
|
"""
|
|
|
|
# The path for nodes in _TEAM_MEMBER_QUERY.
|
|
_TEAM_MEMBER_PATH = ("organization", "team", "members")
|
|
|
|
|
|
def _parse_args(args=None):
|
|
"""Parses command-line arguments and flags."""
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
github_helpers.add_access_token_arg(parser, "admin:org, repo")
|
|
return parser.parse_args(args=args)
|
|
|
|
|
|
def _load_org_members(client):
|
|
"""Loads org members."""
|
|
print("Loading %s..." % _ORG)
|
|
org_members = set()
|
|
ignored = set()
|
|
for node in client.execute_and_paginate(
|
|
_ORG_MEMBER_QUERY % _ORG, _ORG_MEMBER_PATH
|
|
):
|
|
login = node["login"]
|
|
if login not in _IGNORE_ACCOUNTS:
|
|
org_members.add(login)
|
|
else:
|
|
ignored.add(login)
|
|
print(
|
|
"%s has %d non-ignored members, and %d ignored."
|
|
% (_ORG, len(org_members), len(ignored))
|
|
)
|
|
unignored = set(_IGNORE_ACCOUNTS) - ignored
|
|
assert not unignored, "Missing ignored accounts: %s" % unignored
|
|
return org_members
|
|
|
|
|
|
def _load_team_members(client):
|
|
"""Load team members."""
|
|
print("Loading %s..." % _TEAM)
|
|
team_members = set()
|
|
for node in client.execute_and_paginate(
|
|
_TEAM_MEMBER_QUERY % (_ORG, _TEAM), _TEAM_MEMBER_PATH
|
|
):
|
|
team_members.add(node["login"])
|
|
print("%s has %d members." % (_ORG, len(team_members)))
|
|
return team_members
|
|
|
|
|
|
def _update_team(gh, org_members, team_members):
|
|
"""Updates the team if needed.
|
|
|
|
This switches to pygithub because GraphQL lacks equivalent mutation support.
|
|
"""
|
|
gh_team = gh.get_organization(_ORG).get_team_by_slug(_TEAM)
|
|
add_members = org_members - team_members
|
|
if add_members:
|
|
print("Adding members: %s" % ", ".join(add_members))
|
|
for member in add_members:
|
|
gh_team.add_membership(gh.get_user(member))
|
|
|
|
remove_members = team_members - org_members
|
|
if remove_members:
|
|
print("Removing members: %s" % ", ".join(remove_members))
|
|
for member in remove_members:
|
|
gh_team.remove_membership(gh.get_user(member))
|
|
|
|
|
|
def main():
|
|
parsed_args = _parse_args()
|
|
print("Connecting...")
|
|
client = github_helpers.Client(parsed_args)
|
|
|
|
org_members = _load_org_members(client)
|
|
team_members = _load_team_members(client)
|
|
if org_members != team_members:
|
|
gh = github.Github(parsed_args.access_token)
|
|
_update_team(gh, org_members, team_members)
|
|
print("Done!")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|