From 26645906c7a5b64bf24ead3b5e25d5167e0835b0 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Feb 2026 15:21:06 +0100 Subject: [PATCH] remove .gitattributes from release artifacts for reproducible builds Delete .gitattributes files from publish output before packaging to ensure byte-for-byte reproducible release archives. WalletScrutiny performs strict hash-based comparison of every file in the release artifact. Even non-functional git metadata files (e.g. Microservices/Binaries/lin64/Tor/.gitattributes) cause automated verification to fail. This change strips .gitattributes during packaging without affecting functionality or security, enabling fully reproducible releases under automated verification. --- WalletWasabi.Packager/Program.cs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/WalletWasabi.Packager/Program.cs b/WalletWasabi.Packager/Program.cs index fd61f718be..3d4e589296 100644 --- a/WalletWasabi.Packager/Program.cs +++ b/WalletWasabi.Packager/Program.cs @@ -321,6 +321,8 @@ private static async Task PublishAsync() } } + DeleteGitMetadataFiles(currentBinDistDirectory); + // Rename WalletWasabi.Fluent.Desktop(.exe) -> wassabee(.exe). string executableExtension = target.StartsWith("win") ? ".exe" : ""; string oldExecutablePath = Path.Combine(currentBinDistDirectory, $"WalletWasabi.Fluent.Desktop{executableExtension}"); @@ -670,4 +672,32 @@ private static string GetPackageTargetPostfix(string target) return target; } + + private static void DeleteGitMetadataFiles(string rootDir) + { + static void TryDelete(string path) + { + try + { + // Ensure writeable (defensive for Windows attributes). + File.SetAttributes(path, FileAttributes.Normal); + File.Delete(path); + } + catch + { + // Intentionally ignore: best-effort cleanup. + } + } + + foreach (var file in Directory.EnumerateFiles(rootDir, ".gitattributes", SearchOption.AllDirectories)) + { + TryDelete(file); + } + + // Optional: also remove .gitignore (same class of non-functional metadata) + foreach (var file in Directory.EnumerateFiles(rootDir, ".gitignore", SearchOption.AllDirectories)) + { + TryDelete(file); + } + } }