Fixes#45520
The Pub/Sub status-report and enrollment handlers dereferenced
device.HardwareInfo before any nil check, so a payload from Google's
Android Management API with hardwareInfo omitted panicked the request
goroutine.
Fixes#42874
Empty, whitespace-only, and missing `FLEET_JIT_USER_ROLE_*` SAML
attribute values are now treated as `null` (ignored) instead of
returning an error, matching the literal `"null"` workaround.
Add a list of form-based contact sources and set
Most_recent_campaign_member_status__c to 'Registered' when contactSource
matches any of them. This marks contacts originating from website
contact forms, webinars, gated docs, and related sources as registered.
The change includes an eslint-disable-line camelcase comment for the
Salesforce field name.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Enhanced contact registration tracking to automatically set
appropriate campaign status when contacts are registered through
form-based sources such as webinars.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45427)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Resolves#45220
Here's one example why this is a good idea.
On `main`, the fleet production binary contains a private key used for
testing:
```
$ strings ./build/fleet | rg "BEGIN RSA TESTING"
proto3-----BEGIN RSA TESTING KEY-----
```
And it's gone when using this branch:
```
$ strings ./build/fleet | rg "BEGIN RSA TESTING"
<empty>
```
## Testing
- [X] QA'd all new/changed functionality manually.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Reorganized and centralized SCEP test helpers and servers for
certificate enrollment tests.
* Added embedded HTML fixtures to better emulate SCEP/NDES admin
responses (cache/full, permissions, password).
* Standardized UTF‑16 handling for test responses and improved test
server response handling.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45619?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
- `pkg/patch_policy/GenerateQueryForManifest` now wraps the
caller-supplied exists query in an inner set of parentheses before
appending the trailing `AND version_compare(...) < 0` clause. Without
the wrap, any `OR` in the exists body binds *after* the appended `AND`
(SQL precedence: `AND` > `OR`), producing an incorrect `patched` query.
The bug is currently only observable on `codex-cli` (uses `path = ... OR
path LIKE ...`) but would silently break any future FMA whose exists
query contains `OR`.
- All FMA outputs regenerated via `cmd/maintained-apps`. For AND-only
exists queries (the vast majority of existing FMAs), the new patched SQL
is semantically identical to the previous form — just with extra parens
around the WHERE body. `codex-cli/windows.json`'s OR clause is now
correctly grouped.
- `docker-desktop` is unchanged: its patched SQL is constructed inline
in the homebrew ingester at
[ingester.go:198-201](https://github.com/fleetdm/fleet/blob/claude/compassionate-merkle-afbd8a/ee/maintained-apps/ingesters/homebrew/ingester.go#L198-L201)
and bypasses the generator.
### Heads-up: upstream version drift bundled in
The regeneration also pulled in a handful of upstream version bumps that
landed since the last FMA run. These are real upstream changes, not
generator artifacts:
| App | Platform | Old → New |
|---|---|---|
| Figma | windows | 126.3.12 → 126.4.9 |
| GoLand | darwin | 2026.1.1 → 2026.1.2 |
| IntelliJ IDEA | darwin | 2026.1.1 → 2026.1.2 |
| RubyMine | darwin | 2026.1.1 → 2026.1.2 |
| Zed | darwin | 1.2.5 → 1.2.6 |
If you'd prefer these isolated from the paren-only change, let me know
and I'll split the PR.
### Code changes
- [pkg/patch_policy/patch_policy.go](pkg/patch_policy/patch_policy.go):
added `(` to `templateStart` and `)` to `templateEnd{Darwin,Windows}` so
`GenerateQueryForManifest` emits `... NOT EXISTS ((<before>) AND
version_compare(...) < 0);`.
-
[pkg/patch_policy/patch_policy_test.go](pkg/patch_policy/patch_policy_test.go):
updated existing expectations and added an OR-precedence case mirroring
codex-cli's exists query.
-
[ee/maintained-apps/ingesters/homebrew/ingester_test.go](ee/maintained-apps/ingesters/homebrew/ingester_test.go):
updated the generic `Patched` assertion (docker-desktop's hardcoded
expectation is unchanged — it bypasses the generator).
- 282 regenerated files under `ee/maintained-apps/outputs/**/*.json`.
## Test plan
- [x] `go test ./pkg/patch_policy/...` passes (incl. new OR case).
- [x] `go test ./ee/maintained-apps/...` passes.
- [x] `go vet ./pkg/patch_policy/... ./ee/maintained-apps/...` clean.
- [x] `cmd/maintained-apps` runs end-to-end with no errors against the
live Homebrew/winget APIs (with `NETWORK_TEST_GITHUB_TOKEN` set).
- [x] `git diff` audited: every diffed `patched` line on
`outputs/**/*.json` is a paren-only delta; non-`patched` deltas confined
to the 5 upstream version bumps listed above.
- [x] `docker-desktop/darwin.json` unchanged after regeneration.
- [ ] CI green.
Changes:
- Moved the files for four pages (linux-management, basic-comparison,
deployment, and gitops-workshop) out of the landing pages folder.
- Added policies for the moved pages
- Updated the URLs for pages in the landing pages folder to be prefixed
with /lp/, and added redirects that preserve query strings when
redirecting users.
- Created a section in the routes configuration for landing pages
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Implemented /lp/* landing-page paths with 301 redirects from legacy
URLs (query strings preserved).
* Added public access exceptions so selected marketing pages are
reachable without login.
* **Refactor**
* Reorganized routing and page templates to move several pages out of
the previous landing-pages area into dedicated page paths.
* Updated included page scripts and style imports to match the
reorganized pages.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45632)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added comprehensive support for managing Codex CLI (OpenAI's coding
agent) on Windows systems, including automated installation,
uninstallation, and verification that installed binaries match expected
versions
* Integrated Codex CLI icon component into the software interface for
improved visual identification and enhanced user experience when
managing this application
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/42397)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#38785
- UI changes per Figma and latest product guidelines
- Do not cancel setup experience during BYOD (when critical software
install fails)
- Allow a host to rerun setup experience even if it has been in Fleet
for over 24 hours
- This fixes a bug where a host is wiped but not deleted from Fleet, and
then it doesn't run setup experience.
# Checklist for submitter
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Improved Windows re-enrollment detection to better handle BYOD
scenarios, preventing unintended cancellation of pending setup steps for
recently re-enrolled devices.
* Added a fallback lookup for unlinked Windows enrollments to improve
enrollment matching.
* **Bug Fixes**
* Clarified cancellation activity messages to note when users are asked
to restart after install failures.
* Updated Windows install copy and tooltips based on enrollment status.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45331)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Luke Heath <luke@fleetdm.com>
- **Adding vpp users table**
- **Adding ManagedAppleID to HostMDM tables to pull when installing vpp
apps to a BYOD user enrolled device**
- **Adding user create vpp apis**
- **Updating install application to support user enrolled devices**
- **Handling already installed gracefully**
- **Adding provision user logic**
- **Adding logic to associate assets on install**
- **Add license managemnt logic**
- **Adding self service ui**
- **Adding setup experience support**
- **Adding setup experience flow**
- **Fix issue with fleet's docker image in k8s environments (#44373)**
- **Changing how the appleid is captured to use idp mdm users**
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Account-based User Enrollment (iOS/iPadOS) supports VPP and in‑house
.ipa installs, including self‑service installs.
* Enrollment now applies the selected Setup experience automatically for
user‑enrolled hosts.
* Installs and license associations are scoped to account user
associations (user‑scoped installs).
* **Bug Fixes**
* Improved error messaging for license/association failures (including
per‑user device cap cases).
* Mobile UI: self‑service now shows user‑enrolled iOS/iPadOS apps.
* “Already installed” install results are treated as acknowledged
successes.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45202)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Resolves https://github.com/fleetdm/confidential/issues/15906
Rewrite README to align with Fleet's current positioning.
Key changes:
- Rewrote "What's it for?" to lead with MDM, remove company names, and
avoid osquery terminology
- Moved "Is it any good?" above "Lighter than air" so readers see
production credibility and capabilities before philosophy
- Restructured "Is it any good?" subsections to reflect top buying
reasons and align with
[why-fleet?](https://fleetdm.com/docs/get-started/why-fleet)
- Consolidated Chat section with link to fleetdm.com/support
- Removed Twitter/X Follow badge from Contributing
- Removed "The landscape of IT and cybersecurity" tagline from
Contributing
- Toned down "What's next?" opener
- Moved tagline below the image
- ~6% shorter overall, while adding substance (741 → ~720 words)
Resolves#45220 (one of many small PRs, we are close)
## Testing
- [X] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Tests**
* Refactored test infrastructure for scheduling components to use
centralized test utilities.
---
**Note:** This release contains no user-facing changes. All
modifications are internal testing and code organization improvements.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45609)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#45330
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
## Testing
- [X] Added/updated automated tests
so many
- [X] QA'd all new/changed functionality manually
- [X] was able to set gitops mode to enabled via `fleetctl gitops`
- [X] attempting to set gitops mode w/out repository_url in `fleetctl
gitops` failed w/ helpful error
- [X] attempting to set gitops mode w/ invalid repository_url in
`fleetctl gitops` failed w/ helpful error
- [X] attempting to set gitops exceptions in `fleetctl gitops` failed w/
helpful error
- [X] was able to unset gitops mode via `fleetctl gitops`
- [X] leaving `gitops:` blank in `fleetctl gitops` left the mode
untouched (it would retain its previous value)
## New Fleet configuration settings
- [ ] Setting(s) is/are explicitly excluded from GitOps
If you didn't check the box above, follow this checklist for
GitOps-enabled settings:
- [ ] Verified that the setting is exported via `fleetctl
generate-gitops`
it is not, but it's not a requirement here and leaving it out is a no-op
- [x] Verified the setting is documented in a separate PR to [the GitOps
documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485)
- [ ] Verified that the setting is cleared on the server if it is not
supplied in a YAML file (or that it is documented as being optional)
it is not, nor should it be, as that would clear gitops mode on every
customer currently using it
- [ ] Verified that any relevant UI is disabled when GitOps mode is
enabled
n/a, you still need to be able to do gitops mode in the UI
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* GitOps mode and repository URL can now be set via GitOps YAML.
* **Bug Fixes**
* Server preserves existing GitOps settings during config updates;
requires repository URL when enabling and rejects unsupported exceptions
in GitOps YAML.
* **Tests**
* Added tests covering apply behavior, YAML validation, activity
emission on mode changes, and license-restricted rejection on free tier.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45537)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Improve Camtasia uninstall handling by updating trash() to glob-expand
target paths (using compgen), iterate matches (preserving spaces), and
move each found file/symlink to the user's Trash with unique
timestamp+rand+index suffixes. If no matches are found the script now
reports the path doesn't exist. Also update darwin.json to point to the
new uninstall script ref (252f6f0e) and include the updated script
content in the refs section.
Clarify attribution framework and SFDC implementation: fix typos and
wording, distinguish first-touch vs converting-touch behavior, and add
detailed SFDC field mapping for Contact/Lead and Opportunity records.
Document the automation flow that derives L1/L2 from campaign codes,
stamps first-touch, adds campaign members, and copies Most Recent values
into Opportunity Converting fields on creation. Also standardize
campaign examples/naming, correct table headers (Psystage legacy) and
picklist name (Marketing_Email_Status__c), and tidy miscellaneous
examples and status definitions.
Register XCreds as a maintained app: add Homebrew cask (Casks/xcreds.rb)
and API/input JSON, add app metadata
(ee/maintained-apps/inputs/homebrew/xcreds.json), and include outputs
(apps.json and outputs/xcreds/darwin.json) with installer/uninstall
scripts and checks. Also add frontend icon component and asset
(XCreds.tsx, app-icon-xcreds-60x60@2x.png) and wire the icon into the
icons index mapping.