Skip to content

Commit

Permalink
Extract CLA check into standalone Python script
Browse files Browse the repository at this point in the history
  • Loading branch information
tdug committed Jun 25, 2024
1 parent 1019614 commit 4be8d50
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 25 deletions.
72 changes: 72 additions & 0 deletions .github/scripts/check-cla.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import json
import sys
import urllib.request

JSON_HEADER = {'Content-Type': 'application/json'}
TEXT_ENCODING = 'utf-8'

URL_GITHUB = 'https://api.github.com/repos'
URL_JUCE_CLA_CHECK = 'https://cla.juce.com/check'

ALLOWED_AUTHORS = set(
'web-flow'
)


class NoAuthorsException(Exception):
__MESSAGE = "No author or committer user IDs contained within commit information."

def __init__(self, commits: list):
message = f'{self.__MESSAGE}\n\n{commits}'
super().__init__(message)


class UnsignedAuthorsException(Exception):
__MESSAGE_0 = "The following GitHub users need to sign the JUCE CLA:",
__MESSAGE_1 = "Please go to https://cla.juce.com to sign the JUCE Contributor Licence Agreement."

def __init__(self, authors: set[str]):
authors_str = ', '.join(authors)
message = f'{self.__MESSAGE_0} {authors_str}\n\n{self.__MESSAGE_1}'
super().__init__(message)


def _json_request(url: str, data: dict | None = None) -> dict:
if data is not None:
data = json.dumps(data).encode(TEXT_ENCODING)
request = urllib.request.Request(url, data, JSON_HEADER, JSON_HEADER)
with urllib.request.urlopen(request) as response:
raw_response = response.read().decode(TEXT_ENCODING)
return json.loads(raw_response)


def _get_authors(github_repository: str, github_event_number: int) -> set[str]:
pr_commit_list = _json_request(f'{URL_GITHUB}/{github_repository}/pulls/{github_event_number}/commits')
authors = set()
for commit in pr_commit_list:
for author_type in ['author', 'committer']:
if author_type in commit:
authors.add(commit[author_type]['login'])
return authors - ALLOWED_AUTHORS


def _verify_authors(authors: set[str]) -> None:
if not authors:
raise NoAuthorsException()
verification = _json_request(URL_JUCE_CLA_CHECK, {'logins': list(authors)})
if verification['unsigned']:
raise UnsignedAuthorsException(verification['unsigned'])


def main(github_repository: str, github_event_number: int):
authors = _get_authors(github_repository, github_event_number)
try:
_verify_authors(authors)
except Exception as e:
print(e.message)


if __name__ == '__main__':
github_repository = sys.argv[1]
github_event_number = int(sys.argv[2])
main(github_repository, github_event_number)
42 changes: 17 additions & 25 deletions .github/workflows/check-cla.yml
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
name: check-CLA
on: [pull_request_target]
name: Check CLA

on:
pull_request:

jobs:
check-cla:
runs-on: ubuntu-latest
continue-on-error: ${{ github.repository_owner != 'juce' }}
env:
PR_NUMBER: ${{ github.event.number }}
steps:
- name: Checkout Scripts
uses: actions/checkout@v4
with:
sparse-checkout: |
.github/scripts
sparse-checkout-cone-mode: false

- name: LS
run: ls -la

- name: check-CLA
run: |
import urllib.request
import json
import sys
def jsonRequest(url, data={}):
req = urllib.request.Request(url,
headers={'Content-Type': 'application/json'},
data=json.dumps(data).encode('utf-8') if data else None)
with urllib.request.urlopen(req) as response:
return json.loads(response.read().decode('utf-8'))
prCommits = jsonRequest('https://api.github.com/repos/juce-framework/JUCE/pulls/${{ github.event.number }}/commits')
allAuthors = [commit[authorType]['login'] for authorType in ['author', 'committer'] for commit in prCommits if commit[authorType]]
uniqueAuthors = [name for name in list(set(allAuthors)) if name != 'web-flow']
if (len(uniqueAuthors) == 0):
print(f'\nNo author or committer user IDs contained within commit information\n\n{prCommits}\n')
sys.exit(1)
print(f'Authors: {uniqueAuthors}')
claResult = jsonRequest('https://cla.juce.com/check', {'logins': uniqueAuthors})
unsignedLogins = claResult['unsigned']
if (len(unsignedLogins) != 0):
print(f'\nThe following GitHub users need to sign the JUCE CLA: {", ".join(unsignedLogins)}\n\nPlease go to https://cla.juce.com to sign the JUCE Contributor Licence Agreement\n')
sys.exit(1)
shell: python
run: python .github/scripts/check-cla.py ${{github.repository}} ${{ github.event.number }}

0 comments on commit 4be8d50

Please sign in to comment.