Build Pipeline
BuildPipeline turns a .bsetup project into a self-contained Setup.exe with an embedded payload.
Stages
- Validate — product name, version, components; abort on errors.
- Provision self-update —
StampUpdateSettingswritesupdate-settings.json(fromAppUpdatesURL/AppUpdateMode) as a payload file, when a feed URL is authored. - Stage payload — copy component files (or scan the source) into
payload/. - Write runtime script +
install-config.jsonbeside it. - Build the host EXE — behind
IInstallerHostBuilder(real impl runsdotnet publish; tests inject a stub). Uncompressed single-file, so the payload can be appended after the PE. - Embed the icon (Win32
UpdateResource). - Compress payload →
payload.zip(optionally solid/deduplicated — see below). - Embed payload into the EXE (appended with a marker footer).
- Sign (optional) and/or package MSIX (Track C).
The solid (content-addressed) payload
With solid compression, identical file contents are stored once under _blobs/<sha256> and a _payload-manifest.json maps each path to its blob. This is the same content-addressed store a delta update diffs against — the hard part of delta updates already exists in the build output.
// _payload-manifest.json
{ "solid": true, "entries": [
{ "path": "MyApp.exe", "blob": "A1B2…", "size": 20480 },
{ "path": "docs/readme.txt", "blob": "C3D4…", "size": 512 }
] }
Testable seams
- Host production is behind
IInstallerHostBuilder, so the pipeline (staging, compression, embedding, cleanup) is exercised in tests without a multi-minute publish. PublishTimeout(default 10 min),ReadyToRun(off by default — it costs far more build time than it returns for a run-once installer), andKeepIntermediatesare configurable.- Signing that silently did nothing, and compression options that were collected then ignored, are wired for real — a configured certificate really signs, and a failure is an error.
Headless build
Beep.Installer.exe /BUILD=MyApp.bsetup /OUT=out # Track A Setup.exe
Beep.Installer.exe /BUILD=MyApp.bsetup /FORMAT=msix # Track C .msix
Beep.Installer.exe /VALIDATE=MyApp.bsetup # gate in CI
Beep.Installer.exe /BUILD=MyApp.bsetup /REQUIRESIGNED # refuse unsigned