diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-01-05 15:05:53 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-01-05 15:05:53 +0000 |
| commit | b29c0362bfb881febf9848e40023ac588d1e9aa7 (patch) | |
| tree | b8ab4a5f27a7ac458270985216c5cf0b4c7a65d4 /src/git/handlers.rs | |
| parent | 3f50107062d55a15decc47e93fd4e9f473de86e8 (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.rs | 52 |
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}; | |||
| 15 | use super::subprocess::GitSubprocess; | 15 | use super::subprocess::GitSubprocess; |
| 16 | use super::try_set_head_if_available; | 16 | use super::try_set_head_if_available; |
| 17 | 17 | ||
| 18 | use crate::git::authorization::{authorize_push, fetch_repository_data}; | 18 | use crate::git::authorization::{authorize_push, fetch_repository_data, parse_pushed_refs}; |
| 19 | use crate::git::sync::sync_to_owner_repos; | 19 | use crate::git::sync::{sync_pr_refs_to_owner_repos, sync_to_owner_repos}; |
| 20 | use crate::nostr::builder::SharedDatabase; | 20 | use crate::nostr::builder::SharedDatabase; |
| 21 | use crate::nostr::events::{KIND_PR, KIND_PR_UPDATE, KIND_REPOSITORY_STATE}; | 21 | use crate::nostr::events::{KIND_PR, KIND_PR_UPDATE, KIND_REPOSITORY_STATE}; |
| 22 | use crate::purgatory::Purgatory; | 22 | use 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( |