Skip to content

Windows FMA - DeepL#46507

Closed
harrisonravazzolo wants to merge 4 commits into
mainfrom
win-fma-deepl
Closed

Windows FMA - DeepL#46507
harrisonravazzolo wants to merge 4 commits into
mainfrom
win-fma-deepl

Conversation

@harrisonravazzolo

@harrisonravazzolo harrisonravazzolo commented May 29, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

Release Notes

  • New Features
    • Extended DeepL app management to Windows platform with automatic version detection capabilities
    • Added support for silent installation and uninstallation workflows on Windows systems
    • DeepL is now available for management across macOS and Windows

Review Change Stack

@github-actions

Copy link
Copy Markdown
Contributor

Script Diff Results

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

=== Install Script (no changes) ===
=== Uninstall // b098661f -> befae007 ===

--- /tmp/old.2N8rct	2026-05-30 00:44:22.921728021 +0000
+++ /tmp/new.OCcg6C	2026-05-30 00:44:22.921728021 +0000
@@ -1,3 +1,7 @@
+# Locates DeepL's uninstaller from the registry and runs it silently.
+# DeepL installs via Zero Install (0install). Its QuietUninstallString is a
+# 0install command, e.g.:
+
 $displayNameLike = "DeepL*"
 $publisher = "DeepL SE"
 
@@ -23,11 +27,11 @@
 
 Stop-Process -Name "DeepL" -Force -ErrorAction SilentlyContinue
 
-$uninstallCommand = if ($uninstall.QuietUninstallString) {
-    $uninstall.QuietUninstallString
-} else {
-    $uninstall.UninstallString
-}
+# Prefer QuietUninstallString -- it already carries 0install's silent flags
+# (--batch --background). Fall back to UninstallString and add those flags
+# (NOT --verysilent) to keep it non-interactive.
+$useQuiet = [bool]$uninstall.QuietUninstallString
+$uninstallCommand = if ($useQuiet) { $uninstall.QuietUninstallString } else { $uninstall.UninstallString }
 
 $exePath = ""
 $existingArgs = ""
