Skip to content

fix: sync repos created in GitHub orgs and GitLab groups#83

Open
adamsaimi wants to merge 2 commits into
mainfrom
worktree-sync-repo
Open

fix: sync repos created in GitHub orgs and GitLab groups#83
adamsaimi wants to merge 2 commits into
mainfrom
worktree-sync-repo

Conversation

@adamsaimi

Copy link
Copy Markdown
Collaborator

Summary

  • GitHub pagination: fetch_installation_repositories was fetching only the first page (max 30 repos). Now paginates with per_page=100 like all other list methods.
  • GitHub new repos: handle_repositories_added now queues a sync_repository_prs job for each newly added repo (was creating the repo record but leaving PRs unsynced).
  • GitLab system hooks: New project_create system hook support. When a project is created anywhere on the instance, the webhook enqueues a GitLabProjectCreatedMessage. The consumer then:
    • Tries a direct DB lookup by project_namespace_id (zero API calls for root-group projects)
    • Falls back to resolve_root_group (one API call) for subgroup projects
    • Creates the repo and queues MR sync if the namespace is registered in Reviewate

Test plan

  • test_repositories_added_webhook_queues_pr_sync — new repo added to GitHub installation triggers PR sync job
  • test_gitlab_project_create_system_hook_queues_message — system hook enqueues message and returns 202
  • test_handle_project_created_root_group — direct namespace match, no resolve_root_group call
  • test_handle_project_created_subgroup — subgroup falls back to resolve_root_group
  • test_handle_project_created_unknown_namespace — unregistered namespace is silently skipped

🤖 Generated with Claude Code

adamsaimi and others added 2 commits June 10, 2026 10:36
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)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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"])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant