From fe05ce4f4893b32af41db10925b16f0aec6dcbca Mon Sep 17 00:00:00 2001 From: Allen Houchins <32207388+allenhouchins@users.noreply.github.com> Date: Thu, 19 Feb 2026 22:23:51 -0600 Subject: [PATCH] Add PuTTY as a Windows FMA (#40155) This pull request adds support for the PuTTY application (Windows) to the maintained apps system, including metadata, installation/uninstallation scripts, and frontend icon integration. The changes ensure that PuTTY can be managed and visually represented in the software catalog. **Maintained Apps Integration:** - Added a new input file `putty.json` with PuTTY metadata for Windows, specifying installer details and categories. - Generated an output file `putty/windows.json` containing version information, install/uninstall scripts, installer URL, and SHA256 hash for PuTTY. - Updated the aggregated `apps.json` output to include PuTTY with its description and unique identifier for the Windows platform. **Frontend/Icon Integration:** - Added a new React SVG icon component for PuTTY in `Putty.tsx`. - Registered the PuTTY icon in the icon index and mapped it in `SOFTWARE_NAME_TO_ICON_MAP` for display in the software catalog. [[1]](diffhunk://#diff-628095892e1d16090be1db6cc1a5c9cebc65248c32a8b1312385394818f2907bR15) [[2]](diffhunk://#diff-628095892e1d16090be1db6cc1a5c9cebc65248c32a8b1312385394818f2907bR412) --- ee/maintained-apps/inputs/winget/putty.json | 10 ++++++++ ee/maintained-apps/outputs/apps.json | 7 ++++++ ee/maintained-apps/outputs/putty/windows.json | 22 ++++++++++++++++++ .../SoftwarePage/components/icons/Putty.tsx | 14 +++++++++++ .../SoftwarePage/components/icons/index.ts | 2 ++ .../assets/images/app-icon-putty-60x60@2x.png | Bin 0 -> 7236 bytes 6 files changed, 55 insertions(+) create mode 100644 ee/maintained-apps/inputs/winget/putty.json create mode 100644 ee/maintained-apps/outputs/putty/windows.json create mode 100644 frontend/pages/SoftwarePage/components/icons/Putty.tsx create mode 100644 website/assets/images/app-icon-putty-60x60@2x.png diff --git a/ee/maintained-apps/inputs/winget/putty.json b/ee/maintained-apps/inputs/winget/putty.json new file mode 100644 index 0000000000..b77cd4446d --- /dev/null +++ b/ee/maintained-apps/inputs/winget/putty.json @@ -0,0 +1,10 @@ +{ + "name": "PuTTY", + "slug": "putty/windows", + "package_identifier": "PuTTY.PuTTY", + "unique_identifier": "PuTTY release 0.83 (x64)", + "installer_arch": "x64", + "installer_type": "msi", + "installer_scope": "machine", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/outputs/apps.json b/ee/maintained-apps/outputs/apps.json index 2436754d94..ebd75f0b02 100644 --- a/ee/maintained-apps/outputs/apps.json +++ b/ee/maintained-apps/outputs/apps.json @@ -1261,6 +1261,13 @@ "unique_identifier": "com.initex.proxifier.v3.macos", "description": "Proxifier is an app that allows network applications that do not support working through proxy servers to operate through a SOCKS or HTTPS proxy and chains." }, + { + "name": "PuTTY", + "slug": "putty/windows", + "platform": "windows", + "unique_identifier": "PuTTY release 0.83 (x64)", + "description": "PuTTY is a free, open-source SSH and Telnet client for Windows." + }, { "name": "PyCharm Community Edition", "slug": "pycharm-ce/darwin", diff --git a/ee/maintained-apps/outputs/putty/windows.json b/ee/maintained-apps/outputs/putty/windows.json new file mode 100644 index 0000000000..8de34d9366 --- /dev/null +++ b/ee/maintained-apps/outputs/putty/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "0.83.0.0", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'PuTTY release 0.83 (x64)' AND publisher = 'Simon Tatham';" + }, + "installer_url": "https://the.earth.li/~sgtatham/putty/0.83/w64/putty-64bit-0.83-installer.msi", + "install_script_ref": "8959087b", + "uninstall_script_ref": "84bf0290", + "sha256": "aa8e5036d973688f1e8622fbe9ab22e037346e0def0197bf5e7cdf37da4e223d", + "default_categories": [ + "Productivity" + ], + "upgrade_code": "{C9EAA861-2B72-4FAF-9FEE-EEB1AD5FD15E}" + } + ], + "refs": { + "84bf0290": "# Fleet uninstalls app by finding all related product codes for the specified upgrade code\n$inst = New-Object -ComObject \"WindowsInstaller.Installer\"\n$timeoutSeconds = 300 # 5 minute timeout per product\n\nforeach ($product_code in $inst.RelatedProducts(\"{C9EAA861-2B72-4FAF-9FEE-EEB1AD5FD15E}\")) {\n $process = Start-Process msiexec -ArgumentList @(\"/quiet\", \"/x\", $product_code, \"/norestart\") -PassThru\n \n # Wait for process with timeout\n $completed = $process.WaitForExit($timeoutSeconds * 1000)\n \n if (-not $completed) {\n Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue\n Exit 1603 # ERROR_UNINSTALL_FAILURE\n }\n \n # If the uninstall failed, bail\n if ($process.ExitCode -ne 0) {\n Write-Output \"Uninstall for $($product_code) exited $($process.ExitCode)\"\n Exit $process.ExitCode\n }\n}\n\n# All uninstalls succeeded; exit success\nExit 0\n", + "8959087b": "$logFile = \"${env:TEMP}/fleet-install-software.log\"\n\ntry {\n\n$installProcess = Start-Process msiexec.exe `\n -ArgumentList \"/quiet /norestart /lv ${logFile} /i `\"${env:INSTALLER_PATH}`\"\" `\n -PassThru -Verb RunAs -Wait\n\nGet-Content $logFile -Tail 500\n\nExit $installProcess.ExitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/frontend/pages/SoftwarePage/components/icons/Putty.tsx b/frontend/pages/SoftwarePage/components/icons/Putty.tsx new file mode 100644 index 0000000000..ea5bccaea7 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Putty.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Putty = (props: SVGProps) => ( + + + +); +export default Putty; diff --git a/frontend/pages/SoftwarePage/components/icons/index.ts b/frontend/pages/SoftwarePage/components/icons/index.ts index 5e5f8b0f67..ed56ba5210 100644 --- a/frontend/pages/SoftwarePage/components/icons/index.ts +++ b/frontend/pages/SoftwarePage/components/icons/index.ts @@ -12,6 +12,7 @@ import Nextcloud from "./Nextcloud"; import Notepad from "./Notepad++"; import OktaVerify from "./OktaVerify"; import Proxifier from "./Proxifier"; +import Putty from "./Putty"; import SevenZip from "./7Zip"; import Abstract from "./Abstract"; import AcrobatReader from "./AcrobatReader"; @@ -408,6 +409,7 @@ export const SOFTWARE_NAME_TO_ICON_MAP = { "proton mail": ProtonMail, protonvpn: ProtonVpn, proxifier: Proxifier, + putty: Putty, "pycharm ce": PyCharmCe, pycharm: PyCharm, quip: Quip, diff --git a/website/assets/images/app-icon-putty-60x60@2x.png b/website/assets/images/app-icon-putty-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..3ec15de0016d335d5e14c673ed017548b3735b33 GIT binary patch literal 7236 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 Zyh;(LLcac3a`lr<^}eRkM+M8U{{m~dO(g&T literal 0 HcmV?d00001