Skip to content

Commit

Permalink
Merge pull request #63 from dfinity/move-bot-checks-to-python-code
Browse files Browse the repository at this point in the history
chore(IDX): Move bot checks to python code
  • Loading branch information
cgundy authored Nov 28, 2024
2 parents 3ea6bc2 + 85277fe commit f5524f1
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 8 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/check_cla.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ jobs:
check-membership:
name: Check Membership
runs-on: ubuntu-latest
# Dont run this workflow if it was triggered by one of these bots
if: ${{ github.event.pull_request.user.login != 'dependabot[bot]' && github.event.pull_request.user.login != 'github-actions[bot]' && github.event.pull_request.user.login != 'sa-github-api' && github.event.pull_request.user.login != 'pr-automation-bot-public[bot]' && github.event_name != 'merge_group' }}
# Dont run this workflow on merge queue
if: ${{ github.event_name != 'merge_group' }}
outputs:
is_member: ${{ steps.check-membership.outputs.is_member}}
steps:
Expand Down
25 changes: 23 additions & 2 deletions reusable_workflows/check_membership/check_membership.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@
import github3


APPROVED_BOT_LIST = [
"dependabot[bot]",
"github-actions[bot]",
"sa-github-api",
"pr-automation-bot-public[bot]",
"pr-automation-bot-private[bot]",
]


def is_approved_bot(user: str) -> bool:
"""
Return whether the user is an approved bot.
"""
return user in APPROVED_BOT_LIST


def is_member_of_org(gh: github3.login, org: str, user: str) -> bool:
"""
Return whether the user is a member of the organisation.
Expand All @@ -21,13 +37,18 @@ def main() -> None:
raise Exception("github login failed - maybe GH_TOKEN was not correctly set")

is_member = is_member_of_org(gh, org, user)
is_bot = is_approved_bot(user)

org_member = is_member or is_bot

if is_bot:
print(f"{user} is an approved bot and can contribute.")
if is_member:
print(f"{user} is member of {org} and can contribute.")
else:
elif not org_member:
print(f"{user} is an external contributor.")

os.system(f"""echo 'is_member={is_member}' >> $GITHUB_OUTPUT""")
os.system(f"""echo 'is_member={org_member}' >> $GITHUB_OUTPUT""")


if __name__ == "__main__":
Expand Down
34 changes: 30 additions & 4 deletions reusable_workflows/tests/test_membership.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from github3.exceptions import NotFoundError
import pytest

from check_membership.check_membership import is_member_of_org, main
from check_membership.check_membership import is_approved_bot, is_member_of_org, main


def test_is_member():
Expand All @@ -29,6 +29,15 @@ def test_not_member():
assert is_member is False


def test_is_approved_bot():
assert is_approved_bot("dependabot[bot]") is True
assert is_approved_bot("github-actions[bot]") is True
assert is_approved_bot("sa-github-api") is True
assert is_approved_bot("pr-automation-bot-public[bot]") is True
assert is_approved_bot("pr-automation-bot-private[bot]") is True
assert is_approved_bot("random_user") is False


@mock.patch.dict(
os.environ, {"GH_ORG": "my_org", "GH_TOKEN": "secret", "USER": "username"}
)
Expand All @@ -51,6 +60,25 @@ def test_end_to_end_is_member(os_system, github_login_mock, capfd):
os_system.assert_called_once_with("echo 'is_member=True' >> $GITHUB_OUTPUT")


@mock.patch.dict(
os.environ, {"GH_ORG": "my_org", "GH_TOKEN": "secret", "USER": "dependabot[bot]"}
)
@mock.patch("github3.login")
@mock.patch("os.system")
def test_end_to_end_is_approved_bot(os_system, github_login_mock, capfd):
gh = mock.Mock()
gh_org = mock.Mock()
gh.organization.return_value = gh_org
gh_org.is_member.return_value = False
github_login_mock.return_value = gh

main()
out, err = capfd.readouterr()

assert out == "dependabot[bot] is an approved bot and can contribute.\n"
os_system.assert_called_once_with("echo 'is_member=True' >> $GITHUB_OUTPUT")


@mock.patch.dict(
os.environ, {"GH_ORG": "my_org", "GH_TOKEN": "secret", "USER": "username"}
)
Expand Down Expand Up @@ -90,9 +118,7 @@ def test_end_to_end_api_fails(os_system, github_login_mock):
os_system.assert_not_called()


@mock.patch.dict(
os.environ, {"GH_ORG": "my_org", "GH_TOKEN": "", "USER": "username"}
)
@mock.patch.dict(os.environ, {"GH_ORG": "my_org", "GH_TOKEN": "", "USER": "username"})
@mock.patch("github3.login")
def test_github_token_not_passed_in(github_login_mock):
github_login_mock.return_value = None
Expand Down

0 comments on commit f5524f1

Please sign in to comment.