Skip to content

Publish Pipeline

Taiizor edited this page Jun 19, 2026 · 4 revisions

Publish Pipeline

The production publish/packaging script is .build/Sucrose.ps1. It publishes ~18 projects, optionally installs and trims a private .NET runtime, optionally compresses the result into Sucrose-<arch>.7z, and produces exactly the archive that the Bundle Installer Internals embeds. This page documents the script's parameters and defaults, the projects it publishes, the per-project publish command, the CefSharp special-casing, the trimmed private runtime, the 7-Zip compression, and the order in which everything must run. The script requires PowerShell 7+; its own docs live at .build/README.md.

Contents

Where this fits in the build

flowchart LR
    Script[".build/Sucrose.ps1"] --> Pub["publish 18 projects<br/>dotnet publish per project"]
    Pub --> RT["install + trim<br/>Sucrose.Runtime"]
    RT --> Zip["compress to Sucrose-&lt;arch&gt;.7z<br/>(7-Zip lzma2)"]
    Zip --> Bundle["Sucrose.Bundle build<br/>(Costura embeds the .7z)"]
    Bundle --> Exe["Sucrose_Bundle_..._&lt;arch&gt;_&lt;version&gt;.exe"]
    Exe --> Upload["GitHub / SourceForge / Soferity<br/>+ update package manifests"]
Loading

dotnet build (see Building From Source) compiles the code, but the publish pipeline is what produces a shippable layout: per-project published output, the private runtime, and the compressed payload. The Bundle installer cannot be built until this script has produced the .7z.

Parameters and defaults

Param Values Default Notes
Configuration Release / Debug / "" env Configuration or Release
PlatformTarget x64 / x86 / ARM64 / "" env Platform or x64
SelfContained true / false false
RuntimeIdentifier win-x64 / win-x86 / win-arm64 / "" derived from PlatformTarget
TargetFramework string auto-detected from first project (net10.0-windows)
PublishDir string ..\src\Sucrose\Package
PublishBaseDir string script dir (.build)
MaxAttempts 1–10 3 retry per project
RetryDelay 1–60 2 seconds (README table says 2; the .DESCRIPTION/help text says 3 — actual default in code is 2)
InstallRuntime true / false true bundle the trimmed private .NET runtime
CompressPackage true / false true produce the .7z
DotNetVersion string 10.0.109 .NET SDK version to install (provides the .NET runtime 10.0.9)

Usage examples

powershell -File .build/Sucrose.ps1
powershell -File .build/Sucrose.ps1 -Configuration Debug -PlatformTarget x86
powershell -File .build/Sucrose.ps1 -SelfContained "true" -CompressPackage "false"
.\.build\Sucrose.ps1 -PlatformTarget ARM64 -SelfContained true   # self-contained ARM64

Projects published (18)

The script publishes these 18 projects (in $script:Projects):

  • Sucrose.Launcher
  • Live engines: Aurora, CefSharp, MpvPlayer, VlcPlayer, Nebula, Vexana, WebView, Xavier
  • Sucrose.Localizer
  • Sucrose.Portal
  • Services: Backgroundog, Commandog, Property, Reportdog, Undo, Watchdog
  • Sucrose.Update

Note that Sucrose.Localizer is published here, but it is excluded from the compressed app payload (see Compression).

Per-project publish

Each project is published into its own folder and the script retries on failure:

  • Output dir: <PublishDir>\<TargetFramework>\<PlatformTarget>\<ProjectName> (cleaned, then recreated).

  • Command:

    dotnet publish <proj> -c <Config> /p:PlatformTarget=<plat> -r <rid> -f <tfm> --self-contained <bool> -o <dest> --nologo --use-current-runtime --verbosity minimal
  • Each output dir gets a Publish.log. Publishing retries up to MaxAttempts with RetryDelay seconds between attempts.

CefSharp subprocess special-casing

