Skip to content

Commit 290f7cc

Browse files
committed
hash generation on release build
1 parent 969b593 commit 290f7cc

5 files changed

Lines changed: 165 additions & 61 deletions

File tree

build/Build.cs

Lines changed: 68 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ partial class Build : NukeBuild
3434
/// - JetBrains Rider https://nuke.build/rider
3535
/// - Microsoft VisualStudio https://nuke.build/visualstudio
3636
/// - Microsoft VSCode https://nuke.build/vscode
37-
public static int Main() => Execute<Build>(x => x.Test);
37+
public static int Main () => Execute<Build>(x => x.Test);
3838

3939
[Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")]
4040
readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release;
@@ -120,7 +120,7 @@ Version Version
120120
ChocolateyDirectory / $"logexpert.{VersionString}.nupkg"
121121
];
122122

123-
protected override void OnBuildInitialized()
123+
protected override void OnBuildInitialized ()
124124
{
125125
SetVariable("DOTNET_CLI_TELEMETRY_OPTOUT", "1");
126126

@@ -191,6 +191,58 @@ protected override void OnBuildInitialized()
191191
.SetMaxCpuCount(Environment.ProcessorCount));
192192
});
193193

194+
AbsolutePath PluginHashGeneratorProject => SourceDirectory / "PluginHashGenerator.Tool" / "PluginHashGenerator.Tool.csproj";
195+
196+
AbsolutePath PluginHashGeneratedFile => SourceDirectory / "PluginRegistry" / "PluginHashGenerator.Generated.cs";
197+
198+
Target GeneratePluginHashes => _ => _
199+
.After(Compile)
200+
.OnlyWhenStatic(() => Configuration == Configuration.Release)
201+
.Executes(() =>
202+
{
203+
var pluginsDir = OutputDirectory / "plugins";
204+
var pluginsx86Dir = OutputDirectory / "pluginsx86";
205+
206+
// Check if any plugins exist
207+
if (!pluginsDir.DirectoryExists() && !pluginsx86Dir.DirectoryExists())
208+
{
209+
Log.Warning("No plugins directories found. Skipping plugin hash generation.");
210+
return;
211+
}
212+
213+
Log.Information("Generating plugin hashes...");
214+
Log.Information($" Output Path: {OutputDirectory}");
215+
Log.Information($" Target File: {PluginHashGeneratedFile}");
216+
Log.Information($" Configuration: {Configuration}");
217+
218+
try
219+
{
220+
DotNetRun(s => s
221+
.SetProjectFile(PluginHashGeneratorProject)
222+
.SetApplicationArguments([OutputDirectory, PluginHashGeneratedFile, Configuration])
223+
.SetProcessWorkingDirectory(RootDirectory));
224+
225+
Log.Information("Plugin hashes generated successfully");
226+
227+
// Rebuild PluginRegistry project to include the generated file
228+
// IMPORTANT: Set OutputPath to match the main build output directory
229+
Log.Information("Rebuilding PluginRegistry to include generated hashes...");
230+
MSBuild(s => s
231+
.SetTargetPath(SourceDirectory / "PluginRegistry" / "LogExpert.PluginRegistry.csproj")
232+
.SetTargets("Build")
233+
.SetConfiguration(Configuration)
234+
.SetProperty("OutputPath", OutputDirectory)
235+
.SetMaxCpuCount(Environment.ProcessorCount));
236+
237+
Log.Information("PluginRegistry rebuilt successfully to {OutputDir}", OutputDirectory);
238+
}
239+
catch (Exception ex)
240+
{
241+
Log.Error(ex, "Failed to generate plugin hashes");
242+
throw;
243+
}
244+
});
245+
194246
Target Test => _ => _
195247
.DependsOn(Compile)
196248
.Executes(() =>
@@ -308,42 +360,25 @@ protected override void OnBuildInitialized()
308360
.SetVersion(VersionString));
309361
});
310362

