Skip to content

Setup experience for Windows. - #44306

Merged
getvictor merged 62 commits into
mainfrom
victor/43859-orbit-setup-experience-windows
May 6, 2026
Merged

Setup experience for Windows.#44306
getvictor merged 62 commits into
mainfrom
victor/43859-orbit-setup-experience-windows

Conversation

@getvictor

@getvictor getvictor commented Apr 28, 2026

Copy link
Copy Markdown
Member

Related issue: Resolves #43859

This PR brings the Windows Autopilot setup experience to parity with macOS DEP. Windows hosts that enroll
through Autopilot now coordinate with Fleet during the OOBE Enrollment Status Page (ESP), so admin-defined
software installs run while the device is still waiting at the ESP screen, before the user can sign in. Fleet
holds the device on the ESP until profiles and setup-experience software all reach a terminal state, then
either releases the device to login or blocks it on a Reset PC failure screen. A new team-level setting
controls the policy: when enabled, any critical software install failure during ESP blocks the device with a
software-specific error message; when disabled, the device releases regardless of install outcomes (best
effort). A pure 3-hour timeout also forces a finalize, with a timeout-specific error message on the block
screen. The setting is premium-only and rejected when Windows MDM is not configured.

Beyond the gating itself, the PR adds the supporting machinery: orbit-driven setup-experience initialization
on Windows so installs are enqueued at the right moment, defense-in-depth cancellation of pending software
installs (both queue rows and status rows) whenever the device is going to block or time out, idempotent
re-enrollment cleanup so a device that resets and re-enrolls during ESP starts from a clean state. Internally, finalize is structured so a transient failure at any step (cancel, persist, or the state-machine transition) leaves the device retriable on the next management session rather than permanently stuck on "Working on it...". The behavior is exercised by example-based tests, a property-based test that randomly samples the wait/block/release decision matrix, and manual VM testing across Autopilot edge cases.

image

Checklist for submitter

  • Timeouts are implemented and retries are limited to avoid infinite loops

Testing

  • Added/updated automated tests
  • QA'd all new/changed functionality manually

Summary by CodeRabbit

  • Bug Fixes

    • Re-enrollment now clears stale setup-experience results and pending activities so devices aren’t blocked by old work.
    • Insert operations tolerate missing enrollments and return clear not-found behavior.
  • New Features

    • ESP finalization waits for software installation results and can block or release based on configurable “require all” behavior; blocking cancels pending steps and shows prioritized error text.
    • Finalization persists batched final commands for consistent retries.
    • Orbit config exposes setup-experience notification for pending/active Windows hosts.
  • Tests

    • Expanded coverage for ESP flows, datastore awaiting-configuration, Orbit config, and re-enrollment cascades.

@getvictor
getvictor requested a review from Copilot May 1, 2026 19:29
@getvictor

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@getvictor

Copy link
Copy Markdown
Member Author

/agentic_review

@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Full review triggered.

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented May 1, 2026

Copy link
Copy Markdown

Persistent review updated to latest commit cd3836f

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/service/microsoft_mdm.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@server/service/microsoft_mdm_property_test.go`:
- Around line 170-176: The timeout branch currently returns pbtESPRelease when
timedOut and requireAll is false, but per the spec a 3-hour ESP timeout must
always produce the timeout/failure UI; update the timedOut branch in the test
(where variables timedOut, requireAll are used) to always return pbtESPBlock and
false regardless of requireAll so the property encodes a blocking timeout path
(ensure the branch that reads pbtESPBlock/pbtESPRelease is the one updated).

In `@server/service/microsoft_mdm_test.go`:
- Around line 1675-1686: The test currently fails before hitting loadRequireAll
because HostLiteByIdentifierFunc returns an error causing
setupExperienceHostUUID() to return early; change the test to have
ds.HostLiteByIdentifierFunc return a valid *fleet.HostLite (so
setupExperienceHostUUID proceeds) and instead make the AppConfig/TeamLite lookup
fail (e.g., set ds.AppConfigByTeamIDFunc or ds.TeamLiteByIDFunc to return an
error) so getESPCommands(t.Context(), newActiveDevice()) exercises
loadRequireAll() and still returns an error and does not set
SetMDMWindowsAwaitingConfigurationFuncInvoked.

In `@server/service/microsoft_mdm.go`:
- Around line 2105-2115: The loadHost closure caches a nil host and sets
hostLoaded, which lets callers like setupExperienceHostUUID() and
loadRequireAll() dereference cachedHost and panic; change loadHost (the function
using svc.ds.HostLiteByIdentifier) to treat a nil result as an error by
returning a wrapped error when host == nil, and only set cachedHost and
hostLoaded after verifying host != nil so callers cannot receive a nil
cachedHost.
- Around line 2288-2307: The current logic computes shouldBlock := failed &&
requireAll which allows a pure timeout (timedOut == true, requireAll == false)
to go down the release path; change the condition so timeouts always block by
setting shouldBlock to true when timedOut is true (e.g., shouldBlock := timedOut
|| (failed && requireAll)); update the block so buildESPBlockCommands(provID,
errorText) is used for timedOut cases as well and
buildESPReleaseCommands(provID) is only used when neither timedOut nor a
failing-required-software condition applies.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 684a01bb-1eb4-4807-a074-69d1d3be3ee2

📥 Commits

Reviewing files that changed from the base of the PR and between f94b66f and cd3836f.

📒 Files selected for processing (12)
  • cmd/fleetctl/fleetctl/apply_test.go
  • server/datastore/mysql/microsoft_mdm.go
  • server/datastore/mysql/microsoft_mdm_test.go
  • server/fleet/datastore.go
  • server/mdm/microsoft/esp_csp.go
  • server/mock/datastore_mock.go
  • server/service/microsoft_mdm.go
  • server/service/microsoft_mdm_property_test.go
  • server/service/microsoft_mdm_test.go
  • server/service/orbit.go
  • server/service/orbit_test.go
  • server/service/setup_experience_test.go

Comment thread server/service/microsoft_mdm_property_test.go
Comment thread server/service/microsoft_mdm_test.go
Comment thread server/service/microsoft_mdm.go
Comment thread server/service/microsoft_mdm.go
Comment thread server/service/microsoft_mdm.go
@getvictor
getvictor marked this pull request as ready for review May 1, 2026 20:04
@getvictor
getvictor requested a review from a team as a code owner May 1, 2026 20:04

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@getvictor

Copy link
Copy Markdown
Member Author

Comment thread server/datastore/mysql/microsoft_mdm.go
Comment thread server/datastore/mysql/setup_experience.go Outdated
@getvictor
getvictor requested a review from ksykulev May 6, 2026 13:38
@getvictor

Copy link
Copy Markdown
Member Author

@ksykulev ready for re-review

@getvictor
getvictor merged commit d38163d into main May 6, 2026
59 checks passed
@getvictor
getvictor deleted the victor/43859-orbit-setup-experience-windows branch May 6, 2026 19:27
@coderabbitai coderabbitai Bot mentioned this pull request Jun 1, 2026
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants