mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:40:10 +01:00
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.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -4,4 +4,3 @@
|
||||
|
||||
# Python dependencies, consumed by /WORKSPACE.
|
||||
gql >= 2.0.0, < 3.0.0
|
||||
PyGitHub
|
||||
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
Reference in New Issue
Block a user