upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/git/handlers.rs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2026-01-05 15:05:53 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2026-01-05 15:05:53 +0000
commitb29c0362bfb881febf9848e40023ac588d1e9aa7 (patch)
treeb8ab4a5f27a7ac458270985216c5cf0b4c7a65d4 /src/git/handlers.rs
parent3f50107062d55a15decc47e93fd4e9f473de86e8 (diff)
sync PR refs (refs/nostr/<event-id>) to all owner repos when push received
When a push to refs/nostr/<event-id> is received (PR data), the git data is now synced to all other owner repositories that share maintainers with the source owner. This mirrors the behavior added for state event data. Changes: - Add sync_pr_refs_to_owner_repos() function in git/sync.rs - Add PrSyncResult struct to track sync statistics - Add copy_single_commit_between_repos() helper function - Call PR sync in handle_receive_pack after successful push - Add unit test for PrSyncResult default values
Diffstat (limited to 'src/git/handlers.rs')
-rw-r--r--src/git/handlers.rs52
1 files changed, 50 insertions, 2 deletions
diff --git a/src/git/handlers.rs b/src/git/handlers.rs
index e86d2a3..23a15ba 100644
--- a/src/git/handlers.rs
+++ b/src/git/handlers.rs
@@ -15,8 +15,8 @@ use super::protocol::{GitService, PktLine};
15use super::subprocess::GitSubprocess; 15use super::subprocess::GitSubprocess;
16use super::try_set_head_if_available; 16use super::try_set_head_if_available;
17 17
18use crate::git::authorization::{authorize_push, fetch_repository_data}; 18use crate::git::authorization::{authorize_push, fetch_repository_data, parse_pushed_refs};
19use crate::git::sync::sync_to_owner_repos; 19use crate::git::sync::{sync_pr_refs_to_owner_repos, sync_to_owner_repos};
20use crate::nostr::builder::SharedDatabase; 20use crate::nostr::builder::SharedDatabase;
21use crate::nostr::events::{KIND_PR, KIND_PR_UPDATE, KIND_REPOSITORY_STATE}; 21use crate::nostr::events::{KIND_PR, KIND_PR_UPDATE, KIND_REPOSITORY_STATE};
22use crate::purgatory::Purgatory; 22use crate::purgatory::Purgatory;
@@ -383,6 +383,54 @@ pub async fn handle_receive_pack(
383 } 383 }
384 } 384 }
385 385
386 // Sync PR data (refs/nostr/<event-id>) to other owner repositories
387 // Parse pushed refs to find refs/nostr/* refs
388 let pushed_refs = parse_pushed_refs(&request_body);
389 let pr_refs: Vec<(String, String)> = pushed_refs
390 .iter()
391 .filter_map(|(_, new_oid, ref_name)| {
392 ref_name.strip_prefix("refs/nostr/").map(|event_id| {
393 (event_id.to_string(), new_oid.clone())
394 })
395 })
396 .collect();
397
398 if !pr_refs.is_empty() {
399 match fetch_repository_data(&database, identifier).await {
400 Ok(db_repo_data) => {
401 let git_data_path_buf = std::path::PathBuf::from(git_data_path);
402 let pr_sync_result = sync_pr_refs_to_owner_repos(
403 &repo_path,
404 &pr_refs,
405 &db_repo_data,
406 &git_data_path_buf,
407 owner_pubkey,
408 );
409
410 if pr_sync_result.repos_synced > 0 {
411 info!(
412 "Synced {} PR refs to {} other owner repositories for {}",
413 pr_sync_result.refs_created,
414 pr_sync_result.repos_synced,
415 identifier
416 );
417 }
418
419 if !pr_sync_result.errors.is_empty() {
420 for (repo, error) in &pr_sync_result.errors {
421 warn!("Error syncing PR ref to {}: {}", repo, error);
422 }
423 }
424 }
425 Err(e) => {
426 warn!(
427 "Failed to fetch repository data for PR sync after push to {}: {}",
428 identifier, e
429 );
430 }
431 }
432 }
433
386 Ok(Response::builder() 434 Ok(Response::builder()
387 .status(StatusCode::OK) 435 .status(StatusCode::OK)
388 .header( 436 .header(