Skip to content

Commit 3c6a703

Browse files
committed
Track PendingSignatures by Pull Request number directly
The `/repos/{owner}/{repo}/commits/{commit_sha}/pulls` API endpoint does not return Pull Request objects when the commit comes from a fork. Track PendingSignature objects by the Pull Request they came from directly.
1 parent 017f87c commit 3c6a703

File tree

6 files changed

+41
-21
lines changed

6 files changed

+41
-21
lines changed

cla/admin.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class PendingSignatureAdmin(admin.ModelAdmin):
8282
"get_repository_display",
8383
"github_repository_id",
8484
"ref",
85+
"pull_number",
8586
"email_address",
8687
"normalized_email",
8788
"created_at",
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 5.2 on 2025-04-18 11:28
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("cla", "0003_signature_signing_email_address"),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name="pendingsignature",
15+
name="pull_number",
16+
field=models.IntegerField(null=True),
17+
),
18+
]

cla/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ class PendingSignature(models.Model):
110110
agreement = models.ForeignKey(Agreement, on_delete=models.PROTECT)
111111
github_repository_id = models.IntegerField()
112112
ref = models.CharField(max_length=512)
113+
pull_number = models.IntegerField(null=True)
113114
email_address = models.EmailField(max_length=512)
114115
objects = PendingSignatureManager()
115116

cla/tasks.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ async def check_pull_request(
144144
github_repository_id=target_repository_id,
145145
email_address=author.email,
146146
ref=pull_request_head_sha,
147+
defaults={"pull_number": pull_request_number},
147148
)
148149
needs_signing.add(author)
149150
elif signature.github_id is None or signature.github_node_id is None:

cla/tests/test_models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def test_pending_signature_python_and_pg_normailzed(self, email, normalized_emai
2626
pending_signature = PendingSignature.objects.create(
2727
agreement=agreement,
2828
github_repository_id=1,
29-
ref="deadbeef",
29+
pull_number=1,
3030
email_address=email,
3131
)
3232
assert (

clabot/views.py

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -144,37 +144,36 @@ async def sign(request):
144144
normalized_email=normalize_email(email_address),
145145
).all()
146146
):
147-
to_resolve[pending_signature.github_repository_id].add(pending_signature.ref)
147+
to_resolve[pending_signature.github_repository_id].add(pending_signature.pull_number)
148148
found_to_resolve += 1
149149
logging.info(
150150
f"Found {found_to_resolve} pending signatures "
151151
f"across {len(to_resolve)} repositories "
152-
"to resolve for {email_address}"
152+
f"to resolve for {email_address}"
153153
)
154154

155-
for repository_id, refs in to_resolve.items():
155+
for repository_id, pull_numbers in to_resolve.items():
156+
logging.info(repository_id)
156157
repository = await Repository.objects.select_related("installation").aget(
157158
repository_id=repository_id
158159
)
159160
installation = repository.installation
160161
async with AsyncGitHubAPI("clabot", installation=installation) as gh:
161-
for ref in refs:
162-
async for pull in gh.getiter(
163-
f"/repos/{repository.full_name}/commits/{ref}/pulls"
164-
):
165-
logging.info(f"Updating {repository.full_name} #{pull['number']}")
166-
await handle_pull_request(
167-
namedtuple("Event", "data")(
168-
{
169-
"pull_request": pull,
170-
"repository": {
171-
"id": repository.repository_id,
172-
"full_name": repository.full_name,
173-
},
174-
}
175-
),
176-
None,
177-
)
162+
for pull_number in pull_numbers:
163+
pull = await gh.getitem(f"/repos/{repository.full_name}/pulls/{pull_number}")
164+
logging.info(f"Updating {repository.full_name} #{pull_number}")
165+
await handle_pull_request(
166+
namedtuple("Event", "data")(
167+
{
168+
"pull_request": pull,
169+
"repository": {
170+
"id": repository.repository_id,
171+
"full_name": repository.full_name,
172+
},
173+
}
174+
),
175+
None,
176+
)
178177

179178
logging.info("Cleaning up PendingSignature(s)")
180179
await PendingSignature.objects.filter(

0 commit comments

Comments
 (0)