upleb.uk

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

summaryrefslogtreecommitdiff
path: root/grasp-audit/src/fixtures.rs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-12-01 11:56:49 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2025-12-01 11:58:34 +0000
commit7a78815e29b01c83f3d0ec195ba717a2eba8cd37 (patch)
tree4c5ccd9b812f1d1d75ed218501192ddc5459fd12 /grasp-audit/src/fixtures.rs
parente6ceab90de1acad154624022a6036efac18abab6 (diff)
reject push when refs/nostr/<event-id> doesnt match known event and delete incorrect ref on event receive
Diffstat (limited to 'grasp-audit/src/fixtures.rs')
-rw-r--r--grasp-audit/src/fixtures.rs172
1 files changed, 112 insertions, 60 deletions
diff --git a/grasp-audit/src/fixtures.rs b/grasp-audit/src/fixtures.rs
index dc4e638..4b5014d 100644
--- a/grasp-audit/src/fixtures.rs
+++ b/grasp-audit/src/fixtures.rs
@@ -59,7 +59,7 @@ pub const DETERMINISTIC_COMMIT_HASH: &str = "64ea71d79a57a7acb334cd9651f8aec067c
59/// - GPG signing: disabled 59/// - GPG signing: disabled
60/// - User: "GRASP Audit Test <test@grasp-audit.local>" 60/// - User: "GRASP Audit Test <test@grasp-audit.local>"
61/// - Parent: none (root commit) 61/// - Parent: none (root commit)
62/// NOTE: This value is different from DETERMINISTIC_COMMIT_HASH due to different content 62/// NOTE: This value is different from DETERMINISTIC_COMMIT_HASH due to different content
63pub const MAINTAINER_DETERMINISTIC_COMMIT_HASH: &str = "1c2d472c9b71ed51968a66500281a3c4a6840464"; 63pub const MAINTAINER_DETERMINISTIC_COMMIT_HASH: &str = "1c2d472c9b71ed51968a66500281a3c4a6840464";
64 64
65/// Deterministic commit hash for recursive maintainer fixtures (RecursiveMaintainer variant) 65/// Deterministic commit hash for recursive maintainer fixtures (RecursiveMaintainer variant)
@@ -71,8 +71,9 @@ pub const MAINTAINER_DETERMINISTIC_COMMIT_HASH: &str = "1c2d472c9b71ed51968a6650
71/// - GPG signing: disabled 71/// - GPG signing: disabled
72/// - User: "GRASP Audit Test <test@grasp-audit.local>" 72/// - User: "GRASP Audit Test <test@grasp-audit.local>"
73/// - Parent: none (root commit) 73/// - Parent: none (root commit)
74/// NOTE: This value is different from DETERMINISTIC_COMMIT_HASH due to different content 74/// NOTE: This value is different from DETERMINISTIC_COMMIT_HASH due to different content
75pub const RECURSIVE_MAINTAINER_DETERMINISTIC_COMMIT_HASH: &str = "05939b82de66fbdb9c077d0a64fc68522f3cb8e0"; 75pub const RECURSIVE_MAINTAINER_DETERMINISTIC_COMMIT_HASH: &str =
76 "05939b82de66fbdb9c077d0a64fc68522f3cb8e0";
76 77
77/// Deterministic commit hash for PR test fixtures (PRTestCommit variant) 78/// Deterministic commit hash for PR test fixtures (PRTestCommit variant)
78/// This is the hash produced by creating a commit with: 79/// This is the hash produced by creating a commit with:
@@ -83,7 +84,7 @@ pub const RECURSIVE_MAINTAINER_DETERMINISTIC_COMMIT_HASH: &str = "05939b82de66fb
83/// - GPG signing: disabled 84/// - GPG signing: disabled
84/// - User: "GRASP Audit Test <test@grasp-audit.local>" 85/// - User: "GRASP Audit Test <test@grasp-audit.local>"
85/// - Parent: none (root commit) 86/// - Parent: none (root commit)
86pub const PR_TEST_COMMIT_HASH: &str = "8935183ff722bf04e861928c6a7e50868c6ca4a6"; 87pub const PR_TEST_COMMIT_HASH: &str = "5d40fb1555a0c28bf4d650515a73aaa54d4d9bfb";
87 88
88/// Types of test fixtures available 89/// Types of test fixtures available
89/// 90///
@@ -157,10 +158,10 @@ pub enum FixtureKind {
157 /// - Timestamp: 2 seconds in the past (most recent) 158 /// - Timestamp: 2 seconds in the past (most recent)
158 RecursiveMaintainerRepoAndState, 159 RecursiveMaintainerRepoAndState,
159 160
160 /// PR (Patch/Pull Request) event for the SAME repo_id as ValidRepo 161 /// PR (Pull Request) event for the SAME repo_id as ValidRepo
161 /// - Requires ValidRepo (uses same repo_id) 162 /// - Requires ValidRepo (uses same repo_id)
162 /// - Signed by `client.pr_author_keys()` 163 /// - Signed by `client.pr_author_keys()`
163 /// - Kind 1617 (NIP-34 patch) 164 /// - Kind 1618 (NIP-34 PR)
164 /// - Includes `a` tag referencing the repo 165 /// - Includes `a` tag referencing the repo
165 /// - Includes `c` tag pointing to PR_TEST_COMMIT_HASH 166 /// - Includes `c` tag pointing to PR_TEST_COMMIT_HASH
166 /// - Timestamp: 1 second in the past 167 /// - Timestamp: 1 second in the past
@@ -290,6 +291,37 @@ impl<'a> TestContext<'a> {
290 self.mode 291 self.mode
291 } 292 }
292 293
294 /// Build a fixture event WITHOUT publishing it to the relay.
295 ///
296 /// This is useful for tests that need to get a fixture's event ID before
297 /// actually publishing it. For example, testing refs/nostr/<event-id>
298 /// behavior before the corresponding event exists on the relay.
299 ///
300 /// Note: This may still create and publish dependencies (e.g., ValidRepo
301 /// will be created/published if PREvent needs it), but the requested
302 /// fixture itself will NOT be published.
303 ///
304 /// # Example
305 ///
306 /// ```no_run
307 /// # use grasp_audit::*;
308 /// # async fn example(ctx: &TestContext<'_>) -> anyhow::Result<()> {
309 /// // Build PR event to get its ID without publishing
310 /// let pr_event = ctx.build_fixture_only(FixtureKind::PREvent).await?;
311 /// let pr_event_id = pr_event.id.to_hex();
312 ///
313 /// // Now push to refs/nostr/<pr_event_id> before event exists
314 /// // ... git push ...
315 ///
316 /// // Later, publish the PR event when ready
317 /// ctx.client().send_event(pr_event).await?;
318 /// # Ok(())
319 /// # }
320 /// ```
321 pub async fn build_fixture_only(&self, kind: FixtureKind) -> Result<Event> {
322 self.build_fixture(kind).await
323 }
324
293 /// Create a fresh fixture (always creates new) 325 /// Create a fresh fixture (always creates new)
294 async fn create_fresh(&self, kind: FixtureKind) -> Result<Event> { 326 async fn create_fresh(&self, kind: FixtureKind) -> Result<Event> {
295 let event = self 327 let event = self
@@ -348,7 +380,11 @@ impl<'a> TestContext<'a> {
348 { 380 {
349 let mut cache = self.client.fixture_cache().lock().unwrap(); 381 let mut cache = self.client.fixture_cache().lock().unwrap();
350 cache.insert(kind, event.clone()); 382 cache.insert(kind, event.clone());
351 tracing::debug!("get_or_create_shared({:?}) stored in client cache ({} entries)", kind, cache.len()); 383 tracing::debug!(
384 "get_or_create_shared({:?}) stored in client cache ({} entries)",
385 kind,
386 cache.len()
387 );
352 } 388 }
353 389
354 Ok(event) 390 Ok(event)
@@ -398,12 +434,17 @@ impl<'a> TestContext<'a> {
398 FixtureKind::ValidRepo, 434 FixtureKind::ValidRepo,
399 &uuid::Uuid::new_v4().to_string()[..8] 435 &uuid::Uuid::new_v4().to_string()[..8]
400 ); 436 );
401 437
402 let repo = self.client.create_repo_announcement(&test_name).await 438 let repo = self
439 .client
440 .create_repo_announcement(&test_name)
441 .await
403 .with_context(|| format!("create_repo_announcement failed for {}", test_name))?; 442 .with_context(|| format!("create_repo_announcement failed for {}", test_name))?;
404 443
405 // Send it 444 // Send it
406 self.client.send_event(repo.clone()).await 445 self.client
446 .send_event(repo.clone())
447 .await
407 .with_context(|| "Failed to send repo announcement to relay")?; 448 .with_context(|| "Failed to send repo announcement to relay")?;
408 449
409 // Store in the appropriate cache based on mode 450 // Store in the appropriate cache based on mode
@@ -412,13 +453,19 @@ impl<'a> TestContext<'a> {
412 // Store in local cache for within-test fixture dependencies 453 // Store in local cache for within-test fixture dependencies
413 let mut cache = self.local_cache.lock().unwrap(); 454 let mut cache = self.local_cache.lock().unwrap();
414 cache.insert(FixtureKind::ValidRepo, repo.clone()); 455 cache.insert(FixtureKind::ValidRepo, repo.clone());
415 tracing::debug!("get_or_create_repo() stored in local cache ({} entries)", cache.len()); 456 tracing::debug!(
457 "get_or_create_repo() stored in local cache ({} entries)",
458 cache.len()
459 );
416 } 460 }
417 ContextMode::Shared => { 461 ContextMode::Shared => {
418 // Store in client cache for cross-test sharing 462 // Store in client cache for cross-test sharing
419 let mut cache = self.client.fixture_cache().lock().unwrap(); 463 let mut cache = self.client.fixture_cache().lock().unwrap();
420 cache.insert(FixtureKind::ValidRepo, repo.clone()); 464 cache.insert(FixtureKind::ValidRepo, repo.clone());
421 tracing::debug!("get_or_create_repo() stored in client cache ({} entries)", cache.len()); 465 tracing::debug!(
466 "get_or_create_repo() stored in client cache ({} entries)",
467 cache.len()
468 );
422 } 469 }
423 } 470 }
424 471
@@ -448,12 +495,9 @@ impl<'a> TestContext<'a> {
448 let repo = self.get_or_create_repo().await?; 495 let repo = self.get_or_create_repo().await?;
449 496
450 // Create the issue 497 // Create the issue
451 let issue = self.client.create_issue( 498 let issue =
452 &repo, 499 self.client
453 "Test Issue", 500 .create_issue(&repo, "Test Issue", "Issue content for testing", vec![])?;
454 "Issue content for testing",
455 vec![],
456 )?;
457 501
458 // Send it 502 // Send it
459 self.client.send_event(issue.clone()).await?; 503 self.client.send_event(issue.clone()).await?;
@@ -555,7 +599,7 @@ impl<'a> TestContext<'a> {
555 599
556 // Get the owner's repo to use the SAME repo_id 600 // Get the owner's repo to use the SAME repo_id
557 let owner_repo = self.get_or_create_repo().await?; 601 let owner_repo = self.get_or_create_repo().await?;
558 602
559 // Extract repo_id from owner's repo announcement 603 // Extract repo_id from owner's repo announcement
560 let repo_id = owner_repo 604 let repo_id = owner_repo
561 .tags 605 .tags
@@ -573,7 +617,7 @@ impl<'a> TestContext<'a> {
573 617
574 // Get the owner's repo to use the SAME repo_id 618 // Get the owner's repo to use the SAME repo_id
575 let owner_repo = self.get_or_create_repo().await?; 619 let owner_repo = self.get_or_create_repo().await?;
576 620
577 // Extract repo_id from owner's repo announcement 621 // Extract repo_id from owner's repo announcement
578 let repo_id = owner_repo 622 let repo_id = owner_repo
579 .tags 623 .tags
@@ -593,7 +637,7 @@ impl<'a> TestContext<'a> {
593 637
594 // Get the owner's repo to use the SAME repo_id 638 // Get the owner's repo to use the SAME repo_id
595 let owner_repo = self.get_or_create_repo().await?; 639 let owner_repo = self.get_or_create_repo().await?;
596 640
597 // Extract repo_id from owner's repo announcement 641 // Extract repo_id from owner's repo announcement
598 let repo_id = owner_repo 642 let repo_id = owner_repo
599 .tags 643 .tags
@@ -611,7 +655,7 @@ impl<'a> TestContext<'a> {
611 655
612 // Get the owner's repo to use the SAME repo_id 656 // Get the owner's repo to use the SAME repo_id
613 let owner_repo = self.get_or_create_repo().await?; 657 let owner_repo = self.get_or_create_repo().await?;
614 658
615 // Extract repo_id from owner's repo announcement 659 // Extract repo_id from owner's repo announcement
616 let repo_id = owner_repo 660 let repo_id = owner_repo
617 .tags 661 .tags
@@ -630,7 +674,7 @@ impl<'a> TestContext<'a> {
630 674
631 // Get the owner's repo to use the SAME repo_id 675 // Get the owner's repo to use the SAME repo_id
632 let owner_repo = self.get_or_create_repo().await?; 676 let owner_repo = self.get_or_create_repo().await?;
633 677
634 // Extract repo_id from owner's repo announcement 678 // Extract repo_id from owner's repo announcement
635 let repo_id = owner_repo 679 let repo_id = owner_repo
636 .tags 680 .tags
@@ -647,8 +691,12 @@ impl<'a> TestContext<'a> {
647 self.client.send_event(maintainer_announcement).await?; 691 self.client.send_event(maintainer_announcement).await?;
648 692
649 // Build and send the recursive maintainer's repo announcement 693 // Build and send the recursive maintainer's repo announcement
650 let recursive_maintainer_announcement = self.build_recursive_maintainer_announcement(&repo_id).await?; 694 let recursive_maintainer_announcement = self
651 self.client.send_event(recursive_maintainer_announcement).await?; 695 .build_recursive_maintainer_announcement(&repo_id)
696 .await?;
697 self.client
698 .send_event(recursive_maintainer_announcement)
699 .await?;
652 700
653 // Return the state event (caller will send it) 701 // Return the state event (caller will send it)
654 self.build_recursive_maintainer_state(&repo_id) 702 self.build_recursive_maintainer_state(&repo_id)
@@ -672,10 +720,10 @@ impl<'a> TestContext<'a> {
672 let base_time = Timestamp::now().as_u64(); 720 let base_time = Timestamp::now().as_u64();
673 let pr_timestamp = Timestamp::from(base_time - 1); 721 let pr_timestamp = Timestamp::from(base_time - 1);
674 722
675 // Build NIP-34 patch event (kind 1617) 723 // Build NIP-34 PR event (kind 1618)
676 self.client 724 self.client
677 .event_builder( 725 .event_builder(
678 Kind::Custom(1617), // NIP-34 patch/PR kind 726 Kind::Custom(1618), // NIP-34 PR kind (has 'c' tag for commit)
679 "Test PR for GRASP validation", 727 "Test PR for GRASP validation",
680 ) 728 )
681 .tag(Tag::custom( 729 .tag(Tag::custom(
@@ -702,7 +750,8 @@ impl<'a> TestContext<'a> {
702 use nostr_sdk::prelude::*; 750 use nostr_sdk::prelude::*;
703 751
704 // Get relay URL for clone tag 752 // Get relay URL for clone tag
705 let relay_url = self.client 753 let relay_url = self
754 .client
706 .client() 755 .client()
707 .relays() 756 .relays()
708 .await 757 .await
@@ -715,7 +764,8 @@ impl<'a> TestContext<'a> {
715 .replace("wss://", "https://"); 764 .replace("wss://", "https://");
716 765
717 // Create maintainer's repo announcement for the SAME repo_id 766 // Create maintainer's repo announcement for the SAME repo_id
718 let maintainer_npub = self.client 767 let maintainer_npub = self
768 .client
719 .maintainer_keys() 769 .maintainer_keys()
720 .public_key() 770 .public_key()
721 .to_bech32() 771 .to_bech32()
@@ -735,10 +785,7 @@ impl<'a> TestContext<'a> {
735 TagKind::custom("clone"), 785 TagKind::custom("clone"),
736 vec![format!("{}/{}/{}.git", http_url, maintainer_npub, repo_id)], 786 vec![format!("{}/{}/{}.git", http_url, maintainer_npub, repo_id)],
737 )) 787 ))
738 .tag(Tag::custom( 788 .tag(Tag::custom(TagKind::custom("relays"), vec![relay_url]))
739 TagKind::custom("relays"),
740 vec![relay_url],
741 ))
742 .tag(Tag::custom( 789 .tag(Tag::custom(
743 TagKind::custom("maintainers"), 790 TagKind::custom("maintainers"),
744 vec![self.client.recursive_maintainer_pubkey_hex()], 791 vec![self.client.recursive_maintainer_pubkey_hex()],
@@ -776,7 +823,8 @@ impl<'a> TestContext<'a> {
776 use nostr_sdk::prelude::*; 823 use nostr_sdk::prelude::*;
777 824
778 // Get relay URL for clone tag 825 // Get relay URL for clone tag
779 let relay_url = self.client 826 let relay_url = self
827 .client
780 .client() 828 .client()
781 .relays() 829 .relays()
782 .await 830 .await
@@ -789,7 +837,8 @@ impl<'a> TestContext<'a> {
789 .replace("wss://", "https://"); 837 .replace("wss://", "https://");
790 838
791 // Create recursive maintainer's repo announcement for the SAME repo_id 839 // Create recursive maintainer's repo announcement for the SAME repo_id
792 let recursive_maintainer_npub = self.client 840 let recursive_maintainer_npub = self
841 .client
793 .recursive_maintainer_keys() 842 .recursive_maintainer_keys()
794 .public_key() 843 .public_key()
795 .to_bech32() 844 .to_bech32()
@@ -807,12 +856,12 @@ impl<'a> TestContext<'a> {
807 )) 856 ))
808 .tag(Tag::custom( 857 .tag(Tag::custom(
809 TagKind::custom("clone"), 858 TagKind::custom("clone"),
810 vec![format!("{}/{}/{}.git", http_url, recursive_maintainer_npub, repo_id)], 859 vec![format!(
811 )) 860 "{}/{}/{}.git",
812 .tag(Tag::custom( 861 http_url, recursive_maintainer_npub, repo_id
813 TagKind::custom("relays"), 862 )],
814 vec![relay_url],
815 )) 863 ))
864 .tag(Tag::custom(TagKind::custom("relays"), vec![relay_url]))
816 .tag(Tag::custom( 865 .tag(Tag::custom(
817 TagKind::custom("maintainers"), 866 TagKind::custom("maintainers"),
818 vec![ 867 vec![
@@ -821,7 +870,12 @@ impl<'a> TestContext<'a> {
821 ], 870 ],
822 )) 871 ))
823 .build(self.client.recursive_maintainer_keys()) 872 .build(self.client.recursive_maintainer_keys())
824 .map_err(|e| anyhow::anyhow!("Failed to build recursive maintainer repo announcement: {}", e)) 873 .map_err(|e| {
874 anyhow::anyhow!(
875 "Failed to build recursive maintainer repo announcement: {}",
876 e
877 )
878 })
825 } 879 }
826 880
827 /// Build recursive maintainer state event for the given repo_id 881 /// Build recursive maintainer state event for the given repo_id
@@ -898,7 +952,7 @@ pub async fn send_and_verify_accepted(
898) -> Result<(), String> { 952) -> Result<(), String> {
899 use nostr_sdk::prelude::Filter; 953 use nostr_sdk::prelude::Filter;
900 use std::time::Duration; 954 use std::time::Duration;
901 955
902 let event_id = event.id; 956 let event_id = event.id;
903 957
904 client 958 client
@@ -952,12 +1006,12 @@ pub async fn send_and_verify_rejected(
952) -> Result<(), String> { 1006) -> Result<(), String> {
953 use nostr_sdk::prelude::Filter; 1007 use nostr_sdk::prelude::Filter;
954 use std::time::Duration; 1008 use std::time::Duration;
955 1009
956 let event_id = event.id; 1010 let event_id = event.id;
957 1011
958 // Try to send event - rejection may cause send_event to fail with an error 1012 // Try to send event - rejection may cause send_event to fail with an error
959 let send_result = client.send_event(event).await; 1013 let send_result = client.send_event(event).await;
960 1014
961 // If send succeeded, the relay might have accepted it (we'll verify below) 1015 // If send succeeded, the relay might have accepted it (we'll verify below)
962 // If send failed, check if it's a rejection error (expected) 1016 // If send failed, check if it's a rejection error (expected)
963 if let Err(e) = send_result { 1017 if let Err(e) = send_result {
@@ -966,7 +1020,7 @@ pub async fn send_and_verify_rejected(
966 if err_msg.contains("rejected") || err_msg.contains("blocked") { 1020 if err_msg.contains("rejected") || err_msg.contains("blocked") {
967 // Expected rejection - verify event is NOT in database 1021 // Expected rejection - verify event is NOT in database
968 tokio::time::sleep(Duration::from_millis(100)).await; 1022 tokio::time::sleep(Duration::from_millis(100)).await;
969 1023
970 let filter = Filter::new().id(event_id); 1024 let filter = Filter::new().id(event_id);
971 let events = client 1025 let events = client
972 .query(filter) 1026 .query(filter)
@@ -974,9 +1028,12 @@ pub async fn send_and_verify_rejected(
974 .map_err(|e| format!("Failed to query relay for verification: {}", e))?; 1028 .map_err(|e| format!("Failed to query relay for verification: {}", e))?;
975 1029
976 if !events.is_empty() { 1030 if !events.is_empty() {
977 return Err(format!("Event was rejected but still stored: {}", description)); 1031 return Err(format!(
1032 "Event was rejected but still stored: {}",
1033 description
1034 ));
978 } 1035 }
979 1036
980 return Ok(()); // Rejected as expected 1037 return Ok(()); // Rejected as expected
981 } else { 1038 } else {
982 // Unexpected error (network, etc.) 1039 // Unexpected error (network, etc.)
@@ -1029,11 +1086,7 @@ use std::process::Command;
1029/// # Ok(()) 1086/// # Ok(())
1030/// # } 1087/// # }
1031/// ``` 1088/// ```
1032pub fn clone_repo( 1089pub fn clone_repo(relay_domain: &str, npub: &str, repo_id: &str) -> Result<PathBuf, String> {
1033 relay_domain: &str,
1034 npub: &str,
1035 repo_id: &str,
1036) -> Result<PathBuf, String> {
1037 let temp_base = std::env::temp_dir(); 1090 let temp_base = std::env::temp_dir();
1038 let clone_dir_name = format!("grasp-push-test-{}", uuid::Uuid::new_v4()); 1091 let clone_dir_name = format!("grasp-push-test-{}", uuid::Uuid::new_v4());
1039 let clone_path = temp_base.join(&clone_dir_name); 1092 let clone_path = temp_base.join(&clone_dir_name);
@@ -1146,7 +1199,7 @@ impl CommitVariant {
1146 CommitVariant::PRTestCommit => "PR test deterministic commit", 1199 CommitVariant::PRTestCommit => "PR test deterministic commit",
1147 } 1200 }
1148 } 1201 }
1149 1202
1150 /// Get the commit message for this variant 1203 /// Get the commit message for this variant
1151 pub fn commit_message(&self) -> &'static str { 1204 pub fn commit_message(&self) -> &'static str {
1152 match self { 1205 match self {
@@ -1172,11 +1225,14 @@ impl CommitVariant {
1172/// # Returns 1225/// # Returns
1173/// * `Ok(String)` - The deterministic commit hash 1226/// * `Ok(String)` - The deterministic commit hash
1174/// * `Err(String)` - Error message if commit failed 1227/// * `Err(String)` - Error message if commit failed
1175pub fn create_deterministic_commit_with_variant(clone_path: &Path, variant: CommitVariant) -> Result<String, String> { 1228pub fn create_deterministic_commit_with_variant(
1229 clone_path: &Path,
1230 variant: CommitVariant,
1231) -> Result<String, String> {
1176 let test_file = clone_path.join("test.txt"); 1232 let test_file = clone_path.join("test.txt");
1177 let content = variant.file_content(); 1233 let content = variant.file_content();
1178 let message = variant.commit_message(); 1234 let message = variant.commit_message();
1179 1235
1180 fs::write(&test_file, content).map_err(|e| format!("Failed to write file: {}", e))?; 1236 fs::write(&test_file, content).map_err(|e| format!("Failed to write file: {}", e))?;
1181 1237
1182 let output = Command::new("git") 1238 let output = Command::new("git")
@@ -1191,11 +1247,7 @@ pub fn create_deterministic_commit_with_variant(clone_path: &Path, variant: Comm
1191 1247
1192 // Create deterministic commit with fixed dates and GPG disabled 1248 // Create deterministic commit with fixed dates and GPG disabled
1193 let output = Command::new("git") 1249 let output = Command::new("git")
1194 .args([ 1250 .args(["-c", "commit.gpgsign=false", "commit", "-m", message])
1195 "-c", "commit.gpgsign=false",
1196 "commit",
1197 "-m", message,
1198 ])
1199 .env("GIT_AUTHOR_DATE", "2024-01-01T00:00:00Z") 1251 .env("GIT_AUTHOR_DATE", "2024-01-01T00:00:00Z")
1200 .env("GIT_COMMITTER_DATE", "2024-01-01T00:00:00Z") 1252 .env("GIT_COMMITTER_DATE", "2024-01-01T00:00:00Z")
1201 .current_dir(clone_path) 1253 .current_dir(clone_path)