| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- """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
- from typing import List, Optional, Set
- # https://github.com/PyGithub/PyGithub
- # GraphQL is preferred, but falling back to pygithub for unsupported mutations.
- import github
- from 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: Optional[List[str]] = None) -> argparse.Namespace:
- """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: github_helpers.Client) -> Set[str]:
- """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: github_helpers.Client) -> Set[str]:
- """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: github.Github, org_members: Set[str], team_members: Set[str]
- ) -> None:
- """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() -> None:
- 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()
|