From 360f905755c89627e27892799ff35644e0d4d896 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Thu, 15 Sep 2022 13:57:50 -0700 Subject: [PATCH] Remove update_label_access, which is obsolete (#2184) The PyGithub import is causing problems for me in test execution, but TBH I don't think we need it anymore. I should probably update groups.md though. --- docs/project/groups.md | 3 +- github_tools/BUILD | 20 ---- github_tools/requirements.txt | 1 - github_tools/update_label_access.py | 145 ----------------------- github_tools/update_label_access_test.py | 105 ---------------- 5 files changed, 2 insertions(+), 272 deletions(-) delete mode 100644 github_tools/update_label_access.py delete mode 100644 github_tools/update_label_access_test.py diff --git a/docs/project/groups.md b/docs/project/groups.md index 85069a03b696..490b71305c38 100644 --- a/docs/project/groups.md +++ b/docs/project/groups.md @@ -20,10 +20,11 @@ We use a mix of: ## All contributors +TODO: Update this information, it's out of date. + - [GitHub organization](https://github.com/orgs/carbon-language/people) - [GitHub team: Contributors with label access](https://github.com/orgs/carbon-language/teams/contributors-with-label-access): Mirrors the GitHub organization for write access. - [Manually updated](/github_tools/update_label_access.py). - [Discord access](https://discord.com/app) - [Google group](https://groups.google.com/g/carbon-lang-contributors): Grants Google Drive access. diff --git a/github_tools/BUILD b/github_tools/BUILD index 639360317885..56627780b2a0 100644 --- a/github_tools/BUILD +++ b/github_tools/BUILD @@ -30,23 +30,3 @@ py_test( python_version = "PY3", deps = [":pr_comments"], ) - -py_binary( - name = "update_label_access", - srcs = ["update_label_access.py"], - python_version = "PY3", - deps = [ - "github_helpers", - requirement("pygithub"), - ], -) - -py_test( - name = "update_label_access_test", - srcs = ["update_label_access_test.py"], - python_version = "PY3", - deps = [ - ":pr_comments", - ":update_label_access", - ], -) diff --git a/github_tools/requirements.txt b/github_tools/requirements.txt index 7a044d3f86e0..8e885183aa15 100644 --- a/github_tools/requirements.txt +++ b/github_tools/requirements.txt @@ -4,4 +4,3 @@ # Python dependencies, consumed by /WORKSPACE. gql >= 2.0.0, < 3.0.0 -PyGitHub diff --git a/github_tools/update_label_access.py b/github_tools/update_label_access.py deleted file mode 100644 index 8c32e25163cb..000000000000 --- a/github_tools/update_label_access.py +++ /dev/null @@ -1,145 +0,0 @@ -"""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() diff --git a/github_tools/update_label_access_test.py b/github_tools/update_label_access_test.py deleted file mode 100644 index 7bb21c9917d2..000000000000 --- a/github_tools/update_label_access_test.py +++ /dev/null @@ -1,105 +0,0 @@ -"""Tests for update_label_access.py.""" - -__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 os -import unittest -from unittest import mock - -import github # type: ignore - -from github_tools import github_helpers -from github_tools import update_label_access - - -class TestUpdateLabelAccess(unittest.TestCase): - def setUp(self): - # Stub out the access token. - os.environ[github_helpers._ENV_TOKEN] = "unused" - - self.client = mock.create_autospec(github_helpers.Client, instance=True) - self.gh = mock.create_autospec(github.Github, instance=True) - self.gh_org = mock.create_autospec(github.Organization, instance=True) - self.gh_team = mock.create_autospec(github.Team, instance=True) - - self.gh.get_organization = mock.MagicMock(return_value=self.gh_org) - self.gh_org.get_team_by_slug = mock.MagicMock(return_value=self.gh_team) - - def _mock_nodes(self, logins): - self.client.execute_and_paginate.return_value = [ - {"login": login} for login in logins - ] - - def test_load_org_members_empty(self): - self._mock_nodes([]) - self.assertRaises( - AssertionError, update_label_access._load_org_members, self.client - ) - - def test_load_org_members_missing_ignored(self): - self._mock_nodes(["foo", "bar"]) - self.assertRaises( - AssertionError, update_label_access._load_org_members, self.client - ) - - def test_load_org_members_ignored_only(self): - self._mock_nodes(update_label_access._IGNORE_ACCOUNTS) - self.assertEqual( - update_label_access._load_org_members(self.client), set() - ) - - def test_load_org_members_found(self): - self._mock_nodes( - ["foo", "bar"] + list(update_label_access._IGNORE_ACCOUNTS) - ) - self.assertEqual( - update_label_access._load_org_members(self.client), - set(["foo", "bar"]), - ) - - def test_load_team_members_empty(self): - self._mock_nodes([]) - self.assertEqual( - update_label_access._load_team_members(self.client), set() - ) - - def test_load_team_members_found(self): - self._mock_nodes(["foo", "bar"]) - self.assertEqual( - update_label_access._load_team_members(self.client), - set(["foo", "bar"]), - ) - - def test_update_team_empty(self): - update_label_access._update_team(self.gh, set(), set()) - - def test_update_team_equal(self): - update_label_access._update_team( - self.gh, set(["foo", "bar"]), set(["foo", "bar"]) - ) - - def test_update_team_add(self): - self.gh.get_user = mock.MagicMock(return_value="bar-user") - self.gh_team.add_membership = mock.MagicMock() - update_label_access._update_team( - self.gh, set(["foo", "bar"]), set(["foo"]) - ) - self.gh.get_user.assert_called_once_with("bar") - self.gh_team.add_membership.assert_called_once_with("bar-user") - - def test_update_team_remove(self): - self.gh.get_user = mock.MagicMock(return_value="bar-user") - self.gh_team.remove_membership = mock.MagicMock() - update_label_access._update_team( - self.gh, set(["foo"]), set(["foo", "bar"]) - ) - self.gh.get_user.assert_called_once_with("bar") - self.gh_team.remove_membership.assert_called_once_with("bar-user") - - -if __name__ == "__main__": - unittest.main()