Contributing to Pakko

Prerequisites

  • Visual Studio 2026 with the .NET desktop and Desktop development with C++ workloads, plus the MSVC v143 (14.44) x64 and ARM64 build tools (the shell extension targets v143; the Native AOT link of the four exes, T-F355, uses the same C++ tools)
  • .NET 10 SDK (global.json pins the 10.0.100 feature band or later)
  • Language: C# 14 (set once in Directory.Build.props)
  • PowerShell 7 (pwsh) for scripts/*.ps1 (T-F371)
  • Windows 10 1809+ or Windows 11

Building and testing

# Build the core library (works from any terminal)
dotnet build src/Archiver.Core

# Run all tests (excludes a handful of real multi-second Zip64/performance tests and a couple of
# genuinely large, on-demand-only tests)
dotnet test --filter "Category!=Slow&Category!=VeryLarge"

# Run the Zip64 tests too, before a release or when touching Zip64-adjacent code
dotnet test --filter "Category=Slow"

Always run dotnet test with no path argument — all projects must stay green after every change.

The WinUI 3 application (Archiver.App) is debugged from Visual Studio 2026. dotnet build src/Archiver.Core and dotnet test work freely from the terminal — as does dotnet build src/Archiver.App, which compiles the WinUI project (useful as a quick compile-check on ViewModel/XAML changes without opening Visual Studio), though full MSIX packaging/signing/running still needs Deploy.ps1 or Visual Studio.

Never verify an on-device UI or interaction change against a package installed by a bare dotnet build. Its incremental packaging step can silently skip repackaging a changed DLL into the installed .msix — confirmed to go as far as running a stale event handler's old logic entirely, while still reporting "Build succeeded" and showing a fresh-looking title-bar build timestamp. Always run the full .\scripts\Deploy.ps1 (it wipes old AppPackages output before rebuilding) before trusting any on-device check. See scripts/README.md for usage.


Static analysis

Directory.Build.props enables AnalysisLevel=latest-recommended + EnforceCodeStyleInBuild repo-wide, so a plain dotnet build/dotnet test already surfaces real .NET analyzer findings (reviewed severity overrides for known-noisy families live in .editorconfig) — no separate step needed to see these locally.

For the same SonarSource rule engine SonarCloud runs in CI (S3869, S6562, etc.), install the free SonarLint extension for your editor — Visual Studio, VS Code, or Rider. It flags the same issues live in the editor, before a commit ever reaches CI. See docs/TASKS.md's T-F137 entry for the rationale.


Test fixtures

tests/Archiver.Core.Tests.GenerateFixtures is a standalone console project that creates the binary ZIP fixtures consumed by Archiver.Core.Tests. Fixtures are pre-generated and committed to the repository — you do not need to regenerate them on a normal clone.

Regenerate fixtures when:

  • Adding new tests that require new fixture files
  • Existing fixtures become corrupted
dotnet run --project tests/Archiver.Core.Tests.GenerateFixtures

Output goes to tests/Archiver.Core.Tests/Fixtures/.


Local MSIX deployment

For local development and testing you need a signed MSIX. See scripts/README.md for full details. The short version:

  1. Once per machine — create and install a self-signed developer certificate:

    .\scripts\Setup-DevCert.ps1
    

    Copy the thumbprint it prints.

  2. After each build — package and sideload:

    .\scripts\Deploy.ps1
    # or: .\scripts\Deploy.ps1 -Thumbprint "<thumbprint>"
    

    Visual Studio shortcut — Release builds in VS trigger Deploy.ps1 -DeployOnly automatically via a post-build event. No manual script needed after first setup; just build in Release and the new MSIX is installed automatically. Use .\scripts\Deploy.ps1 from the terminal for a full build + deploy outside of Visual Studio.

CI: every push to main and every pull request also builds and tests automatically via .github/workflows/build.yml — this doesn't replace the local steps above, it just means a red test suite or a broken build/sign step gets caught before merge. See scripts/README.md's "Continuous Integration" section for what it builds and how it's signed.


Testing the Explorer hand-off

After installing the MSIX, run the installed Archiver.Shell.exe --open-ui --extract <archive> and check that Pakko opens with the archive in its list — the exact command is in scripts/README.md, Step 3. (Pakko registers no pakko:// URI scheme since T-F232.)


Project structure

Project Role
Archiver.Core Compression/extraction logic and the tar.exe AppContainer sandbox — no UI dependencies, no NuGet packages
Archiver.App.Core WinUI-free helpers for Archiver.App (Archive Browser tree/breadcrumb building, real-filesystem browsing, file-activation routing) — kept separate so they're unit-testable without a WinUI test host
Archiver.App WinUI 3 main application
Archiver.Shell Shell-triggered operation entry point (silent CLI, launched by the shell extension); shows progress via the Windows Shell's built-in IProgressDialog, in-process
Archiver.ShellExtension C++ COM DLL implementing IExplorerCommand (the actual right-click context menu) — built via MSBuild, not dotnet build; see .claude/rules/shell-extension.md
Archiver.CLI Standalone console frontend (T-F09), built as pakko.exe — no WinUI; ships as its own self-contained per-architecture download via scripts/Publish-Cli.ps1 (and winget), and since T-F317 also inside the MSIX behind the pakko execution alias; see docs/CLI.md
Archiver.Messages Core's error/skip messages in 37 languages, shared by Archiver.Shell and Archiver.App (T-F209)
Archiver.Core.Tests Unit tests for core compression/extraction logic
Archiver.Core.IntegrationTests Tests that shell out to the real C:\Windows\System32\tar.exe (tagged [Integration])
Archiver.Core.PerformanceTests ZIP compression/extraction performance-regression tests vs. a vendored, sandboxed 7za.exe reference (T-F114); see docs/TESTING.md
Archiver.App.Core.Tests Unit tests for Archiver.App.Core's WinUI-free helpers
Archiver.Shell.Tests Argument parser tests for Archiver.Shell
Archiver.ShellExtension.Tests C++ Google Test suite for Archiver.ShellExtension's COM-free logic — run separately, not covered by dotnet test; see .claude/rules/shell-extension.md
Archiver.Messages.Tests Translation parity for Archiver.Messages and its culture resolver
Archiver.CLI.Tests Parser/mapper/help-text unit tests for Archiver.CLI plus a Subprocess/ layer that launches the real built pakko.exe; see docs/CLI.md
Archiver.Core.Tests.GenerateFixtures Fixture generator (see above)

There is no Archiver.ProgressWindow project — an earlier design (a second WinUI 3 satellite .exe talking to Archiver.Shell over a named pipe) was removed; see docs/DECISIONS.md (T-F65).