Skip to content

feat(windows): add native MSI installer (WPB-5221) - #9722

Draft
adamlow-wire wants to merge 8 commits into
devfrom
feature/WPB-5221-windows-native-msi
Draft

feat(windows): add native MSI installer (WPB-5221)#9722
adamlow-wire wants to merge 8 commits into
devfrom
feature/WPB-5221-windows-native-msi

Conversation

@adamlow-wire

@adamlow-wire adamlow-wire commented Aug 18, 2026

Copy link
Copy Markdown
EpicWPB-5221 [Desktop] Windows installer

Summary

Adds a native, per-machine Windows MSI installer for enterprise deployment through MDM and software-management systems.

The existing Squirrel EXE path remains available. MSI installations deliberately do not run the application-managed Squirrel updater; enterprises update them by deploying a newer MSI with the same permanent upgrade code.

Jira: WPB-5221

What changed

  • adds an electron-builder MSI build target with stable product-family upgrade codes
  • installs per-machine under Program Files and supports quiet msiexec deployment
  • preserves desktop and Start menu shortcuts plus the wire: protocol registration
  • adds branded installer UI and an embedded Wire banner
  • prevents the Squirrel updater from starting when an MSI installation has no Update.exe
  • signs and verifies the versioned MSI in the Windows release pipeline
  • deploys the version-matched MSI artifact to S3
  • documents MDM deployment, upgrades, detection, migration risks, and release acceptance criteria

Validation

  • build/deployment unit tests: 23 passing
  • updater compatibility tests: 2 passing
  • TypeScript type checks and test compilation pass
  • ESLint, Prettier, Groovy syntax, and git diff --check pass
  • native x64 MSI builds successfully
  • MSI tables inspected for per-machine scope, identity, upgrades, shortcuts, protocol registration, launch condition, and branding
  • quiet administrative extraction with msiexec /a ... /qn succeeds

Release checks still required

  • production certificate signing and timestamp verification in Windows CI
  • ICE/WiX validation on the signed release artifact
  • fresh install, repair, uninstall, and N-to-N+1 upgrade as SYSTEM on supported Windows versions
  • migration testing with an existing per-user Squirrel installation
  • validation in the target MDM tenant, including detection and rollback
  • update the external Windows smoke-test job and download-page consumer before MSI promotion

Security

  • no new network endpoints, credentials, or privilege-escalation mechanism
  • installer scope is intentionally per-machine and therefore requires administrative deployment authority
  • production signing is configured to use SHA-256, timestamping, fail-fast signing, and verification of all signatures

Comment thread bin/build-tools/lib/build-windows-msi.ts Outdated
Comment thread jenkins/windows.groovy Outdated
Comment thread bin/build-tools/lib/build-windows-msi.ts
Comment thread jenkins/deployment.groovy
// Windows-specific stage: Update RELEASES file for Squirrel auto-updates
// ------------------------------------------------------------------------
if (projectName.contains('Windows')) {
if (projectName.contains('Windows') && !isWindowsMsi) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isWindowsMsi is no longer defined (hasWindowsMsi and hasWindowsSquirrel are now used above) so this should fail when the Jenkins deployment reaches this stage. Since a build can now intentionally contain both installer families I think this should be based on hasWindowsSquirrel so we still update the Squirrel RELEASES feed whenever those artifacts are present.

Comment thread jenkins/deployment.groovy

if (params.Release == 'Production') {
env.S3_PATH = 'win/prod'
env.MSI_S3_PATH = 'win/msi/prod'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MSI is uploaded to MSI_S3_PATH here, but the later Generate & Store Presigned URLs stage iterates all wrap/dist artifacts and always generates URLs using env.S3_PATH. That means the MSI URL will point to win/prod/... instead of win/msi/prod/...

Can we select the S3 path based on the artifact there?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants