Developer documentation for maintaining and building System-Setup.
.github/workflows/build-release.yml <-- CI/CD: auto-builds Setup.exe on push
Windows/
Setup.cmd <-- Entry point (source users)
Setup.ps1 <-- Main orchestrator
Setup-UI.ps1 <-- GUI (Windows Forms)
restore.ps1 <-- Parallel winget installer
Enable-WindowsFeatures.ps1
bootstrap-dev.sh <-- Shell + dev setup (Git Bash)
Build-Exe.ps1 <-- Compiles Setup.exe
Sign-Scripts.ps1 <-- Optional code signing
winget-packages.json <-- Package manifest
vscode-extensions.txt <-- VS Code extensions
zshrc-template <-- .zshrc for Powerlevel10k
p10k-template <-- Powerlevel10k config
zsh-gitbash.tar.gz <-- Bundled zsh binaries (~2 MB)
README.md <-- Technical reference
Every push to main triggers .github/workflows/build-release.yml:
- Checks out code on a
windows-latestrunner - Installs
ps2exemodule - Runs
Build-Exe.ps1to producedist/Setup.exe - Creates a GitHub Release with auto-incremented version tag (
v1.0.N) - Attaches
Setup.exeto the release
The release marked latest is always the most recent build. The download link in README always points to the latest.
No manual steps needed. Push to main = new release.
cd Windows
.\Setup.cmd # interactive with GUI
.\Setup.cmd -Unattended # install everything, no GUI
.\Setup.cmd -SkipPhase2 # only winget packages
.\Setup.cmd -SkipPhase1 # only shell/dev setup
.\Setup.cmd -Throttle 8 # faster parallel installscd Windows
Install-Module ps2exe -Scope CurrentUser # one-time
.\Build-Exe.ps1
# Output: ..\dist\Setup.exe (~3 MB).\Setup-UI.ps1Edit winget-packages.json. Each entry:
{ "PackageIdentifier": "Publisher.AppName" }Find IDs: winget search <name> or winget.run
The GUI (Setup-UI.ps1) has its own package list -- update both files when adding.
To snapshot your current installed apps:
winget export -o winget-packages.json --accept-source-agreementsEdit vscode-extensions.txt (one extension ID per line).
To snapshot current extensions:
code --list-extensions > vscode-extensions.txtcd "/c/Program Files/Git"
tar czf /path/to/Windows/zsh-gitbash.tar.gz \
usr/bin/zsh.exe usr/bin/zsh-5.9.exe usr/bin/msys-zsh-5.9.dll \
usr/share/zsh etc/zsh usr/lib/zsh| Constraint | Why |
|---|---|
| All .ps1 files must be pure ASCII | PowerShell 5.1 without BOM chokes on Unicode |
Use $(if (...) {...} else {...}) not if (...) {...} else {...} in expressions |
Ternary if is PS7-only |
Don't use $input as a variable name |
Reserved automatic variable |
Use @() around pipeline results assigned to arrays |
PS collapses single-element arrays to scalars |
winget settings --enable InstallerHashOverride before --ignore-security-hash |
Required on winget 1.28+ |
dist/ is in .gitignore |
Exe goes to Releases via CI, not in the repo |
See Windows/README.md for architecture, environment variables, feature flags, and profile details.