@@ -37,34 +41,4 @@
 } elseif ($uninstallCommand -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
     $exePath = $matches[1]
     $existingArgs = $matches[2].Trim()
-} elseif ($uninstallCommand -match '^\s*(\S+)\s*(.*)$') {
-    $exePath = $matches[1]
-    $existingArgs = $matches[2].Trim()
-} else {
-    Throw "Could not parse uninstall string: $uninstallCommand"
-}
-
-if ($existingArgs -notmatch '(?i)--verysilent') {
-    $existingArgs = ("$existingArgs --verysilent").Trim()
-}
-
-Write-Host "Uninstall command: $exePath"
-Write-Host "Uninstall args: $existingArgs"
-
-try {
-    $processOptions = @{
-        FilePath = $exePath
-        ArgumentList = $existingArgs
-        NoNewWindow = $true
-        PassThru = $true
-        Wait = $true
-    }
-
-    $process = Start-Process @processOptions
-    $exitCode = $process.ExitCode
-    Write-Host "Uninstall exit code: $exitCode"
-    Exit $exitCode
-} catch {
-    Write-Host "Error running uninstaller: $_"
-    Exit 1
-}
+} elseif ($uninstallC

@github-actions

Copy link
Copy Markdown
Contributor

Script Diff Results

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

=== Install Script (no changes) ===
=== Uninstall // befae007 -> 3de00047 ===

--- /tmp/old.uqEbz9	2026-05-30 00:54:14.810442229 +0000
+++ /tmp/new.BD15Ko	2026-05-30 00:54:14.810442229 +0000
@@ -1,44 +1,74 @@
-# Locates DeepL's uninstaller from the registry and runs it silently.
-# DeepL installs via Zero Install (0install). Its QuietUninstallString is a
-# 0install command, e.g.:
-
-$displayNameLike = "DeepL*"
-$publisher = "DeepL SE"
-
-$paths = @(
-  'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
-  'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall',
-  'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
-  'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+$ErrorActionPreference = "Stop"
+$ProgressPreference = "SilentlyContinue"
+
+$uninstallKeys = @(
+    "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*",
+    "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*",
+    "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*",
+    "HKCU:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
 )
 
-$uninstall = $null
-foreach ($p in $paths) {
-  $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object {
-    $_.DisplayName -like $displayNameLike -and $_.Publisher -like "$publisher*"
-  }
-  if ($items) { $uninstall = $items | Select-Object -First 1; break }
-}
-
-if (-not $uninstall -or (-not $uninstall.UninstallString -and -not $uninstall.QuietUninstallString)) {
-  Write-Host "Uninstall entry not found"
-  Exit 0
-}
-
-Stop-Process -Name "DeepL" -Force -ErrorAction SilentlyContinue
-
-# Prefer QuietUninstallString -- it already carries 0install's silent flags
-# (--batch --background). Fall back to UninstallString and add those flags
-# (NOT --verysilent) to keep it non-interactive.
-$useQuiet = [bool]$uninstall.QuietUninstallString
-$uninstallCommand = if ($useQuiet) { $uninstall.QuietUninstallString } else { $uninstall.UninstallString }
-
-$exePath = ""
-$existingArgs = ""
-if ($uninstallCommand -match '^\s*"([^"]+)"\s*(.*)$') {
-    $exePath = $matches[1]
-    $existingArgs = $matches[2].Trim()
-} elseif ($uninstallCommand -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
-    $exePath = $matches[1]
-    $existingArgs = $matches[2].Trim()
-} elseif ($uninstallC
+$app = Get-ItemProperty $uninstallKeys -ErrorAction SilentlyContinue |
+    Where-Object { $_.DisplayName -like "DeepL*" } |
+    Select-Object -First 1
+
+if (-not $app) {
+    Write-Host "DeepL not found in registry; nothing to uninstall."
+    exit 0
+}
+
+# Prefer QuietUninstallString verbatim — 0install already includes --batch --background there.
+$useQuiet = $false
+$cmd = $null
+$arguments = ""
+
+if ($app.QuietUninstallString) {
+    $uninstallString = $app.QuietUninstallString
+    $useQuiet = $true
+} else {
+    $uninstallString = $app.UninstallString
+}
+
+if (-not $uninstallString) {
+    Write-Host "No uninstall string found for DeepL."
+    exit 1
+}
+
+# Parse the uninstall string into executable + arguments.
+if ($uninstallString -match '^"([^"]+)"\s*(.*)$') {
+    # Quoted executable path.
+    $cmd = $matches[1]
+    $arguments = $matches[2].Trim()
+} elseif ($uninstallString -match '^(\S+\.exe)\s*(.*)$') {
+    # Unquoted single-token executable.
+    $cmd = $matches[1]
+    $arguments = $matches[2].Trim()
+} else {
+    # Bare path with no arguments.
+    $cmd = $uninstallString.Trim()
+    $arguments = ""
+}
+
+# Only append 0install silent flags when we fell back to the plain UninstallString.
+if (-not $useQuiet) {
+    if ($arguments -notmatch '--batch')      { $arguments = ("$arguments --batch").Trim() }
+    if ($arguments -notmatch '--background') { $arguments = ("$arguments --background").Trim() }
+}
+
+Write-Host "Uninstalling DeepL: $cmd $arguments"
+
+if ($arguments) {
+    $proc = Start-Process -FilePath $cmd -ArgumentList $arguments -Wait -PassThru -NoNewWindow
+} else {
+    $proc = Start-Process -FilePath $cmd -Wait -PassThru -NoNewWindow
+}
+
+$exitCode = $proc.ExitCode
+Write-Host "Uninstaller exited with code $exitCode"
+
+# 0install / common success codes.
+if ($exitCode -eq 0 -or $exitCode -eq 3010 -or $exitCode -eq 1605) {
+    exit 0
+}
+
+exit $exitCode

@harrisonravazzolo harrisonravazzolo marked this pull request as ready for review May 30, 2026 00:58
@harrisonravazzolo harrisonravazzolo requested a review from a team as a code owner May 30, 2026 00:58

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

@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 453b112b-ab02-4124-80ba-dbe4ac742157

📥 Commits

Reviewing files that changed from the base of the PR and between ef6a51d and e9f1911.

📒 Files selected for processing (6)
  • cmd/maintained-apps/validate/windows.go
  • ee/maintained-apps/inputs/winget/deepl.json
  • ee/maintained-apps/inputs/winget/scripts/deepl_install.ps1
  • ee/maintained-apps/inputs/winget/scripts/deepl_uninstall.ps1
  • ee/maintained-apps/outputs/apps.json
  • ee/maintained-apps/outputs/deepl/windows.json

Walkthrough

This PR adds complete Windows support for DeepL to Fleet's maintained apps system. It introduces a Winget input manifest defining DeepL's installer characteristics, two PowerShell scripts for automated installation and uninstallation with registry-based detection and exit code normalization, output definitions registering DeepL as a Windows app with version 26.4.1 metadata, and a validation logic adjustment to handle DeepL's detection when version information is unavailable.

Possibly related PRs

  • fleetdm/fleet#42397: Modifies the same appExists validation function in cmd/maintained-apps/validate/windows.go to add special-case detection fallback logic for a specific app.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning No pull request description was provided by the author, violating the template requirement for context about changes and related issue tracking. Add a detailed description following the template, including the related issue number, relevant checklist items completed, and a summary of the Windows DeepL FMA implementation.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies that this PR adds Windows support for DeepL application in the FMA (Frequently Maintained Applications) system, which aligns with the changeset.
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 win-fma-deepl

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.

@codecov

codecov Bot commented May 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 66.81%. Comparing base (ef6a51d) to head (e9f1911).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #46507   +/-   ##
=======================================
  Coverage   66.81%   66.81%           
=======================================
  Files        2805     2805           
  Lines      223576   223576           
  Branches    11481    11481           
=======================================
+ Hits       149380   149387    +7     
+ Misses      60640    60635    -5     
+ Partials    13556    13554    -2     
Flag Coverage Δ
backend 68.53% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@allenhouchins

Copy link
Copy Markdown
Member

Moving this one to draft to think through it some more. If it doesn't register a version string (which I confirmed it doesn't via osquery or winget) then we can never guarantee the patch policy.

@allenhouchins allenhouchins marked this pull request as draft May 30, 2026 01:18
@allenhouchins allenhouchins self-assigned this May 30, 2026
@harrisonravazzolo

Copy link
Copy Markdown
Member Author

Let's just close this one and skip - I thought maybe it registered it in the reg key but no. Odd little app.

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