311-
Target ColumnizerLibCreateNuget => _ => _
312-
.DependsOn(Compile, Test)
313-
.Executes(() =>
314-
{
315-
var columnizerFolder = SourceDirectory / "ColumnizerLib";
316-
317-
NuGetTasks.NuGetPack(s =>
318-
{
319-
s = s.SetTargetPath(columnizerFolder / "ColumnizerLib.csproj")
320-
.EnableBuild()
321-
.SetConfiguration(Configuration)
322-
.SetProperty("version", VersionString)
323-
.SetOutputDirectory(BinDirectory);
324-
325-
return s;
326-
});
327-
});
328-
329363
Target Pack => _ => _
330-
.DependsOn(BuildChocolateyPackage, CreatePackage, PackageSftpFileSystem, ColumnizerLibCreate, CopyLicenses);
364+
.DependsOn(BuildChocolateyPackage, CreatePackage, PackageSftpFileSystem, ColumnizerLibCreate, CopyLicenses, GeneratePluginHashes, CreateSetup);
331365

332366
Target CopyFilesForSetup => _ => _
333367
.DependsOn(Compile)
334368
.After(Test)
335369
.Executes(() =>
336370
{
337-
OutputDirectory.Copy(SetupDirectory, ExistsPolicy.DirectoryMerge);
371+
OutputDirectory.Copy(SetupDirectory, ExistsPolicy.MergeAndOverwriteIfNewer);
338372
SetupDirectory.GlobFiles(ExcludeFileGlob).ForEach(file => file.DeleteFile());
339373

340374
SetupDirectory.GlobDirectories(ExcludeDirectoryGlob).ForEach(dir => dir.DeleteDirectory());
341375
});
342376

343377
Target CreateSetup => _ => _
344-
.DependsOn(CopyFilesForSetup, ChangeVersionNumber)
378+
.DependsOn(CopyFilesForSetup, ChangeVersionNumber, Compile)
345379
.Before(Publish)
346-
.OnlyWhenStatic(() => Configuration == "Release")
380+
.After(GeneratePluginHashes)
381+
.OnlyWhenStatic(() => Configuration == Configuration.Release)
347382
.Executes(() =>
348383
{
349384
var publishCombinations =
@@ -498,7 +533,7 @@ protected override void OnBuildInitialized()
498533
}
499534
});
500535

501-
private void ExecuteInnoSetup(AbsolutePath innoPath)
536+
private void ExecuteInnoSetup (AbsolutePath innoPath)
502537
{
503538
Process proc = new();
504539

@@ -520,12 +555,12 @@ private void ExecuteInnoSetup(AbsolutePath innoPath)
520555
}
521556
}
522557

523-
private string ReplaceVersionMatch(Match match, string replacement)
558+
private string ReplaceVersionMatch (Match match, string replacement)
524559
{
525560
return $"{match.Groups[1]}{replacement}{match.Groups[3]}";
526561
}
527562

528-
private void TransformTemplateFile(AbsolutePath path, bool deleteTemplate)
563+
private void TransformTemplateFile (AbsolutePath path, bool deleteTemplate)
529564
{
530565
string text = path.ReadAllText();
531566
text = text.Replace("##version##", VersionString);
@@ -539,20 +574,20 @@ private void TransformTemplateFile(AbsolutePath path, bool deleteTemplate)
539574
}
540575

541576
[GeneratedRegex(@"(\[assembly: AssemblyInformationalVersion\("")([^""]*)(""\)\])")]
542-
private static partial Regex AssemblyInformationalVersion();
577+
private static partial Regex AssemblyInformationalVersion ();
543578

544579
[GeneratedRegex(@"(\[assembly: AssemblyVersion\("")([^""]*)(""\)\])")]
545-
private static partial Regex AssemblyVersion();
580+
private static partial Regex AssemblyVersion ();
546581

