-
Notifications
You must be signed in to change notification settings - Fork 3
building and packaging
Every release ships six zip packages - one per supported runtime identifier:
release_<version>_<rid>.zip
3.1.0 win-x64 | win-arm64 | linux-x64 | linux-arm64 | osx-x64 | osx-arm64
| Package | Contents |
|---|---|
._win-x64.zip |
SimpleZipDrive.exe, 7za.exe, 7zip-license.txt, winfsp-msil.dll, Avalonia native libraries (libSkiaSharp.dll, libHarfBuzzSharp.dll, av_libglesv2.dll), ReadMe.md, LICENSE.txt, WhatsNew.md
|
._win-arm64.zip |
same layout (ARM64 7za.exe) |
._linux-x64.zip / ._linux-arm64.zip
|
SimpleZipDrive (apphost), 7zzs, 7zip-license.txt, libSkiaSharp.so, libHarfBuzzSharp.so, docs |
._osx-x64.zip / ._osx-arm64.zip
|
SimpleZipDrive, universal 7zz, 7zip-license.txt, libSkiaSharp.dylib, libHarfBuzzSharp.dylib, docs |
All are framework-dependent single-file executables: the .NET 10 runtime and the filesystem driver (WinFsp/Dokan on Windows, libfuse3/macFUSE on Linux/macOS) are the only prerequisites.
Three workflows live in .github/workflows:
| Workflow | Trigger | What it does |
|---|---|---|
ci.yml |
Every push/PR to master
|
Builds and tests the solution on Windows and compiles the app on Ubuntu and macOS |
release.yml |
workflow_dispatch (version input) or a release_* tag push |
Verifies the csproj version matches, builds + tests on Windows, publishes and packages the six bundles on Windows/Linux/macOS runners, uploads them as release-bundles-* artifacts, then waits for approval in the protected release environment before creating/updating the GitHub release |
wiki-sync.yml |
Push to master touching docs/** (or manually) |
Mirrors docs/*.md into the repository wiki (index.md → Home.md) |
- Run Release from the Actions tab (or push a
release_x.y.ztag). - When the Build bundles jobs finish, download the release-bundles-* artifacts from the run summary - the six
release_<version>_<rid>.zipfiles. The run summary lists sizes and SHA256 checksums, and nothing is public yet. - Inspect the zips and smoke-test at least one packaged executable per OS.
- Approve the waiting Publish release job in the
releaseenvironment (Settings → Environments →release→ required reviewer). The workflow then creates the GitHub release with the six bundles attached and the matchingWhatsNew.mdsection as the release notes.
If the bundles are wrong, do not approve: cancel the run, fix, and re-run.
First-time setup: the
releaseenvironment needs at least one required reviewer, and the wiki sync needs aWIKI_TOKENrepository secret (a PAT with repository access -GITHUB_TOKENcannot push to the wiki repository). Both are already configured for this repository.
scripts/package-release.ps1 performs the same publish/package steps locally:
# All targets for the current OS (other OSes are skipped on Windows, see below)
.\scripts\package-release.ps1 -Version 3.1.0
# Only the targets for one OS
.\scripts\package-release.ps1 -Version 3.1.0 -RuntimeIdentifiers win-x64,win-arm64It runs the test suite first (pass -SkipTests to skip), publishes the requested runtime identifiers, and writes the bundles into SimpleZipDrive\bin\Release next to the historical releases. Existing files in that folder are never deleted; only the bundles for the requested version are written (or overwritten). On Linux/macOS the script uses the zip CLI so the apphost and the 7-Zip binary keep their executable bit; on a Windows host, Linux/macOS runtime identifiers are skipped with a warning because Compress-Archive cannot record Unix permissions. Build those bundles on their own OS (as the release workflow does) - a Windows developer asking for all six targets gets the two Windows bundles plus a clear warning.
Important: the
.csprojcontains<SelfContained>true</SelfContained>, but releases are built framework-dependent - the publish command must override it with--self-contained false. Publishing without the override produces huge self-contained bundles that also break the packaging assumptions documented below.
dotnet publish SimpleZipDrive\SimpleZipDrive.csproj -c Release -r win-x64 --self-contained false -o out\win-x64
dotnet publish SimpleZipDrive\SimpleZipDrive.csproj -c Release -r win-arm64 --self-contained false -o out\win-arm64
dotnet publish SimpleZipDrive\SimpleZipDrive.csproj -c Release -r linux-x64 --self-contained false -o out\linux-x64
dotnet publish SimpleZipDrive\SimpleZipDrive.csproj -c Release -r linux-arm64 --self-contained false -o out\linux-arm64
dotnet publish SimpleZipDrive\SimpleZipDrive.csproj -c Release -r osx-x64 --self-contained false -o out\osx-x64
dotnet publish SimpleZipDrive\SimpleZipDrive.csproj -c Release -r osx-arm64 --self-contained false -o out\osx-arm64When packaging by hand, include the single-file executable, every file in the publish root except PDBs, and ReadMe.md/LICENSE.txt/WhatsNew.md. The support files in the publish root (the platform 7-Zip binary and its 7zip-license.txt, Avalonia's Skia/HarfBuzz/ANGLE libraries, and on Windows winfsp-msil.dll) must ship loose beside the executable.
Three constraints make the file layout non-negotiable:
-
winfsp-msil.dllmust stay a real file beside the exe. Its static initializer (Fsp.Interop.Api.CheckVersion) callsFileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);Assembly.Locationis an empty string inside a single-file bundle, soPath.GetFullPath("")throws and every WinFsp mount dies with "The path is empty (Parameter 'path')" before the driver is ever contacted. The csproj contains a target that runs before the bundler computes its file list:<Target Name="KeepWinFspInteropOutOfBundle" BeforeTargets="_ComputeFilesToBundle"> <ItemGroup> <ResolvedFileToPublish Update="@(ResolvedFileToPublish)" Condition="'%(ResolvedFileToPublish.Filename)%(ResolvedFileToPublish.Extension)' == 'winfsp-msil.dll'" ExcludeFromSingleFile="true" /> </ItemGroup> </Target>
Timing matters:
AfterTargets="ComputeFilesToPublish"/BeforeTargets="BundleFiles"do not work - the SDK splits bundled/non-bundled files in_ComputeFilesToBundle. -
The 7-Zip fallback binary must stay a real file beside the exe on every platform.
SevenZipFallbackprobesAppContext.BaseDirectoryfor7za.exe(Windows),7zzs(Linux) or7zz(macOS); the csproj copies exactly the file matching the publishRuntimeIdentifierand links it under its canonical name. Bundling it into the single file would make the fallback silently unavailable. On Unix the app sets the executable bit at runtime, and the release bundles preserve the bit through thezipCLI. The Unix binaries are committed with mode100755(git update-index --chmod=+x) so a publish from Linux/macOS keeps them executable.7zip-license.txtmust ship beside them: it contains the Windows (7za.exe) and Linux/macOS (7zz,7zzs) license texts, since the Windows and Unix packages carry different notices. -
winfsp.net stays at 2.1.x (
2.1.25156). Interop 2.2.x rejects the stable native 2.1 driver ("incorrect dll version (need 2.2, have 2.1)"); interop 2.1 accepts both the 2.1 stable driver and 2.2+ betas. Version gates live inWinFspMountService(RequiredWinFspVersion = 2.1).
- Bump
<AssemblyVersion>/<FileVersion>to the new version inSimpleZipDrive.csprojandSimpleZipDrive.Tests.csproj(there is no explicit<Version>property;AssemblyVersiondrives the published version). - Update
WhatsNew.md(user-facing Added/Fixed/Changed/Internal sections) - the matching## <version>section becomes the GitHub release notes automatically. - Push to
master- the CI workflow must be green. - Run Release from the Actions tab with the version, or push a
release_<version>tag. The workflow verifies the csproj version, runs the tests again, and builds the six bundles. - Download the release-bundles-* artifacts and review the zips before approving - the run summary lists sizes and SHA256 checksums.
- Smoke-test a downloaded bundle on each OS: mount a stored ZIP, a compressed archive, a
.zarcontainer, and an Xbox.iso/.csoimage through the packaged executable (both a drive letter and a folder; elevated and non-elevated for WinFsp; a folder mount on Linux/macOS). - Approve the Publish release job in the
releaseenvironment. The workflow creates the GitHub release with the six bundles attached (full release - not draft/prerelease). - Inform issue reporters whose bugs the release fixes.
Bundles can also be produced locally with scripts/package-release.ps1 -Version <version> and uploaded by hand with gh release create release_<version> --title "<version>" --notes-file . *.zip, but the Actions path is the supported one.
Deep Dives
Operations
Development
Resources