fix: sync repos created in GitHub orgs and GitLab groups#83
Conversation
GitHub: - fetch_installation_repositories now paginates (was capped at 30 repos) - handle_repositories_added queues PR sync for newly added repos GitLab: - Handle project_create system hook: webhook enqueues event, consumer resolves namespace to org (direct DB lookup for root groups, one resolve_root_group API call for subgroups) then creates the repo and queues MR sync Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
repositories_added items are minimal repo objects — html_url is not included. Construct the URL as https://github.com/{full_name} instead of storing an empty string. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
||
| # System hooks use event_name instead of object_kind | ||
| if event_name == "project_create": | ||
| event = GitLabProjectCreatedSystemHookEvent(**event_data) |
There was a problem hiding this comment.
[CRITICAL] Pydantic ValidationError not caught — schema instantiation outside error handler
The schema instantiation event = GitLabProjectCreatedSystemHookEvent(**event_data) (line 75) is not wrapped in the try/except Exception block that follows (lines 76–92). Any required field mismatch or validation error from the schema will propagate as HTTP 500 instead of being caught and logged.
Fix: Wrap the instantiation:
if event_name == "project_create":
try:
event = GitLabProjectCreatedSystemHookEvent(**event_data)
except Exception as e:
logger.warning(f"Invalid project_create payload: {e}")
return WebhookResponse(message="Invalid payload", processed=False)
try:
broker = get_faststream_broker()
...| mock_get_broker_handler.return_value = mock_broker | ||
| mock_get_broker_sse.return_value = mock_broker | ||
|
|
||
| create_organization.installation_id = "inst999" |
There was a problem hiding this comment.
[HIGH] Test setup: installation_id mismatch causes test to fail
Line 598 sets create_organization.installation_id = "inst999", but the webhook payload sends "installation": {"id": 999}. The handler converts this to str(999) = "999". The org lookup filters on Organization.installation_id == "999", which doesn't match "inst999" — the query returns None, triggering a 404 instead of the expected 202.
Fix:
create_organization.installation_id = "999" # Must match str(installation["id"])
Summary
fetch_installation_repositorieswas fetching only the first page (max 30 repos). Now paginates withper_page=100like all other list methods.handle_repositories_addednow queues async_repository_prsjob for each newly added repo (was creating the repo record but leaving PRs unsynced).project_createsystem hook support. When a project is created anywhere on the instance, the webhook enqueues aGitLabProjectCreatedMessage. The consumer then:project_namespace_id(zero API calls for root-group projects)resolve_root_group(one API call) for subgroup projectsTest plan
test_repositories_added_webhook_queues_pr_sync— new repo added to GitHub installation triggers PR sync jobtest_gitlab_project_create_system_hook_queues_message— system hook enqueues message and returns 202test_handle_project_created_root_group— direct namespace match, noresolve_root_groupcalltest_handle_project_created_subgroup— subgroup falls back toresolve_root_grouptest_handle_project_created_unknown_namespace— unregistered namespace is silently skipped🤖 Generated with Claude Code