Skip to content

Update Fleet-maintained apps - #46375

Merged
allenhouchins merged 4 commits into
mainfrom
fma-2605281832
May 28, 2026
Merged

Update Fleet-maintained apps #46375
allenhouchins merged 4 commits into
mainfrom
fma-2605281832

Conversation

@fleet-release

@fleet-release fleet-release commented May 28, 2026

Copy link
Copy Markdown
Contributor

Automated ingestion of latest Fleet-maintained app data.

Summary by CodeRabbit

  • Chores
    • Updated Arc, Claude, Grammarly Desktop, Granola, Canva, and Power BI to newer releases with refreshed installers and checksums.
  • Bug Fixes
    • Improved Windows uninstall reliability and parsing for Canva and Power BI, and added safer handling when leftover registry/install entries are present.
  • Chores
    • Adjusted Power BI installer invocation to align with the updated installer behavior.

Review Change Stack

Generated automatically with cmd/maintained-apps.

@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.

@github-actions

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/arc/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/canva/windows.json

=== Install Script (no changes) ===
=== Uninstall // 58022dd8 -> f683286d ===

--- /tmp/old.1qqZ1Y	2026-05-28 18:35:46.117942375 +0000
+++ /tmp/new.SwNgwr	2026-05-28 18:35:46.117942375 +0000
@@ -32,7 +32,7 @@
 # Parse the uninstall string. Handle both quoted and unquoted exe paths.
 if ($uninstallString -match '^"([^"]+)"(.*)') {
     $exePath = $matches[1]
-} elseif ($uninstallString -match '^([^\s]+)(.*)') {
+} elseif ($uninstallString -match '^(.+?\.exe)(.*)$') {
     $exePath = $matches[1]
 } else {
     Write-Host "Error: Could not parse uninstall string: $uninstallString"

ee/maintained-apps/outputs/claude/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/grammarly-desktop/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/granola/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/granola/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/power-bi/windows.json

=== Install // ee068356 -> 4be62464 ===

--- /tmp/old.B9893X	2026-05-28 18:35:46.293944930 +0000
+++ /tmp/new.E7vAMP	2026-05-28 18:35:46.293944930 +0000
@@ -1,12 +1,8 @@
-# Learn more about .exe install scripts:
-# http://fleetdm.com/learn-more-about/exe-install-scripts
-
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {
 
 # Add argument to install silently
-# Asana uses --silent for silent installation
 $processOptions = @{
   FilePath = "$exeFilePath"
   ArgumentList = "/silent", "/norestart", "ACCEPT_EULA=1"

=== Uninstall // fa3b8ea6 -> 201475bb ===

--- /tmp/old.1KNqL7	2026-05-28 18:35:46.311945191 +0000
+++ /tmp/new.tU79Ti	2026-05-28 18:35:46.312945206 +0000
@@ -8,13 +8,16 @@
 # Removing the MSI directly orphans the bundle: its uninstall then no-ops
 # (returns 0) and leaves the "Microsoft PowerBI Desktop (x64)" registration
 # behind, which is what Fleet's osquery-based validator keeps detecting.
-# Correct approach: uninstall via the BUNDLE first; it removes the MSI and its
-# own registration. Burn relaunches a cached copy of itself + spawns msiexec
-# asynchronously, so wait for those to finish.
+#
+# Correct approach: uninstall via the BUNDLE first. It removes both the MSI and
+# its own registration. Burn relaunches a cached copy of itself and spawns
+# msiexec asynchronously, so wait for those to finish.
 
 $ExpectedExitCodes = @(0, 1605, 1641, 3010)
 $exitCode = 0
 
+# Power BI's default install folder; used as a safety check before deleting any
+# stale registration that survives a successful uninstall.
 $installDirs = @(
     (Join-Path $env:ProgramFiles 'Microsoft Power BI Desktop'),
     (Join-Path ${env:ProgramFiles(x86)} 'Microsoft Power BI Desktop')
@@ -58,6 +61,8 @@
 }
 
 try {
+
+    # Uninstall roots across all hives (matches osquery's "programs" table).
     $roots = [System.Collections.Generic.List[string]]::new()
     $roots.Add('HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall')
     $roots.Add('HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall')
@@ -77,20 +82,23 @@
         Stop-Process -Name $proc -Force -ErrorAction SilentlyContinue
     }
 
-    # Phase 1: uninstall via the Burn bundle bootstrapper(s) FIRST.
+    # --- Phase 1: uninstall via the Burn bundle bootstrapper(s) FIRST. ---
     foreach ($e in ($entries | Where-Object { $_.Command -match "(?i)PBIDesktopSetup.*\.exe" })) {
         $exe = Get-ExePath $e.Command
         if (-not $exe) { Write-Host "Could not parse bundle exe from: $($e.Command)"; continue }
         if (-not (Test-Path -LiteralPath $exe)) { Write-Host "Bundle exe missing: $exe"; continue }
 
         Write-Host "Uninstalling bundle: '$($e.DisplayName)'"
+        Write-Host "  Command: $exe"
+        Write-Host "  Args: /uninstall /quiet /norestart"
         $p = Start-Process -FilePath $exe -ArgumentList "/uninstall /quiet /norestart" -PassThru -Wait
         Write-Host "  Exit code: $($p.ExitCode)"
         if (($ExpectedExitCodes -notcontains $p.ExitCode) -and ($exitCode -eq 0)) { $exitCode = $p.ExitCode }
+
         Wait-ForProcessExit -Names @("PBIDesktopSetup_x64", "PBIDesktopSetup", "msiexec") -TimeoutSeconds 240
     }
 
-    # Phase 2: remove any MSI entries the bundle didn't clean up.
+    # --- Phase 2: remove any MSI entries the bundle didn't clean up. ---
     foreach ($e in (Get-PowerBIEntries -Roots $roots)) {
         $msiCode = $null
         if ($e.Command -match "(?i)MsiExec\.exe\s+/[IX]\s*(\{[A-F0-9-]+\})") { $msiCode = $Matches[1] }
@@ -104,16 +112,22 @@
         if (($ExpectedExitCodes -notcontains $p.ExitCode) -and ($exitCode -eq 0)) { $exitCode = $p.ExitCode }
     }
 
-    # Phase 3: safety net for stale registration when product files are gone.
+    # --- Phase 3: safety net. If the product files are gone but a stale ARP
+    # registration lingers, remove the orphaned key so detection clears. Gated
+    # on the install folder being absent so we never hide a real install. ---
     $productGone = -not ($installDirs | Where-Object { $_ -and (Test-Path -LiteralPath $_) })
     foreach ($e in (Get-PowerBIEntries -Roots $roots)) {
-        if ($productGone) {
+        $isMachineKey = $e.KeyPath -like 'Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\*'
+        if ($productGone -and $isMachineKey) {
             Write-Host "Removing orphaned registration: '$($e.DisplayName)' ($($e.KeyPath))"
             Remove-Item -Path $e.KeyPath -Recurse -Force -ErrorAction SilentlyContinue
         } else {
             Write-Host "WARNING: entry still present and product files remain: '$($e.DisplayName)'"
             if ($exitCode -eq 0) { $exitCode = 1 }
         }
+            Write-Host "WARNING: entry still present and product files remain: '$($e.DisplayName)'"
+            if ($exitCode -eq 0) { $exitCode = 1 }
+        }
     }
 
 } catch {

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR updates version metadata, installer URLs, and SHA256 checksums across multiple maintained-app JSON manifests (Arc, Claude, Grammarly Desktop, Granola macOS and Windows). It replaces the Canva Windows uninstall script with a modified regex for unquoted executable paths. Power BI Windows receives a version bump and new install/uninstall script refs; the uninstall script tightens its ARP/registry cleanup by only deleting orphaned machine-hive entries and otherwise emits a WARNING and may return a non-zero exit code.

Possibly related PRs

  • fleetdm/fleet#45904: Updates the Arc macOS maintained-app metadata (version, queries.patched, installer_url, sha256) — overlaps the Arc darwin.json change.
  • fleetdm/fleet#46284: Implements Power BI Windows install/uninstall script changes referenced here (silent-flag and uninstall safety-net logic).
  • fleetdm/fleet#46310: Updates Canva Windows uninstall script references and logic; this PR applies the corresponding uninstall-script changes to the maintained-app JSON and refs.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is minimal and lacks most required sections from the template, such as related issues, checklist items, testing details, and validation information. Complete the pull request description by adding required sections from the template, including related issue number, relevant checklist items, testing evidence, and security/validation details.
Title check ❓ Inconclusive The title 'Update Fleet-maintained apps' is vague and generic, using non-descriptive language that doesn't clearly convey the specific changes in the pull request. Revise the title to be more specific about the primary changes, such as 'Update Fleet-maintained app versions and Power BI installer arguments' or similar, to better reflect the substantive updates across multiple applications.
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fma-2605281832

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ee/maintained-apps/outputs/power-bi/windows.json`:
- Line 19: In the Phase 3 cleanup foreach (the loop iterating Get-PowerBIEntries
after computing $productGone) there is a duplicated warning block and an extra
closing brace that breaks parsing; edit the loop that checks $isMachineKey so
that only the single else branch remains (keep the Write-Host "WARNING: entry
still present..." and the if ($exitCode -eq 0) { $exitCode = 1 } inside that
else) and remove the duplicate Write-Host/if lines and the stray closing brace
so the foreach and try/catch blocks are properly balanced.
🪄 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: 32ff33e8-f7ff-4749-b99f-2827d6587e25

📥 Commits

Reviewing files that changed from the base of the PR and between 7b7b89a and 72cf936.

📒 Files selected for processing (7)
  • ee/maintained-apps/outputs/arc/darwin.json
  • ee/maintained-apps/outputs/canva/windows.json
  • ee/maintained-apps/outputs/claude/darwin.json
  • ee/maintained-apps/outputs/grammarly-desktop/darwin.json
  • ee/maintained-apps/outputs/granola/darwin.json
  • ee/maintained-apps/outputs/granola/windows.json
  • ee/maintained-apps/outputs/power-bi/windows.json

Comment thread ee/maintained-apps/outputs/power-bi/windows.json Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/arc/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/canva/windows.json

=== Install Script (no changes) ===
=== Uninstall // 58022dd8 -> f683286d ===

--- /tmp/old.e8MI5X	2026-05-28 19:40:39.126520315 +0000
+++ /tmp/new.SPaMbz	2026-05-28 19:40:39.127520312 +0000
@@ -32,7 +32,7 @@
 # Parse the uninstall string. Handle both quoted and unquoted exe paths.
 if ($uninstallString -match '^"([^"]+)"(.*)') {
     $exePath = $matches[1]
-} elseif ($uninstallString -match '^([^\s]+)(.*)') {
+} elseif ($uninstallString -match '^(.+?\.exe)(.*)$') {
     $exePath = $matches[1]
 } else {
     Write-Host "Error: Could not parse uninstall string: $uninstallString"

ee/maintained-apps/outputs/claude/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/grammarly-desktop/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/granola/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/granola/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/power-bi/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

@github-actions

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/arc/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/canva/windows.json

=== Install Script (no changes) ===
=== Uninstall // 58022dd8 -> f683286d ===

--- /tmp/old.3j5UYy	2026-05-28 19:41:46.348066162 +0000
+++ /tmp/new.4GdQBT	2026-05-28 19:41:46.349066163 +0000
@@ -32,7 +32,7 @@
 # Parse the uninstall string. Handle both quoted and unquoted exe paths.
 if ($uninstallString -match '^"([^"]+)"(.*)') {
     $exePath = $matches[1]
-} elseif ($uninstallString -match '^([^\s]+)(.*)') {
+} elseif ($uninstallString -match '^(.+?\.exe)(.*)$') {
     $exePath = $matches[1]
 } else {
     Write-Host "Error: Could not parse uninstall string: $uninstallString"

ee/maintained-apps/outputs/claude/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/grammarly-desktop/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/granola/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/granola/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/power-bi/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Actionable comments posted: 0

1 similar comment
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Actionable comments posted: 0

Replace /silent with /quiet for the Power BI EXE installer in the winget install script and the windows.json output snippet. Aligns the installer arguments with the bundle's uninstall usage (/uninstall /quiet /norestart) to ensure consistent silent install/uninstall behavior.
@github-actions

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/arc/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/canva/windows.json

=== Install Script (no changes) ===
=== Uninstall // 58022dd8 -> f683286d ===

--- /tmp/old.P4jagl	2026-05-28 20:44:05.790983601 +0000
+++ /tmp/new.fu4gDM	2026-05-28 20:44:05.790983601 +0000
@@ -32,7 +32,7 @@
 # Parse the uninstall string. Handle both quoted and unquoted exe paths.
 if ($uninstallString -match '^"([^"]+)"(.*)') {
     $exePath = $matches[1]
-} elseif ($uninstallString -match '^([^\s]+)(.*)') {
+} elseif ($uninstallString -match '^(.+?\.exe)(.*)$') {
     $exePath = $matches[1]
 } else {
     Write-Host "Error: Could not parse uninstall string: $uninstallString"

ee/maintained-apps/outputs/claude/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/grammarly-desktop/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/granola/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/granola/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/power-bi/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Actionable comments posted: 0

@github-actions

Copy link
Copy Markdown
Contributor

Closing in favor of #46386.

@github-actions

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/arc/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/canva/windows.json

=== Install Script (no changes) ===
=== Uninstall // 58022dd8 -> f683286d ===

--- /tmp/old.JM3bkT	2026-05-28 20:56:22.949934299 +0000
+++ /tmp/new.3SwEQS	2026-05-28 20:56:22.949934299 +0000
@@ -32,7 +32,7 @@
 # Parse the uninstall string. Handle both quoted and unquoted exe paths.
 if ($uninstallString -match '^"([^"]+)"(.*)') {
     $exePath = $matches[1]
-} elseif ($uninstallString -match '^([^\s]+)(.*)') {
+} elseif ($uninstallString -match '^(.+?\.exe)(.*)$') {
     $exePath = $matches[1]
 } else {
     Write-Host "Error: Could not parse uninstall string: $uninstallString"

ee/maintained-apps/outputs/claude/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/grammarly-desktop/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/granola/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/granola/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/power-bi/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

@github-actions

Copy link
Copy Markdown
Contributor

Closing in favor of #46389.

@github-actions github-actions Bot closed this May 28, 2026
@allenhouchins allenhouchins reopened this May 28, 2026
@allenhouchins allenhouchins changed the title Update Fleet-maintained apps Update Fleet-maintained apps May 28, 2026
@allenhouchins
allenhouchins merged commit 5a8fc5a into main May 28, 2026
26 of 27 checks passed
@allenhouchins
allenhouchins deleted the fma-2605281832 branch May 28, 2026 21:18
@github-actions

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/arc/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/canva/windows.json

=== Install Script (no changes) ===
=== Uninstall // 58022dd8 -> f683286d ===

--- /tmp/old.q9Q4yF	2026-05-28 21:18:36.533991692 +0000
+++ /tmp/new.D2sDNO	2026-05-28 21:18:36.533991692 +0000
@@ -32,7 +32,7 @@
 # Parse the uninstall string. Handle both quoted and unquoted exe paths.
 if ($uninstallString -match '^"([^"]+)"(.*)') {
     $exePath = $matches[1]
-} elseif ($uninstallString -match '^([^\s]+)(.*)') {
+} elseif ($uninstallString -match '^(.+?\.exe)(.*)$') {
     $exePath = $matches[1]
 } else {
     Write-Host "Error: Could not parse uninstall string: $uninstallString"

ee/maintained-apps/outputs/claude/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/grammarly-desktop/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/granola/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/granola/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/power-bi/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants