Skip to content

Building from Source

Kevin Peter Koekemoer edited this page Oct 7, 2026 · 1 revision

πŸ› οΈ Building from Source & CI/CD

Metadata Editor is written in C# using .NET 8.0 WPF (net8.0-windows) with an MVVM architecture and automated xUnit test suite.


🧰 Prerequisites

  • .NET 8.0 SDK (Windows x64)
  • Windows 10 or Windows 11
  • (Optional) Visual Studio 2022 (with .NET Desktop Development workload) or VS Code
  • (Optional) Inno Setup 6 (for compiling the Windows MetadataEditor-Setup-v<Version>.exe installer)

πŸ—οΈ Project Architecture

MetadataEditor/
β”œβ”€β”€ .github/workflows/
β”‚   └── build-and-release.yml      # CI/CD pipeline for automated builds, tests & GitHub Releases
β”œβ”€β”€ Samples/                       # Sample NFO files (Movie, TV Show, Episode, Album, Scene ASCII)
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ MetadataEditor/            # Main WPF Desktop Application
β”‚   β”‚   β”œβ”€β”€ Models/                # NfoMetadata, ArtworkItem, ActorItem, TrackItem, XmlExtraItem, AppSettings
β”‚   β”‚   β”œβ”€β”€ Services/              # NfoParserService, FileEncodingDetector, SettingsService, ThemeService, UpdateService
β”‚   β”‚   β”œβ”€β”€ ViewModels/            # MainViewModel, SettingsViewModel, RelayCommand
β”‚   β”‚   β”œβ”€β”€ Views/                 # SettingsWindow, Converters
β”‚   β”‚   β”œβ”€β”€ Styles/                # Theme.xaml (Dynamic Dark/Midnight/Light resource brushes)
β”‚   β”‚   β”œβ”€β”€ Resources/             # app.ico, app.svg, generate-icon.ps1
β”‚   β”‚   └── MainWindow.xaml        # Main 3-tab shell & sidebar browser
β”‚   └── tests/
β”‚       └── MetadataEditor.Tests/  # xUnit automated test suite
β”œβ”€β”€ build-portable.bat             # Builds framework-dependent portable distribution
β”œβ”€β”€ build-single-file.bat          # Builds self-contained single-file executable
β”œβ”€β”€ installer.iss                  # Inno Setup installer script
└── MetadataEditor.sln             # Solution file

πŸš€ Building & Running Tests via CLI

Clone the repository and run the standard .NET CLI commands from the repository root:

# 1. Clone the repository
git clone https://github.com/KevinK56/MetadataEditor.git
cd MetadataEditor

# 2. Restore and build the solution
dotnet build MetadataEditor.sln -c Release

# 3. Run the automated xUnit test suite
dotnet test MetadataEditor.sln -c Release

# 4. Run the application
dotnet run --project src/MetadataEditor/MetadataEditor.csproj

πŸ“¦ Producing Release Builds Locally

1. Self-Contained Single-File Executable

Run build-single-file.bat or execute:

dotnet publish src/MetadataEditor/MetadataEditor.csproj `
  -c Release `
  -r win-x64 `
  --self-contained true `
  -p:PublishSingleFile=true `
  -p:IncludeNativeLibrariesForSelfExtract=true `
  -p:EnableCompressionInSingleFile=true `
  -o release/single-file

2. Portable Framework-Dependent Build

Run build-portable.bat or execute:

dotnet publish src/MetadataEditor/MetadataEditor.csproj `
  -c Release `
  -r win-x64 `
  --self-contained false `
  -o release/portable

3. Inno Setup Windows Installer

With Inno Setup 6 installed:

"C:\Program Files (x86)\Inno Setup 6\ISCC.exe" /DMyAppVersion="2026.10.08.1" installer.iss

This outputs release\installer\MetadataEditor-Setup-v2026.10.08.1.exe.


πŸ€– Continuous Integration & Automated Releases

Every push to master runs the GitHub Actions workflow .github/workflows/build-and-release.yml:

  1. Dynamic Versioning: Calculates the build version from the UTC date and git commit count (YYYY.MM.DD.<CommitCount>).
  2. Automated Testing: Runs all unit tests in MetadataEditor.Tests (XML parsing, extra node attribute preservation, encoding detection, settings persistence, update service version comparison).
  3. Artifact Compilation: Builds the self-contained single-file MetadataEditor.exe, portable .zip bundle, and Inno Setup installer MetadataEditor-Setup-v<Version>.exe.
  4. GitHub Release Publishing: Automatically tags the commit and publishes all three release artifacts so users receive updates directly via the in-app UpdateService.

Clone this wiki locally