Skip to content

Commit 3a0cf08

Browse files
authored
Skip CLA check for get-convex organization members (#836)
1 parent c0dc53b commit 3a0cf08

File tree

3 files changed

+82
-10
lines changed

3 files changed

+82
-10
lines changed

.github/workflows/cla.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,7 @@ jobs:
1818
if: ${{ (startsWith(github.head_ref, 'dependabot') || startsWith(github.head_ref, 'renovate')) == false }}
1919
env:
2020
PR_DESCRIPTION: ${{ github.event.pull_request.body }}
21+
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
22+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2123
run: |
2224
./scripts/check_cla.py

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,4 @@ dist
110110
tsconfig.tsbuildinfo
111111
convex-local-backend*
112112
.mypy_cache
113+
__pycache__/

scripts/check_cla.py

Lines changed: 79 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,86 @@
22
import os
33
import re
44
import sys
5+
import urllib.error
6+
import urllib.request
57

68
CLA_TEXT = "By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice."
9+
ORGANIZATION = "get-convex"
710

8-
try:
9-
PR_DESCRIPTION = os.environ["PR_DESCRIPTION"]
10-
except KeyError:
11-
print("There was no pull request description given")
12-
sys.exit(1)
11+
def is_org_member(username, github_token):
12+
"""
13+
Check if a user is a member of the get-convex GitHub organization.
14+
Returns True if the user is a confirmed member.
15+
Returns False if the user is not a member (404 response).
16+
Returns None if the check fails (network error, API error, etc.).
17+
"""
18+
try:
19+
# GitHub API endpoint to check organization membership
20+
url = f"https://api.github.com/orgs/{ORGANIZATION}/members/{username}"
21+
22+
headers = {
23+
"Accept": "application/vnd.github+json",
24+
"X-GitHub-Api-Version": "2022-11-28"
25+
}
26+
27+
if github_token:
28+
headers["Authorization"] = f"Bearer {github_token}"
29+
30+
request = urllib.request.Request(url, headers=headers)
31+
32+
# Try to fetch the membership status
33+
# A 204 response means the user is a confirmed member
34+
# A 404 response means the user is not a member (or membership is private)
35+
# Other errors indicate API failure and we return None to show a warning
36+
try:
37+
with urllib.request.urlopen(request) as response:
38+
if response.status == 204:
39+
return True
40+
return None
41+
except urllib.error.HTTPError as e:
42+
if e.code == 404:
43+
# User is not a member or membership is private
44+
return False
45+
# For other HTTP errors, return None to indicate failure
46+
return None
47+
48+
except Exception as e:
49+
print(f"⚠️ Warning: Failed to check organization membership: {e}")
50+
return None
1351

14-
if not re.search(re.escape(CLA_TEXT), PR_DESCRIPTION, re.MULTILINE):
15-
print(
16-
"Pull request description does not include the required CLA text. Please add the following text to your PR description:\n\n" + CLA_TEXT
17-
)
18-
sys.exit(1)
52+
def main():
53+
# Get PR description
54+
try:
55+
PR_DESCRIPTION = os.environ["PR_DESCRIPTION"]
56+
except KeyError:
57+
print("❌ Error: There was no pull request description given")
58+
sys.exit(1)
59+
60+
# Get PR author username - this should always be set
61+
PR_AUTHOR = os.environ.get("PR_AUTHOR")
62+
GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN")
63+
64+
if not PR_AUTHOR:
65+
print("❌ Error: PR_AUTHOR environment variable not set")
66+
sys.exit(1)
67+
68+
# Check if the author is a member of get-convex organization
69+
member_status = is_org_member(PR_AUTHOR, GITHUB_TOKEN)
70+
71+
if member_status is True:
72+
print(f"✅ Skipping CLA check: {PR_AUTHOR} is a member of the {ORGANIZATION} organization (Convex employee/contractor)")
73+
sys.exit(0)
74+
elif member_status is None:
75+
print(f"⚠️ Warning: Could not verify organization membership for {PR_AUTHOR}. Proceeding with CLA check.")
76+
77+
# Proceed with standard CLA check
78+
if not re.search(re.escape(CLA_TEXT), PR_DESCRIPTION, re.MULTILINE):
79+
print(
80+
"❌ Pull request description does not include the required CLA text. Please add the following text to your PR description:\n\n" + CLA_TEXT
81+
)
82+
sys.exit(1)
83+
84+
print("✅ CLA text found in PR description")
85+
86+
if __name__ == "__main__":
87+
main()

0 commit comments

Comments
 (0)