From 778133ddb0955dacf48fab3fae70cab0532388c2 Mon Sep 17 00:00:00 2001 From: RachelElysia <71795832+RachelElysia@users.noreply.github.com> Date: Fri, 2 Jan 2026 17:03:10 -0500 Subject: [PATCH] FMA: Fix aircall category typo and add string check for category in generator (#37815) --- cmd/maintained-apps/main.go | 45 +++++++++++++++++++ ee/maintained-apps/inputs/winget/aircall.json | 2 +- .../outputs/aircall/windows.json | 2 +- frontend/interfaces/software.ts | 1 + 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/cmd/maintained-apps/main.go b/cmd/maintained-apps/main.go index a6119433fc..30ad0a7f22 100644 --- a/cmd/maintained-apps/main.go +++ b/cmd/maintained-apps/main.go @@ -61,6 +61,19 @@ func main() { } func processOutput(ctx context.Context, app *maintained_apps.FMAManifestApp) error { + // validate categories before writing any files + if err := validateCategories(ctx, app); err != nil { + // Make the validation failure very obvious on stderr. + fmt.Fprintf( + os.Stderr, + "maintained-apps: fatal error processing %s: %v\n", + app.Slug, + err, + ) + // Wrap so callers still see a proper error. + return ctxerr.Wrap(ctx, err, "validating categories") + } + if err := updateAppsListFile(ctx, app); err != nil { return ctxerr.Wrap(ctx, err, "updating apps list file") } @@ -102,6 +115,38 @@ func processOutput(ctx context.Context, app *maintained_apps.FMAManifestApp) err return nil } +// Match types in frontend/interfaces/software.ts +var allowedCategories = map[string]struct{}{ + "Browsers": {}, + "Communication": {}, + "Developer Tools": {}, + "Productivity": {}, + "Security": {}, + "Utilities": {}, +} + +func allowedCategoriesString() string { + cats := make([]string, 0, len(allowedCategories)) + for c := range allowedCategories { + cats = append(cats, c) + } + slices.Sort(cats) + return strings.Join(cats, ", ") +} + +// validateCategories ensures every category on the app is one of the supported values. +func validateCategories(ctx context.Context, app *maintained_apps.FMAManifestApp) error { + for _, c := range app.DefaultCategories { + if _, ok := allowedCategories[c]; !ok { + return ctxerr.New(ctx, fmt.Sprintf( + "invalid category %q for slug %s (allowed: %s)", + c, app.Slug, allowedCategoriesString(), + )) + } + } + return nil +} + func updateAppsListFile(ctx context.Context, outApp *maintained_apps.FMAManifestApp) error { appListFilePath := path.Join(maintained_apps.OutputPath, "apps.json") inputJson, err := os.ReadFile(appListFilePath) diff --git a/ee/maintained-apps/inputs/winget/aircall.json b/ee/maintained-apps/inputs/winget/aircall.json index 93c6be32d5..4eed94b690 100644 --- a/ee/maintained-apps/inputs/winget/aircall.json +++ b/ee/maintained-apps/inputs/winget/aircall.json @@ -6,5 +6,5 @@ "installer_arch": "x64", "installer_type": "msi", "installer_scope": "machine", - "default_categories": ["Communicatio"] + "default_categories": ["Communication"] } diff --git a/ee/maintained-apps/outputs/aircall/windows.json b/ee/maintained-apps/outputs/aircall/windows.json index 675eddd972..a29db686b3 100644 --- a/ee/maintained-apps/outputs/aircall/windows.json +++ b/ee/maintained-apps/outputs/aircall/windows.json @@ -10,7 +10,7 @@ "uninstall_script_ref": "08c272d5", "sha256": "42e747bbeefb791ab6dca212c5b8f823bf90d6e6e6d3b0ab5db1bcd6d83bb268", "default_categories": [ - "Communicatio" + "Communication" ] } ], diff --git a/frontend/interfaces/software.ts b/frontend/interfaces/software.ts index 845e06a070..6d68a74f37 100644 --- a/frontend/interfaces/software.ts +++ b/frontend/interfaces/software.ts @@ -70,6 +70,7 @@ export interface ISoftwareInstallPolicy { name: string; } +// Match allowedCategories in cmd/maintained-apps/main.go export type SoftwareCategory = | "Browsers" | "Communication"