547582
[GeneratedRegex(@"(\[assembly: AssemblyConfiguration\()(""[^""]*"")(\)\])")]
548-
private static partial Regex AssemblyConfiguration();
583+
private static partial Regex AssemblyConfiguration ();
549584

550585
[GeneratedRegex(@"(\[assembly: AssemblyFileVersion\("")([^""]*)(""\)\])")]
551-
private static partial Regex AssemblyFileVersion();
586+
private static partial Regex AssemblyFileVersion ();
552587

553588
[GeneratedRegex(@"\w\w{2}[_]p?[tso]?[erzliasx]+[_rhe]{5}", RegexOptions.IgnoreCase, "en-GB")]
554-
private static partial Regex SFTPPlugin();
589+
private static partial Regex SFTPPlugin ();
555590

556591
[GeneratedRegex("\\.template$")]
557-
private static partial Regex TemplateRegex();
592+
private static partial Regex TemplateRegex ();
558593
}

src/PluginRegistry/PluginHashGenerator.Generated.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,35 @@ public static partial class PluginValidator
1010
{
1111
/// <summary>
1212
/// Gets pre-calculated SHA256 hashes for built-in plugins.
13-
/// Generated: 2025-12-01 16:28:17 UTC
13+
/// Generated: 2025-12-01 20:15:57 UTC
1414
/// Configuration: Release
1515
/// Plugin count: 21
1616
/// </summary>
1717
public static Dictionary<string, string> GetBuiltInPluginHashes()
1818
{
1919
return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
2020
{
21-
["AutoColumnizer.dll"] = "FF0ED3DBD0DF2AD9AB69D7F57D4B342AA5D5F5E1F634FBBD2A5FFD910C2B3E32",
21+
["AutoColumnizer.dll"] = "2F35380276BC50E75501042BAA30AB28FAFC2C75B7FAAC291A6E8081FF55848D",
2222
["BouncyCastle.Cryptography.dll"] = "E5EEAF6D263C493619982FD3638E6135077311D08C961E1FE128F9107D29EBC6",
2323
["BouncyCastle.Cryptography.dll (x86)"] = "E5EEAF6D263C493619982FD3638E6135077311D08C961E1FE128F9107D29EBC6",
24-
["CsvColumnizer.dll"] = "ACA9628F8BF040FCDE60F315BB3F90E8DA73FE3554AE12C596977581AB3CD051",
25-
["CsvColumnizer.dll (x86)"] = "ACA9628F8BF040FCDE60F315BB3F90E8DA73FE3554AE12C596977581AB3CD051",
26-
["DefaultPlugins.dll"] = "ED702576F7BA1F990EBA0C12F1B8E87C17BBC73B3C6A8D0FB7FBFA5A565DA28A",
27-
["FlashIconHighlighter.dll"] = "238FA09C6FF890EABB5733B991C0D6832C485AF9A2DC6FF150F0DC5E9F4600CA",
28-
["GlassfishColumnizer.dll"] = "375D0A2F8C5306115F8BAD3402E190607E5F1FBAB494A81603E26905977B6085",
29-
["JsonColumnizer.dll"] = "479B148FA380F36EFD36559ADDE77104D769B003AC6FA61A57A62D64C2ABD6FE",
30-
["JsonCompactColumnizer.dll"] = "7A7960116E4E9AB6C822FB76318483EBBB481D088E5CE87E26228092DA669698",
31-
["Log4jXmlColumnizer.dll"] = "E2595D46D882F04686A17E1196E6E032E6BDF57FA490DFAED8E44C28236114FC",
32-
["LogExpert.Core.dll"] = "A39033D18E452306C8084C3E9882F88E866A440792C302BD3DEDAA18D12874DB",
24+
["CsvColumnizer.dll"] = "F981D01F5800E26839EDD321617EF99238D342A382B2FB187A8BD28C155530DD",
25+
["CsvColumnizer.dll (x86)"] = "F981D01F5800E26839EDD321617EF99238D342A382B2FB187A8BD28C155530DD",
26+
["DefaultPlugins.dll"] = "374BBCA9AADEFF62B8132F998905497F9874C235E8366D505B50BE068D470BE8",
27+
["FlashIconHighlighter.dll"] = "68D432BA92F9D4C55D3092DC60BBACD970992CE0850B265B6F932CB9F4463B42",
28+
["GlassfishColumnizer.dll"] = "368BFB8DAD0227FDE86F0DC181354469143B2A5DB7606657FC6E116CA0B2276D",
29+
["JsonColumnizer.dll"] = "35AB6B4A97D5F67162BFB86CEB1EF40E5EB23C7B1C4678AF854B117731E220ED",
30+
["JsonCompactColumnizer.dll"] = "5385F2C3B747D19343C414C9844CBF62A4534A08DCE70C37886D8C5FB169D0D4",
31+
["Log4jXmlColumnizer.dll"] = "473405959760982DA0DA88CBA7DAD731AF779F35F0A48CC496A5BC637BB160EB",
32+
["LogExpert.Core.dll"] = "63537559788737D1C537BF74D3A8ED5FD2F297D3E9213952331A3004D2B90025",
3333
["Microsoft.Extensions.DependencyInjection.Abstractions.dll"] = "67FA4325000DB017DC0C35829B416F024F042D24EFB868BCF17A895EE6500A93",
3434
["Microsoft.Extensions.DependencyInjection.Abstractions.dll (x86)"] = "67FA4325000DB017DC0C35829B416F024F042D24EFB868BCF17A895EE6500A93",
3535
["Microsoft.Extensions.Logging.Abstractions.dll"] = "BB853130F5AFAF335BE7858D661F8212EC653835100F5A4E3AA2C66A4D4F685D",
3636
["Microsoft.Extensions.Logging.Abstractions.dll (x86)"] = "BB853130F5AFAF335BE7858D661F8212EC653835100F5A4E3AA2C66A4D4F685D",
37-
["RegexColumnizer.dll"] = "B409178DB55845E03255FC5C5CAD77E1057FAA50AA009BBED89C95D557F661F2",
38-
["SftpFileSystem.dll"] = "0B33C65EC692D8514E541E9B0CFAB718123679C326C65F511E0BF1A89C2BF681",
39-
["SftpFileSystem.dll (x86)"] = "2832363F320463C9781AFC97205567954633DEFBB5CE44DCED39E8B5F8B21D27",
40-
["SftpFileSystem.Resources.dll"] = "54EF796F05DAEAA883E095B16B257E2D885F73151BE4EFDB640FD863033793CF",
41-
["SftpFileSystem.Resources.dll (x86)"] = "54EF796F05DAEAA883E095B16B257E2D885F73151BE4EFDB640FD863033793CF",
37+
["RegexColumnizer.dll"] = "CB6ED4AA1E44FED173F36D2026C4962C98901867FB558183EC5AE85E46740146",
38+
["SftpFileSystem.dll"] = "4ACDC0BC5A8A0CBE30CA712560A1FE28EE485F2ADF074A19BFEC335CC6ECDC29",
39+
["SftpFileSystem.dll (x86)"] = "124F4845FF1A422052A2915AFFA2A6039177845C1372D185C5B1A55EA74667C9",
40+
["SftpFileSystem.Resources.dll"] = "BD0AD236AA3BC1A5E95C296A40B8265311F8B6E8A77DCCF06EA99782673D2432",
41+
["SftpFileSystem.Resources.dll (x86)"] = "BD0AD236AA3BC1A5E95C296A40B8265311F8B6E8A77DCCF06EA99782673D2432",
4242

4343
};
4444
}

src/Solution Items/AssemblyInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
using System.Reflection;
22
using System.Runtime.InteropServices;
33

4-
[assembly: AssemblyConfiguration("")]
4+
[assembly: AssemblyConfiguration("Release")]
55
[assembly: AssemblyProduct("LogExpert")]
66
[assembly: AssemblyCopyright("Original work Copyright (c) 2008-2011 Hagen Raab\r\nModified work Copyright (c) 2025 Zarunbal|Hirogen and many others")]
77

88
[assembly: AssemblyVersion("1.21.0")]
99
[assembly: AssemblyFileVersion("1.21.0")]
10-
[assembly: AssemblyInformationalVersion("1.21.0")]
10+
[assembly: AssemblyInformationalVersion("1.21.0 Release")]
1111

1212
[assembly: ComVisible(false)]
13-
//warning CA1824: Mark assemblies with NeutralResourcesLanguageAttribute
13+
//warning CA1824: Mark assemblies with NeutralResourcesLanguageAttribute

src/docs/PLUGIN_HASH_MANAGEMENT.md

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ LogExpert uses SHA256 hashes to verify plugin integrity and prevent tampering. W
66

77
## Automated Process
88

9-
### Option 1: Using the Hash Generator Tool (Recommended)
9+
### Option 1: Using the Hash Generator Tool (Manual)
1010

1111
After building plugins:
1212

@@ -21,7 +21,7 @@ This will:
2121
- Generate `PluginHashGenerator.Generated.cs` with the `GetBuiltInPluginHashes()` method
2222
- Automatically integrate with the partial class `PluginValidator`
2323

24-
### Option 2: MSBuild Integration (Automatic)
24+
### Option 2: MSBuild Integration (Automatic during regular builds)
2525

2626
The plugin hashes are automatically regenerated during Release builds if `GeneratePluginHashesEnabled` is set to `true`.
2727

@@ -63,13 +63,50 @@ dotnet build src/LogExpert.sln --configuration Release
6363
dotnet build src/PluginRegistry/LogExpert.PluginRegistry.csproj /t:GeneratePluginHashes --configuration Release
6464
```
6565

66-
### Option 3: Nuke Build Target
66+
### Option 3: Nuke Build Integration (Recommended for Release builds)
67+
68+
The Nuke build system now includes automatic plugin hash generation as part of the Release build process.
69+
70+
**When Does It Run?**
71+
- Automatically as part of the `Pack` target when building in Release configuration
72+
- Can be run independently via the `GeneratePluginHashes` target
73+
- Only runs when building in Release configuration
74+
- Skips generation if no plugins directories exist
75+
76+
**Usage Examples:**
6777

6878
```powershell
6979
# From repository root
70-
./build.ps1 --target GeneratePluginHashes
80+
81+
# Full release build with hash generation
82+
./build.ps1 --target Pack --configuration Release
83+
84+
# Only generate plugin hashes (after plugins are built)
85+
./build.ps1 --target GeneratePluginHashes --configuration Release
86+
87+
# Complete release workflow
88+
./build.ps1 --target Clean Compile GeneratePluginHashes Pack --configuration Release
7189
```
7290

91+
**What the Nuke target does:**
92+
1. Checks if plugins exist in `bin/Release/plugins` or `bin/Release/pluginsx86`
93+
2. Runs the PluginHashGenerator.Tool to scan and hash all plugin DLLs
94+
3. Generates `PluginHashGenerator.Generated.cs` with updated hashes
95+
4. Rebuilds the PluginRegistry project to include the newly generated file
96+
5. Logs detailed information about the process
97+
98+
**Integration with other targets:**
99+
- `GeneratePluginHashes` runs **after** `Compile`
100+
- `Pack` target **depends on** `GeneratePluginHashes` (along with other packaging tasks)
101+
- When creating installers/packages, hashes are always up-to-date
102+
103+
**Benefits:**
104+
- ✅ Ensures hashes are always generated during Release packaging
105+
- ✅ No manual intervention needed for release builds
106+
- ✅ Prevents shipping releases with outdated or missing hashes
107+
- ✅ Integrated logging for troubleshooting
108+
- ✅ Automatically rebuilds PluginRegistry to include generated file
109+
73110
## File Structure
74111

75112
```
@@ -82,6 +119,8 @@ src/
82119
├── PluginHashGenerator.Tool/
83120
│ ├── Program.cs # Hash generator implementation
84121
│ └── PluginHashGenerator.Tool.csproj
122+
build/
123+
└── Build.cs # Nuke build with GeneratePluginHashes target
85124
```
86125

87126
## Generated Code Example
@@ -219,8 +258,21 @@ dotnet run --project src/PluginHashGenerator.Tool/PluginHashGenerator.Tool.cspro
219258
```
220259
## Quick Start Guide
221260

222-
After modifying plugins, regenerate hashes:
261+
### For Regular Development (Debug builds)
262+
No action needed - hashes are bypassed in Debug configuration.
263+
264+
### For Release Builds
223265

266+
**Using Nuke Build (Recommended):**
267+
```powershell
268+
# From repository root
269+
cd G:\Github\LogExpert
270+
271+
# Full release build (hashes generated automatically)
272+
./build.ps1 --target Pack --configuration Release
273+
```
274+
275+
**Manual Process:**
224276
```powershell
225277
# 1. Build the tool first (if not already built)
226278
cd G:\Github\LogExpert
@@ -234,3 +286,15 @@ dotnet run --project src/PluginHashGenerator.Tool/PluginHashGenerator.Tool.cspro
234286
235287
# 4. Rebuild to include the generated file
236288
dotnet build src/PluginRegistry/LogExpert.PluginRegistry.csproj --configuration Release
289+
```
290+
291+
### After Modifying Plugins
292+
293+
If you modify any plugin code, regenerate hashes before creating a release:
294+
295+
```powershell
296+
# Rebuild and regenerate hashes
297+
./build.ps1 --target Clean Compile GeneratePluginHashes --configuration Release
298+
299+
# Or just regenerate if already built
300+
./build.ps1 --target GeneratePluginHashes --configuration Release

src/setup/LogExpertInstaller.iss

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
; Path of the inno setup file
1212
#define AppPath SourcePath
1313
#define SetupName "LogExpert.Installer"
14-
#define ReleaseFolder = "..\..\bin\Debug"
14+
#define ReleaseFolder = "..\..\bin\Release"
1515

1616
[Setup]
1717
; NOTE: The value of AppId uniquely identifies this application.
@@ -27,7 +27,7 @@ AppVerName={#AppName} {#AppVersion}
2727
AppPublisherURL={#AppURL}
2828
AppSupportURL={#AppURL}
2929
AppUpdatesURL={#AppURL}
30-
DefaultDirName={pf}\{#AppName}
30+
DefaultDirName={commonpf}\{#AppName}
3131
DefaultGroupName={#AppName}
3232
AllowNoIcons=yes
3333

@@ -191,8 +191,13 @@ Filename: "{app}\{#AppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(
191191

192192
[Code]
193193
function InitializeSetup(): Boolean;
194+
var ErrCode: integer;
194195
begin
195-
Dependency_ForceX86 := False;
196-
Dependency_AddDotNet100Desktop;
196+
if not Dependency_IsNetCoreInstalled('Microsoft.AspNetCore.App', 10, 0, 0) then begin
197+
if MsgBox('.net 10 64Bit is missing do you want to download it from https://dotnet.microsoft.com/download/dotnet/10.0 ?', mbConfirmation, MB_YESNO) = IDYES then
198+
begin
199+
ShellExecAsOriginalUser('open', 'https://dotnet.microsoft.com/download/dotnet/10.0', '', '', SW_SHOW, ewNoWait, ErrCode);
200+
end;
201+
end;
197202
Result := True;
198203
end;

0 commit comments

Comments
 (0)