After publishing Sucrose.Live.CefSharp, the function Configure-CefSharpSubprocess writes a custom CefSharp.BrowserSubprocess.runtimeconfig.json so the CefSharp subprocess uses the bundled private runtime rather than a machine-wide one:

  • tfm = net10.0, rollForward = LatestMajor, framework Microsoft.NETCore.App v10.0.0
  • additionalProbingPaths = ../Sucrose.Runtime/shared/Microsoft.NETCore.App/10.0.0
  • configProperties: DOTNET_ROOT = ../Sucrose.Runtime, DOTNET_MULTILEVEL_LOOKUP = 0
  • (The version is clamped to the net6.0..net10.0 range.)

This is what lets the CefSharp browser subprocess resolve the same trimmed runtime as the rest of the app. See Engine CefSharp for the engine itself.

The trimmed private runtime

When InstallRuntime=true (the default), Install-DotNetRuntime:

  • Runs .build/dotnet-install.ps1 -Version 10.0.109 -NoPath -Architecture <plat> -InstallDir <...\Sucrose.Runtime>.
  • Output: <PublishDir>\<tfm>\<plat>\Sucrose.Runtime.

Remove-UnnecessaryRuntimeFiles then trims that runtime:

  • Deletes files: dnx.cmd, dnx.ps1, dotnet.exe, LICENSE.txt, ThirdPartyNotices.txt.
  • Deletes dirs: templates, sdk-manifests, sdk, packs, shared\Microsoft.AspNetCore.App.
  • Leaves shared\Microsoft.NETCore.App (and Microsoft.WindowsDesktop.App, which the WPF apps need; only AspNetCore is removed).

This Sucrose.Runtime folder is the private runtime the apps probe at run time (e.g. Sucrose.Update.csproj sets AppHostDotNetSearch=AppRelative, AppHostDotnetRoot=..\Sucrose.Runtime). The net effect: end users do not need a system-wide .NET 10 install. Passing -SelfContained true produces a fully standalone publish that does not rely on Sucrose.Runtime.

Compression

When CompressPackage=true (the default), Compress-SucrosePackage:

  • Picks the host-architecture 7z.exe from src/Bundle/Sucrose.Bundle/SevenZip/7z-<sysarch>/7z.exe.

  • Output: <PublishDir>\Compressed\<tfm>\Sucrose-<plat>.7z.

  • Source: <PublishDir>\<tfm>\<plat>\*.

  • 7z args:

    a -t7z -m0=lzma2 -mx=9 -mfb=64 -ms=64m <archive> <src>\* -xr!Sucrose.Bundle -xr!Sucrose.Localizer
    

The -xr!Sucrose.Bundle -xr!Sucrose.Localizer excludes mean those two folders are not shipped inside the app payload. The resulting Sucrose-<plat>.7z is exactly what Sucrose.Bundle.csproj embeds as the logical resource Packages\Sucrose.7z.

End-to-end build-and-ship order

  1. Run .build/Sucrose.ps1 -PlatformTarget <arch> → publishes the app, trims the runtime, and writes src/Sucrose/Package/Compressed/net10.0-windows/Sucrose-<arch>.7z.
  2. Build Sucrose.Bundle (src/Sucrose.Bundle.slnx) for the same <arch> → Costura.Fody merges dependencies and embeds the .7z, the 7-Zip binaries, the Checksum Hashes.json, and the Showcase → a single Sucrose.Bundle.exe in src/Sucrose/Bundle/<arch>.
  3. Rename/upload it as Sucrose_Bundle_.NET_Framework_4.8_<arch>_<version>.exe to GitHub Releases / SourceForge / Soferity, then update the package-manager manifests (.packages/...) with the new SHA256 hashes.

The order is mandatory: the Bundle build fails if step 1 has not produced the .7z, because it embeds that file. No CI automates steps 1–3 — they are manual/local.

Versioning

  • The app version is auto-derived from the build date: Version = yy.MM.dd (Directory.Build.props). Package manifests use yy.MM.dd.0.
  • FileVersion/AssemblyVersion/InformationalVersion all equal $(Version).
  • The Bundle reads its own version at run time via Skylark.Helper.Versionly.Auto(AssemblyType.Entry).

See also

Home

Getting Started

Wallpaper Types

Using Sucrose

Settings Reference

Creating Wallpapers

Engine Reference

Automation & Command Line

Architecture & Internals

Data, Files & Diagnostics

Building & Contributing

Help & Support

Clone this wiki locally