Repository navigation
building
This page covers SDK requirements, build and publish commands, and the CI pipeline.
-
.NET SDK 10.0.301 or newer 10.0.3xx patch — pinned in
global.json(rollForward: latestPatch): 10.0.3xx patches are accepted; newer 10.0.4xx feature bands and 11+ are not, and anything older than 10.0.301 (e.g. a VS-shipped 10.0.1xx) fails before build. - Any OS supported by .NET (the CI builds on Windows, Linux, and macOS).
- No native toolchain is required — this is a pure managed codebase.
git clone https://github.com/purelogiccode/XISOSharp.git
cd XISOSharp
# Restore + build everything (Debug)
dotnet build CSharp_XISOSharp.sln
# Release build
dotnet build CSharp_XISOSharp.sln -c Release
# Build just the CLI or the library
dotnet build XISOSharp.Cli -c Release
dotnet build XISOSharp -c ReleaseThe solution contains:
| Project | Target(s) | Output |
|---|---|---|
XISOSharp |
net8.0, net9.0, net10.0 |
XISOSharp.dll + NuGet package |
XISOSharp.Cli |
net8.0, net9.0, net10.0 (ships: net10.0) |
XISOSharp executable |
XISOSharp.Gui |
net10.0 | Avalonia GUI (shippable, shells out to the CLI) |
XISOSharp.Tests |
net8.0, net9.0, net10.0 | xUnit test assembly (engine + CLI) |
ZArchiveSharp (ZArchiveSharp.Tests / ZArchiveSharp.Benchmarks / ZArchiveSharp.Cli) |
— | Lives in the sibling ../CSharp_ZArchiveSharp repo (own solution); consumed here as NuGet package ZArchiveSharp 1.4.0 (ZArchiveSharp.Cli is a dotnet tool, not a library reference) |
XISOSharp.Benchmarks |
net10.0 | BenchmarkDotNet harness |
XISOSharpTester |
net10.0-windows | WPF regression-test rig (Windows-only, runs from build output) |
Note
Two GUI stacks, different jobs: XISOSharp.Gui (Avalonia, cross-platform) is
the shippable GUI — it shells out to the CLI and publishes per-RID via
publish-gui.ps1. XISOSharpTester (WPF, Windows-only) is the in-process
regression rig for engine + reference-tool interop (see Testing);
it runs from its build output (dotnet run --project XISOSharpTester) and is
intentionally not published single-file. Both (plus the battle harness) share
the single XISOSharp.ProcessRunner + XISOSharp.ToolLocator
(override → sibling → PATH + -v probe) in the core library — no per-app runners.
Note
The Core project packs a NuGet package only via an explicit
dotnet pack XISOSharp -c Release -o ./artifacts (CI pack job, releases) —
plain dotnet build stays clean (GeneratePackageOnBuild is off).
dotnet test XISOSharp.Tests
dotnet test XISOSharp.Tests -c ReleaseThe suite is xUnit-based and runs sequentially (many historical tests set the process working directory, so the assembly disables parallelization). Create and extract themselves are CWD-free and covered by concurrent-operation tests. With code coverage:
dotnet test XISOSharp.Tests --collect:"XPlat Code Coverage"See Testing for the full picture, including cross-checking against the reference C tool.
The CLI can be published as a self-contained single-file executable — no .NET runtime required on the target machine:
# Windows x64
dotnet publish XISOSharp.Cli -c Release -f net10.0 -r win-x64 --self-contained
# Linux x64
dotnet publish XISOSharp.Cli -c Release -f net10.0 -r linux-x64 --self-contained
# macOS (Intel / Apple Silicon)
dotnet publish XISOSharp.Cli -c Release -f net10.0 -r osx-x64 --self-contained
dotnet publish XISOSharp.Cli -c Release -f net10.0 -r osx-arm64 --self-contained(-f net10.0 is required: the CLI multi-targets net8/9/10, but only net10.0
ships. PublishSingleFile needs no -p: override — it defaults on in the
csproj. publish-cli.ps1 / publish-gui.ps1 wrap this loop for all RIDs.)
Supported runtime identifiers (single source of truth: XISOSharp.Cli.csproj /
XISOSharp.Gui.csproj RuntimeIdentifiers, matching the publish-*.ps1 defaults):
win-x86; win-x64; win-arm64; linux-x64; linux-arm64; osx-x64; osx-arm64 for the
CLI (XboxKit parity, incl. the 32-bit win-x86); the GUI ships the six 64-bit
RIDs only.
Output lands in XISOSharp.Cli/bin/Release/net10.0/<rid>/publish/ as a single
XISOSharp (or XISOSharp.exe) binary (renamed from the XISOSharp.Cli
assembly name by the csproj RenamePublishedExeToXisoSharp target).
The library package (XISOSharp) is configured in XISOSharp.csproj:
| Setting | Value |
|---|---|
| Version | Derived from git tags via MinVer (v1.0.2 / 1.0.2) |
| Symbols |
snupkg with SourceLink (EmbedAllSources, EmbedUntrackedSources; library only — apps carry embedded/portable PDBs) |
| Reproducibility |
Deterministic + ContinuousIntegrationBuild on CI (repo-wide, incl. CLI/GUI binaries) |
| Signing | Strong-named (XISOSharp.snk, committed — contributors sign with no setup) |
| Trimming/AOT |
IsTrimmable, AOT-compatible library surface (no in-repo AOT publish) |
| API validation |
EnablePackageValidation + strict mode (library only — apps ship as binaries, not NuGet) |
| Metadata | MIT license, README, icon, tags (xiso, xbox, extract-xiso, …) |
Pack manually:
dotnet pack XISOSharp -c Release -o ./artifactsBesides the NuGet package and the six RID bundles, the repository ships desktop-integration artifacts:
| Artifact | Source | Validation |
|---|---|---|
| PowerShell/bash/zsh/fish completions | docs/completions/ |
packaging-smoke: parsers + scripts/check_cli_completions.py
|
xisosharp(1) man page |
docs/man/xisosharp.1 |
groff render + mandoc lint |
| winget manifests | packaging/winget/manifests/... |
winget validate and a local manifest install |
| Scoop manifest |
packaging/scoop/xisosharp.json and bucket/xisosharp.json
|
installed from the repository-root bucket |
| Homebrew cask | packaging/homebrew/xisosharp.rb |
brew install --cask on macOS |
| Container image | Dockerfile |
.github/workflows/docker.yml builds, smoke-tests and (on tags) pushes ghcr.io/purelogiccode/xisosharp
|
scripts/update-packaging.ps1 -Version <version> regenerates the winget, Scoop
and Homebrew manifests (including SHA-256 values) from a published GitHub
release. Signs are optional and gated on repository configuration:
| Feature | Configuration |
|---|---|
| NuGet author signing |
NUGET_SIGNING_CERT (base64 PFX) + NUGET_SIGNING_PASSWORD secrets; optional NUGET_SIGNING_TIMESTAMPER variable |
| Windows Authenticode |
ENABLE_WINDOWS_SIGNING=true variable + WINDOWS_SIGNING_CERT / WINDOWS_SIGNING_PASSWORD secrets |
| macOS codesign |
ENABLE_MACOS_SIGNING=true variable + MACOS_SIGNING_CERT / MACOS_SIGNING_PASSWORD / MACOS_SIGNING_IDENTITY secrets |
| macOS notarization | additionally MACOS_NOTARY_APPLE_ID / MACOS_NOTARY_TEAM_ID / MACOS_NOTARY_PASSWORD
|
Unsigned builds remain the default; enabling a flag without its secrets fails the release job instead of silently publishing an unsigned bundle.
.github/workflows/ci.yml runs on every push/PR to master/main and on version
tags (v* or bare [0-9]*, both accepted by MinVer and the publish gate):
-
build-and-test - matrix over
ubuntu-latest,windows-latest,macos-latest: restore → format verification (Windows) → build (Release) → test theXISOSharp.Testsproject with XPlat code coverage. The merged line/branch coverage lands in the job summary (fails below 70% line / 60% branch), and the trx + coverage reports are uploaded as artifacts. -
gui-smoke - Windows:
XISOSharp -v,XISOSharp.Gui --probe-cliandXISOSharp.Gui --self-test, the headless contract the GUI ships with. -
docs-links - restores DocFX, builds the API metadata/reference into the
staged Docsify site and runs
scripts/check_docs_links.py; broken local Markdown/HTML links fail the job. -
inspectcode - JetBrains InspectCode (pinned
2026.2.3.1) over the whole solution; any warning or error fails the job and the SARIF report is uploaded to Security → Code scanning. -
dependency-audit -
dotnet list package --vulnerable --include-transitivefails on any known-vulnerable direct or transitive package. -
aot-smoke - publishes
XISOSharp.AotSmokewith NativeAOT on Linux and runs it, proving the library (and transitive ZAR/CCI packages) stay trim/AOT-compatible. - fuzz-smoke - two minutes of deterministic mutation fuzzing over ISO, CISO, CCI, ZAR, STFS and XBE/XEX inputs; any exception outside the documented format/I/O contract fails the job.
-
battle-interop - Windows: the CLI is compared against the checked-in
extract-xiso, xdvdfs and xboxkit oracles over the shared synthetic,
copyright-free corpus (
--synthetic, generated byPublicCorpusWriter) for list/extract/rewrite, checksum/md5, unpack/pack and CISO round-trip; reports are uploaded as artifacts. - packaging-smoke - Linux: parses/validates all four completion scripts, checks that every CLI flag is completable, and renders/lints the man page.
-
packaging-windows -
winget validateand Scoop/winget version/hash consistency checks. -
package-install-smoke - Windows installs the winget manifest and the
Scoop bucket, macOS installs the Homebrew cask; each runs
xisosharp -v. -
pack - after every gate:
dotnet packthe library (the only published package), optionally signs it, then uploads the nupkgs. -
publish (only on version tags, environment
nuget) - push the nupkgs to nuget.org using theNUGET_API_KEYsecret.
Companion workflows:
| Workflow | Trigger | Purpose |
|---|---|---|
codeql.yml |
push/PR to master, weekly |
CodeQL C# analysis → code scanning |
dependency-review.yml |
pull requests | Blocks high/critical vulnerable dependencies; PR summary |
scorecard.yml |
weekly, push to master
|
OpenSSF Scorecard supply-chain score → code scanning |
release.yml |
version tags | Builds the six RID bundles, optionally signs/notarizes them, smoke-tests them, creates the GitHub release |
docker.yml |
tag push, CLI/Dockerfile changes | Builds/smoke-tests the CLI image; publishes GHCR tags on releases |
pages.yml / wiki.yml
|
docs/** on master
|
Publish the Docsify site and mirror it to the wiki |
Dependabot (.github/dependabot.yml) opens grouped weekly PRs for NuGet
packages and GitHub Actions, and security updates are enabled repository-wide.
Pushing a version tag (1.6.0 or v1.6.0) does two independent things:
-
ci.ymlpacks and publishesXISOSharp.<version>.nupkg+.snupkg(the library is the only NuGet package) to NuGet. -
release.ymlbuilds the six framework-dependent bundles (release_<version>_<rid>.zipforwin-x64,win-arm64,linux-x64,linux-arm64,MacOsX-x64,MacOsX-arm64) from the same tag, smoke-tests the native ones, generates an SPDX 2.2 SBOM and a build-provenance attestation, and attaches everything to the GitHub release. Its body is the version's section ofrelease-notes.md. WhenENABLE_WINDOWS_SIGNING/ENABLE_MACOS_SIGNINGare set, Windows bundles are Authenticode-signed and verified, macOS bundles are codesigned (and notarized when the notary secrets exist) before the smoke job and release upload.
release.yml also has a workflow_dispatch entry with a dry_run switch to
rehearse the bundle build + smoke tests without creating a release. The manual
publish-cli.ps1 / publish-gui.ps1 recipe in
AGENTS.md remains the offline fallback.
The reference-binary cross-checks (extract-xiso / xdvdfs / xboxkit oracles) early-return
when the gitignored References/ binaries are absent, so a green pipeline means the suite
passed — not necessarily that reference byte-compatibility was exercised. Run the battle
harness locally with the oracles installed for that guarantee (see
Testing).
See also: Testing · Contributing · Troubleshooting
-
User Guide
-
Library API
-
Development