You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat: decide a github organization request once, with one question, one card and one status line (lfx-cdp-insights-ops#817) - #5015
Second of three PRs for #817. An organization request (#5014) is now handled as one decision instead of one per repository: the rows of the organization are classified together, get one question or one review card, and a reviewer's click decides all of them. The onboarding of the whole list in one integration call, with the cap raised, comes in the third PR.
Rows know their organization. The ingest stores requestHints.organization = <owner> on every row expanded from an organization link (no migration, hints are already JSONB). organizationSiblings / organizationGroupKey (@crowd/project-onboarding) group rows by origin message and owner.
One classification per organization.classifyAndRouteProjects classifies the first row of a group and reuses the result for its siblings: one parser call and one PCC/CDP lookup instead of N.
New non-LF organizations go to the CDP team by hand.create_segment on an organization would create one project per repository (the project name derives from the repository), so until the third PR the group is routed to review with proposedAction = human_review and the reason " isn't in LFX Insights yet; a new non-LF project with the N repositories of github.com/ is created by the CDP team". New review case new_project_by_hand: "Not in LFX Insights yet · Create as a non-LF project in CDP with these repositories by hand, then mark as done". No LLM evaluation runs for these rows.
One question per organization.askRequester posts the question once for the lead row and stamps the same message ts on the siblings; the answer command answers every sibling of that message and re-runs the check for all of them. The question reads "❓ github.com/ (N repositories): …".
One review card per organization.notifyReviewRequest posts a single card for the group ("github.com/ · N repositories", buttons "Add N repos to " / "Connect GitHub and add N repos", confirm texts with the count) and stamps its ts on all rows. Approve, Reject and Mark as done resolve the lead and every sibling that shares the card; Approve starts one onboardProjects run with all the ids (each row still runs its own create_integration / update_integration, which is safe because the integration is created once and then extended). The card closure after onboarding and the refused-click refresh keep the organization heading.
One status line per organization. The living status message folds the group into "👀 github.com/ · N repositories · with the CDP team: " (or a count summary when the rows differ), and the thread replies speak of the organization ("… (N repositories) weren't added", "were added by hand").
Still per repository in this PR: the onboardProjects run approves N rows one by one, and the cap stays at 20 repositories.
Refs linuxfoundation/lfx-cdp-insights-ops#817
Test plan
pnpm tsc-check, pnpm lint --deny-warnings
Unit tests: group helpers, shared classification and by-hand routing, organization card and decision message, grouped question and answer, grouped review decision with one onboarding run, status line, thread replies, ingest hints (557 tests across project-onboarding, slack, both workers and the backend Slack services)
Prod, after deploying api, projects-evaluation-worker and automatic-onboarding-worker (no evaluateProjects run in flight):
onboard OpenDataPlane, LF project, https://github.com/opendataplane/ → one status line "github.com/opendataplane · 5 repositories · with the CDP team: …", one card with the count, Reject closes all five rows and one thread reply
an organization of an LF project already in LFX Insights with a modern GitHub connection → one "Add N repos to " card; Approve starts one onboarding run for all rows and the card closes with the organization heading
an organization with an unknown name → one question "❓ github.com/ (N repositories): …"; one answer re-runs all rows
Medium Risk
Changes core project-catalog classification, Slack interactions, and Temporal onboarding/evaluation workflows with multi-row DB transactions; incorrect grouping could mis-route or bulk-approve repositories.
Overview
GitHub organization onboarding is treated as one request across all expanded repos instead of per-repository flows.
Catalog rows get requestHints.organization at ingest (and on provenance promotion for already-catalogued repos). New organizationGroup helpers group siblings by Slack thread + owner and drive shared classification (one classify call per org, with per-repo exceptions for already-tracked repos), one Slack question (shared messageTs, one answer updates all matching siblings in a transaction), one review card (approve/reject/mark-done resolves siblings; oneonboardProjects / evaluateProjects run with multiple catalogIds), and folded status/thread copy (*github.com/<owner>* (N repositories)).
New non-LF multi-repo orgs are routed to human_review (new_project_by_hand) until true multi-repo project creation exists. Evaluation batching withWholeOrganizations keeps org batches intact; review cards close only when all org members settle, with partial onboard counts on closure.
Also fixes Slack-wrapped GitHub org links in parsing (stripSlackFormatting) and org extraction in githubRepoUrl.
Reviewed by Cursor Bugbot for commit be49996. Bugbot is set up for automated code reviews on this repo. Configure here.
This PR extends organization-link onboarding so CDP handles each GitHub organization request as one grouped decision, while retaining per-repository onboarding and the 20-repository cap.
Changes:
Stores organization hints and reuses classification across sibling repositories.
Groups Slack questions, review cards, decisions, and status messages.
Routes new non-LF organization projects to manual review and adds regression tests.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Shared classification can lose request context or diverge across concurrent runs, and partial onboarding failures can be presented as successful completion.
Organization processing now repeatedly calls this lookup during batch expansion, question/card posting, decisions, and card closure. findProjectCatalogBySourceUrl filters on projectCatalog.sourceUrl (projectCatalog.ts:101), but the migrations provide no index on that column. Each lookup therefore scans the catalog for a small request group. Add a migration indexing projectCatalog.sourceUrl to avoid repeated full-table scans as the catalog grows.
Exclude repository URLs before stripping trailing formatting underscores
services/libs/common/src/githubRepoUrl.ts:177
Removing trailing underscores before checking the URL shape turns a repository link such as https://github.com/acme/_ into https://github.com/acme/. When the request parser is unavailable, this incorrectly expands the entire organization instead of just the requested repository, or rejects the request because the organization exceeds the cap. Exclude repository URLs before stripping unmatched formatting underscores.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Second of three PRs for #817. An organization request (#5014) is now handled as one decision instead of one per repository: the rows of the organization are classified together, get one question or one review card, and a reviewer's click decides all of them. The onboarding of the whole list in one integration call, with the cap raised, comes in the third PR.
requestHints.organization = <owner>on every row expanded from an organization link (no migration, hints are already JSONB).organizationSiblings/organizationGroupKey(@crowd/project-onboarding) group rows by origin message and owner.classifyAndRouteProjectsclassifies the first row of a group and reuses the result for its siblings: one parser call and one PCC/CDP lookup instead of N.create_segmenton an organization would create one project per repository (the project name derives from the repository), so until the third PR the group is routed to review withproposedAction = human_reviewand the reason " isn't in LFX Insights yet; a new non-LF project with the N repositories of github.com/ is created by the CDP team". New review casenew_project_by_hand: "Not in LFX Insights yet · Create as a non-LF project in CDP with these repositories by hand, then mark as done". No LLM evaluation runs for these rows.askRequesterposts the question once for the lead row and stamps the same message ts on the siblings; the answer command answers every sibling of that message and re-runs the check for all of them. The question reads "❓ github.com/ (N repositories): …".notifyReviewRequestposts a single card for the group ("github.com/ · N repositories", buttons "Add N repos to " / "Connect GitHub and add N repos", confirm texts with the count) and stamps its ts on all rows. Approve, Reject and Mark as done resolve the lead and every sibling that shares the card; Approve starts oneonboardProjectsrun with all the ids (each row still runs its owncreate_integration/update_integration, which is safe because the integration is created once and then extended). The card closure after onboarding and the refused-click refresh keep the organization heading.Still per repository in this PR: the
onboardProjectsrun approves N rows one by one, and the cap stays at 20 repositories.Refs linuxfoundation/lfx-cdp-insights-ops#817
Test plan
pnpm tsc-check,pnpm lint --deny-warningsapi,projects-evaluation-workerandautomatic-onboarding-worker(noevaluateProjectsrun in flight):onboard OpenDataPlane, LF project, https://github.com/opendataplane/→ one status line "github.com/opendataplane · 5 repositories · with the CDP team: …", one card with the count, Reject closes all five rows and one thread reply🤖 Generated with Claude Code