-
Notifications
You must be signed in to change notification settings - Fork 1
Contributing
How the Windows repository is laid out, how to build and run it on your own machine, and what a good pull request or bug report looks like. If you are only filing a bug, skip to Reporting a bug.
The tree is not a conventional src/-only solution. The command-line tool's sources sit at the
repository root, and only the shared library and the GUI live under src/.
| Path | What it is |
|---|---|
Program.cs, Logger.cs, StatusManager.cs, ReportManager.cs, DialogManager.cs, ManifestParser.cs
|
The command-line tool. BootstrapMate.csproj builds these into managedbootstrapinstall.exe
|
BootstrapMate.csproj |
The command-line project. It explicitly excludes src/** from compilation and consumes Core through a ProjectReference
|
src/BootstrapMate.Core/ |
The shared library: ConfigManager.cs, ManagementDetector.cs, SignatureVerifier.cs, BootstrapMateConfig.cs, BootstrapMateConstants.cs
|
src/BootstrapMate.App/ |
The GUI, in Views/, ViewModels/, Converters/ and Assets/. Builds BootstrapMate.exe
|
installer/ |
Product.wxs, the WiX project, and Generate-GuiAppFiles.ps1, which generates the GUI's ComponentGroup |
resources/ |
The ADMX and ADML policy templates |
examples/ |
Example manifests and Intune detection scripts |
build.ps1 |
The full local build: publish, sign, MSI, .intunewin
|
.github/workflows/ |
ci.yml (compile gate on push and PR to main) and release.yml (tag-triggered) |
BootstrapMate.sln contains all three projects.
The GUI is WinUI 3, on the Windows App SDK, targeting net10.0-windows10.0.19041.0. It is not
WPF — the command-line project sets UseWPF to false explicitly. The GUI does not share an
in-process execution engine with the command-line tool: it shells out to
managedbootstrapinstall.exe elevated and tails the log file for output. A change to how a package
is installed belongs in the command-line sources at the root, not in src/BootstrapMate.App.
Note that the README's "Project Structure" section lists BootstrapMate.Service,
BootstrapMate.CLI, BootstrapMate.Common and BootstrapMate.Tests, and describes BootstrapMate
installing itself as a Windows Service. None of those directories exist, there is no Windows Service
anywhere in the code, and there are no unit tests. Use the table above, not the README, when you are
looking for where something lives.
You need the .NET 10 SDK. See Building and Signing for the full picture, including signing and the MSI.
For an iteration loop, build the command-line tool alone, unsigned:
.\build.ps1 -AllowUnsigned -Architecture x64 -SkipMSIOr go straight through dotnet and skip the build script entirely:
dotnet publish BootstrapMate.csproj --configuration Release --runtime win-x64 --output publish\executables\x64 --self-contained trueRun the result from an elevated prompt. app.manifest requests requireAdministrator, and an
unelevated --silent run refuses to raise a UAC prompt and exits 1.
.\publish\executables\x64\managedbootstrapinstall.exe --url https://example.com/bootstrap.json --verboseTo exercise the GUI:
dotnet publish src\BootstrapMate.App\BootstrapMate.App.csproj --configuration Release --runtime win-x64 --output publish\app\x64 --self-contained trueThe GUI looks for the command-line executable in C:\Program Files\BootstrapMate\, then alongside
itself, then in ..\..\executables\<arch>\, so a build laid out under publish\ is found from a
development run.
Test against a manifest you control, on a machine you are willing to have modified. BootstrapMate
runs installers elevated and, on some paths, rewrites the machine PATH — see
Troubleshooting and Gotchas. A virtual machine with a snapshot is the
right environment.
.editorconfig is authoritative and is checked in at the repository root:
- UTF-8, CRLF line endings, final newline, trailing whitespace trimmed.
- Two-space indentation by default; four spaces for
.csand.ps1. - C# lines up to 120 characters.
Beyond that, follow what the tree already does:
- Nullable reference types are enabled on the command-line project; keep new code null-annotated.
-
LangVersionislatest. - Warnings are not errors, but do not add new ones.
- The command-line tool logs through the static
Logger, not through the Serilog orMicrosoft.Extensions.Loggingpackages the project references but does not use. Match the existing marker vocabulary —[SECTION],[PROGRESS],[SUB-PROGRESS],[SUCCESS],[SKIPPED],[COMPLETION],[OUTPUT]— because both GUI log viewers parse those markers. - NuGet restores from nuget.org only.
nuget.configclears every other source; do not add one. - Anything that both the GUI and the command-line tool need goes in
src/BootstrapMate.Core.
main is the trunk. Work on a branch and open a pull request against main; CI runs on every push
and pull request to main and must pass. CI publishes both projects and builds the MSI for x64
and arm64 — it runs no tests, so a green CI means the code compiles and packages, nothing more.
Say in the pull request how you verified the behaviour.
Write the commit subject as an imperative sentence describing the behaviour change, the way the
recent history does: Scope the policy Authorization header to the manifest host, Expire session
logs older than the retention window. Older commits use feat: and fix: prefixes; new ones do
not need them. Squash-merge titles carry the pull request number, so keep the subject readable on
its own.
If your change alters something an administrator would notice — a flag, a registry path, a default, a log line — update the corresponding wiki page in the same change, and add a line to Release Notes when it ships.
Releases are cut by pushing a vYYYY.MM.DD.HHMM tag. Do not push tags as part of a pull request.
Open an issue on the repository. A report that can be acted on without a round trip contains all four of the following.
The version string. Either run the tool, or read it off the top of a log:
& "C:\Program Files\BootstrapMate\managedbootstrapinstall.exe" --versionThe log excerpt. Each run writes a session directory,
C:\ProgramData\ManagedBootstrap\logs\<yyyy-MM-dd>\<HHmmss>\, holding bootstrap.log,
events.jsonl and session.json. Attach the newest directory, or at least bootstrap.log's
session header block that follows === BootstrapMate Session Started === — it records the
version, process ID, user, both architectures and the full command line — plus every line around
the failure. Day directories older than 30 days are pruned and only the newest 100 sessions are
kept, so collect promptly.
Get-ChildItem C:\ProgramData\ManagedBootstrap\logs -Filter *.log -Recurse | Sort-Object LastWriteTime -Descending | Select-Object -First 1If the failure was in a .pkg or .nupkg install, re-run with --verbose. Some installer output
is only written at Debug level.
The status registry values. Read them from the path StatusManager actually writes, not the one
--status prints:
Get-ItemProperty 'HKLM:\SOFTWARE\Cimian\BootstrapMate\Status\SetupAssistant'
Get-ItemProperty 'HKLM:\SOFTWARE\Cimian\BootstrapMate\Status\Userland'
Get-ItemProperty 'HKLM:\SOFTWARE\Cimian\BootstrapMate' -Name LastRunVersionThe effective configuration. Redact any AuthorizationHeader value before you paste it.
Get-ItemProperty 'HKLM:\SOFTWARE\Policies\BootstrapMate'
Get-ItemProperty 'HKLM:\SOFTWARE\BootstrapMate\Settings'
Get-ItemProperty 'HKCU:\SOFTWARE\BootstrapMate\Settings'Also say whether C:\ProgramData\ManagedBootstrap\cache is empty. Any file left there is a failed
install, kept deliberately for inspection.
Two things to check before filing, because they are known and documented rather than bugs: an exit code of 0 does not mean every package installed, since per-package failures are caught and the run continues; and several configurable settings are inert in the command-line tool. Both are covered on Troubleshooting and Gotchas. Redact hostnames, serial numbers and credentials from anything you attach — issues are public.