feat(xref): extract cross-references from descriptions, user notes, and fix system note regex

- Fix MENTIONED_RE/CLOSED_BY_RE to match real GitLab format
  ('mentioned in issue #N' / 'mentioned in merge request !N')
- Add GITLAB_URL_RE + parse_url_refs() for full URL extraction
- Add extract_refs_from_descriptions() -> source_method='description_parse'
- Add extract_refs_from_user_notes() -> source_method='note_parse'
- Wire both into orchestrator after system note extraction
- 36 tests: regex fix, URL parsing, integration, idempotency
This commit is contained in:
teernisse
2026-02-13 15:15:43 -05:00
parent c10471ddb9
commit 0aecbf33c0
3 changed files with 721 additions and 20 deletions

View File

@@ -640,6 +640,24 @@ pub async fn ingest_project_merge_requests_with_progress(
);
}
let desc_refs = crate::core::note_parser::extract_refs_from_descriptions(conn, project_id)?;
if desc_refs.inserted > 0 || desc_refs.skipped_unresolvable > 0 {
debug!(
inserted = desc_refs.inserted,
unresolvable = desc_refs.skipped_unresolvable,
"Extracted cross-references from descriptions"
);
}
let user_note_refs = crate::core::note_parser::extract_refs_from_user_notes(conn, project_id)?;
if user_note_refs.inserted > 0 || user_note_refs.skipped_unresolvable > 0 {
debug!(
inserted = user_note_refs.inserted,
unresolvable = user_note_refs.skipped_unresolvable,
"Extracted cross-references from user notes"
);
}
{
let enqueued = enqueue_mr_closes_issues_jobs(conn, project_id)?;
if enqueued > 0 {