From 1e3612115c8eadd283077218977cb91b6bce3982 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 2 Jul 2026 18:46:09 -0400 Subject: [PATCH 01/10] use package.json for plugin info --- src/plugins/serverlessops-catalog/src/plugin.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/serverlessops-catalog/src/plugin.tsx b/src/plugins/serverlessops-catalog/src/plugin.tsx index e204669..f0a6ccc 100644 --- a/src/plugins/serverlessops-catalog/src/plugin.tsx +++ b/src/plugins/serverlessops-catalog/src/plugin.tsx @@ -37,6 +37,9 @@ export const SoCatalogTabbedDirectoryIndexPage = PageBlueprint.make({ const serverlessOpsCatalogPlugin = createFrontendPlugin({ pluginId: 'serverlessops-catalog', + info: { + packageJson: () => require('../../../package.json'), + }, routes: { catalogIndex: catalogIndexRouteRef, tabbedCatalog: tabbedCatalogRouteRef, From 83ede2704a2dc5c99a76dce41118072b2b930aca Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 2 Jul 2026 20:22:33 -0400 Subject: [PATCH 02/10] convert serverlessops-catalog plugin to a module I no longer need a plugin and can just make overrides to the catalog plugin --- src/packages/app/package.json | 2 +- src/packages/app/src/App.tsx | 4 +- .../.eslintrc.js | 0 .../README.md | 0 .../dev/index.tsx | 6 ++ .../package.json | 7 +- .../CatalogEntityPage/catalogEntityPage.tsx | 0 .../CatalogIndexColumns/columns.tsx | 0 .../ApiCatalogIndexPageEntityList.tsx | 0 .../CatalogIndexPageEntityList.tsx | 0 .../ComponentCatalogIndexPageEntityList.tsx | 0 .../DomainCatalogIndexPageEntityList.tsx | 0 .../GroupCatalogIndexPageEntityList.tsx | 0 .../LocationCatalogIndexPageEntityList.tsx | 0 .../ResourceCatalogIndexPageEntityList.tsx | 0 .../SystemCatalogIndexPageEntityList.tsx | 0 .../UserCatalogIndexPageEntityList.tsx | 0 .../CatalogIndexPageEntityList/index.ts | 0 .../TabbedCatalogIndexPage.tsx | 0 .../TabbedCatalogIndexPage/index.ts | 0 .../TabbedDirectoryIndexPage.tsx | 0 .../TabbedDirectoryIndexPage/index.ts | 0 .../catalog-module-serverlessops/src/index.ts | 3 + .../src/module.tsx | 41 ++++++++++ .../src/routes.ts | 0 .../src/setupTests.ts | 0 .../serverlessops-catalog/dev/index.tsx | 6 -- .../serverlessops-catalog/src/index.ts | 5 -- .../serverlessops-catalog/src/plugin.test.ts | 17 ----- .../serverlessops-catalog/src/plugin.tsx | 54 ------------- src/yarn.lock | 76 +++++++++---------- 31 files changed, 95 insertions(+), 126 deletions(-) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/.eslintrc.js (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/README.md (100%) create mode 100644 src/plugins/catalog-module-serverlessops/dev/index.tsx rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/package.json (92%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/CatalogEntityPage/catalogEntityPage.tsx (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/CatalogIndexColumns/columns.tsx (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/CatalogIndexPageEntityList/ApiCatalogIndexPageEntityList.tsx (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/CatalogIndexPageEntityList/CatalogIndexPageEntityList.tsx (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/CatalogIndexPageEntityList/ComponentCatalogIndexPageEntityList.tsx (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/CatalogIndexPageEntityList/DomainCatalogIndexPageEntityList.tsx (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/CatalogIndexPageEntityList/GroupCatalogIndexPageEntityList.tsx (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/CatalogIndexPageEntityList/LocationCatalogIndexPageEntityList.tsx (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/CatalogIndexPageEntityList/ResourceCatalogIndexPageEntityList.tsx (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/CatalogIndexPageEntityList/SystemCatalogIndexPageEntityList.tsx (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/CatalogIndexPageEntityList/UserCatalogIndexPageEntityList.tsx (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/CatalogIndexPageEntityList/index.ts (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/TabbedCatalogIndexPage/TabbedCatalogIndexPage.tsx (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/TabbedCatalogIndexPage/index.ts (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/TabbedDirectoryIndexPage/TabbedDirectoryIndexPage.tsx (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/components/TabbedDirectoryIndexPage/index.ts (100%) create mode 100644 src/plugins/catalog-module-serverlessops/src/index.ts create mode 100644 src/plugins/catalog-module-serverlessops/src/module.tsx rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/routes.ts (100%) rename src/plugins/{serverlessops-catalog => catalog-module-serverlessops}/src/setupTests.ts (100%) delete mode 100644 src/plugins/serverlessops-catalog/dev/index.tsx delete mode 100644 src/plugins/serverlessops-catalog/src/index.ts delete mode 100644 src/plugins/serverlessops-catalog/src/plugin.test.ts delete mode 100644 src/plugins/serverlessops-catalog/src/plugin.tsx diff --git a/src/packages/app/package.json b/src/packages/app/package.json index 74cdd02..e94b66f 100644 --- a/src/packages/app/package.json +++ b/src/packages/app/package.json @@ -37,8 +37,8 @@ "@backstage/plugin-techdocs-module-addons-contrib": "backstage:^", "@backstage/plugin-user-settings": "backstage:^", "@backstage/ui": "backstage:^", + "@internal/backstage-plugin-catalog-module-serverlessops": "workspace:^", "@internal/backstage-plugin-scaffolder-entity-pickers": "workspace:^", - "@internal/backstage-plugin-serverlessops-catalog": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "react": "^18.0.2", diff --git a/src/packages/app/src/App.tsx b/src/packages/app/src/App.tsx index ef79c96..07c87c1 100644 --- a/src/packages/app/src/App.tsx +++ b/src/packages/app/src/App.tsx @@ -1,6 +1,6 @@ import { createApp } from '@backstage/frontend-defaults'; import catalogPlugin from '@backstage/plugin-catalog/alpha'; -import serverlessOpsCatalogPlugin from '@internal/backstage-plugin-serverlessops-catalog'; +import serverlessOpsCatalogModule from '@internal/backstage-plugin-catalog-module-serverlessops'; import { navModule } from './modules/nav'; import { configApiRef, googleAuthApiRef, useApi } from '@backstage/core-plugin-api'; import { SignInPageBlueprint } from '@backstage/plugin-app-react'; @@ -48,7 +48,7 @@ export default createApp({ features: [ catalogPlugin, navModule, - serverlessOpsCatalogPlugin, + serverlessOpsCatalogModule, createFrontendModule({ pluginId: 'app', extensions: [signInPage], diff --git a/src/plugins/serverlessops-catalog/.eslintrc.js b/src/plugins/catalog-module-serverlessops/.eslintrc.js similarity index 100% rename from src/plugins/serverlessops-catalog/.eslintrc.js rename to src/plugins/catalog-module-serverlessops/.eslintrc.js diff --git a/src/plugins/serverlessops-catalog/README.md b/src/plugins/catalog-module-serverlessops/README.md similarity index 100% rename from src/plugins/serverlessops-catalog/README.md rename to src/plugins/catalog-module-serverlessops/README.md diff --git a/src/plugins/catalog-module-serverlessops/dev/index.tsx b/src/plugins/catalog-module-serverlessops/dev/index.tsx new file mode 100644 index 0000000..595f259 --- /dev/null +++ b/src/plugins/catalog-module-serverlessops/dev/index.tsx @@ -0,0 +1,6 @@ +import { createDevApp } from '@backstage/frontend-dev-utils' +import serverlessOpsCatalogModule from '../src' + +createDevApp({ + features: [serverlessOpsCatalogModule], +}) diff --git a/src/plugins/serverlessops-catalog/package.json b/src/plugins/catalog-module-serverlessops/package.json similarity index 92% rename from src/plugins/serverlessops-catalog/package.json rename to src/plugins/catalog-module-serverlessops/package.json index 93796b9..f7f5471 100644 --- a/src/plugins/serverlessops-catalog/package.json +++ b/src/plugins/catalog-module-serverlessops/package.json @@ -1,5 +1,5 @@ { - "name": "@internal/backstage-plugin-serverlessops-catalog", + "name": "@internal/backstage-plugin-catalog-module-serverlessops", "version": "0.1.0", "main": "src/index.ts", "types": "src/index.ts", @@ -11,8 +11,9 @@ "types": "dist/index.d.ts" }, "backstage": { - "role": "frontend-plugin", - "pluginId": "serverlessops-catalog" + "role": "frontend-plugin-module", + "pluginId": "catalog", + "moduleId": "serverlessops" }, "sideEffects": false, "scripts": { diff --git a/src/plugins/serverlessops-catalog/src/components/CatalogEntityPage/catalogEntityPage.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogEntityPage/catalogEntityPage.tsx similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/CatalogEntityPage/catalogEntityPage.tsx rename to src/plugins/catalog-module-serverlessops/src/components/CatalogEntityPage/catalogEntityPage.tsx diff --git a/src/plugins/serverlessops-catalog/src/components/CatalogIndexColumns/columns.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexColumns/columns.tsx similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/CatalogIndexColumns/columns.tsx rename to src/plugins/catalog-module-serverlessops/src/components/CatalogIndexColumns/columns.tsx diff --git a/src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/ApiCatalogIndexPageEntityList.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ApiCatalogIndexPageEntityList.tsx similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/ApiCatalogIndexPageEntityList.tsx rename to src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ApiCatalogIndexPageEntityList.tsx diff --git a/src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/CatalogIndexPageEntityList.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/CatalogIndexPageEntityList.tsx similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/CatalogIndexPageEntityList.tsx rename to src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/CatalogIndexPageEntityList.tsx diff --git a/src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/ComponentCatalogIndexPageEntityList.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ComponentCatalogIndexPageEntityList.tsx similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/ComponentCatalogIndexPageEntityList.tsx rename to src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ComponentCatalogIndexPageEntityList.tsx diff --git a/src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/DomainCatalogIndexPageEntityList.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/DomainCatalogIndexPageEntityList.tsx similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/DomainCatalogIndexPageEntityList.tsx rename to src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/DomainCatalogIndexPageEntityList.tsx diff --git a/src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/GroupCatalogIndexPageEntityList.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/GroupCatalogIndexPageEntityList.tsx similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/GroupCatalogIndexPageEntityList.tsx rename to src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/GroupCatalogIndexPageEntityList.tsx diff --git a/src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/LocationCatalogIndexPageEntityList.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/LocationCatalogIndexPageEntityList.tsx similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/LocationCatalogIndexPageEntityList.tsx rename to src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/LocationCatalogIndexPageEntityList.tsx diff --git a/src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/ResourceCatalogIndexPageEntityList.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ResourceCatalogIndexPageEntityList.tsx similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/ResourceCatalogIndexPageEntityList.tsx rename to src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ResourceCatalogIndexPageEntityList.tsx diff --git a/src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/SystemCatalogIndexPageEntityList.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/SystemCatalogIndexPageEntityList.tsx similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/SystemCatalogIndexPageEntityList.tsx rename to src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/SystemCatalogIndexPageEntityList.tsx diff --git a/src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/UserCatalogIndexPageEntityList.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/UserCatalogIndexPageEntityList.tsx similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/UserCatalogIndexPageEntityList.tsx rename to src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/UserCatalogIndexPageEntityList.tsx diff --git a/src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/index.ts b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/index.ts similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/CatalogIndexPageEntityList/index.ts rename to src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/index.ts diff --git a/src/plugins/serverlessops-catalog/src/components/TabbedCatalogIndexPage/TabbedCatalogIndexPage.tsx b/src/plugins/catalog-module-serverlessops/src/components/TabbedCatalogIndexPage/TabbedCatalogIndexPage.tsx similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/TabbedCatalogIndexPage/TabbedCatalogIndexPage.tsx rename to src/plugins/catalog-module-serverlessops/src/components/TabbedCatalogIndexPage/TabbedCatalogIndexPage.tsx diff --git a/src/plugins/serverlessops-catalog/src/components/TabbedCatalogIndexPage/index.ts b/src/plugins/catalog-module-serverlessops/src/components/TabbedCatalogIndexPage/index.ts similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/TabbedCatalogIndexPage/index.ts rename to src/plugins/catalog-module-serverlessops/src/components/TabbedCatalogIndexPage/index.ts diff --git a/src/plugins/serverlessops-catalog/src/components/TabbedDirectoryIndexPage/TabbedDirectoryIndexPage.tsx b/src/plugins/catalog-module-serverlessops/src/components/TabbedDirectoryIndexPage/TabbedDirectoryIndexPage.tsx similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/TabbedDirectoryIndexPage/TabbedDirectoryIndexPage.tsx rename to src/plugins/catalog-module-serverlessops/src/components/TabbedDirectoryIndexPage/TabbedDirectoryIndexPage.tsx diff --git a/src/plugins/serverlessops-catalog/src/components/TabbedDirectoryIndexPage/index.ts b/src/plugins/catalog-module-serverlessops/src/components/TabbedDirectoryIndexPage/index.ts similarity index 100% rename from src/plugins/serverlessops-catalog/src/components/TabbedDirectoryIndexPage/index.ts rename to src/plugins/catalog-module-serverlessops/src/components/TabbedDirectoryIndexPage/index.ts diff --git a/src/plugins/catalog-module-serverlessops/src/index.ts b/src/plugins/catalog-module-serverlessops/src/index.ts new file mode 100644 index 0000000..d08f350 --- /dev/null +++ b/src/plugins/catalog-module-serverlessops/src/index.ts @@ -0,0 +1,3 @@ +export { + serverlessOpsCatalogModule as default, +} from './module'; diff --git a/src/plugins/catalog-module-serverlessops/src/module.tsx b/src/plugins/catalog-module-serverlessops/src/module.tsx new file mode 100644 index 0000000..3f1c757 --- /dev/null +++ b/src/plugins/catalog-module-serverlessops/src/module.tsx @@ -0,0 +1,41 @@ +import { UserIcon } from '@backstage/core-components' +import { + createFrontendModule, + createRouteRef, + PageBlueprint, +} from '@backstage/frontend-plugin-api' + +const tabbedDirectoryRouteRef = createRouteRef() + +export const SoCatalogTabbedIndexPage = PageBlueprint.make({ + params: { + path: '/catalog', + routeRef: createRouteRef({ aliasFor: 'catalog.catalogIndex' }), + loader: async () => { + const { TabbedCatalogIndexPage } = await import('./components/TabbedCatalogIndexPage') + return < TabbedCatalogIndexPage /> + } + } +}) + +export const SoCatalogTabbedDirectoryIndexPage = PageBlueprint.make({ + name: 'directory', + params: { + path: '/directory', + title: 'Directory', + icon: , + routeRef: tabbedDirectoryRouteRef, + loader: async () => { + const { TabbedDirectoryIndexPage } = await import('./components/TabbedDirectoryIndexPage') + return < TabbedDirectoryIndexPage /> + } + }, +}) + +export const serverlessOpsCatalogModule = createFrontendModule({ + pluginId: 'catalog', + extensions: [ + SoCatalogTabbedIndexPage, + SoCatalogTabbedDirectoryIndexPage, + ] +}); diff --git a/src/plugins/serverlessops-catalog/src/routes.ts b/src/plugins/catalog-module-serverlessops/src/routes.ts similarity index 100% rename from src/plugins/serverlessops-catalog/src/routes.ts rename to src/plugins/catalog-module-serverlessops/src/routes.ts diff --git a/src/plugins/serverlessops-catalog/src/setupTests.ts b/src/plugins/catalog-module-serverlessops/src/setupTests.ts similarity index 100% rename from src/plugins/serverlessops-catalog/src/setupTests.ts rename to src/plugins/catalog-module-serverlessops/src/setupTests.ts diff --git a/src/plugins/serverlessops-catalog/dev/index.tsx b/src/plugins/serverlessops-catalog/dev/index.tsx deleted file mode 100644 index 5145933..0000000 --- a/src/plugins/serverlessops-catalog/dev/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import { createDevApp } from '@backstage/frontend-dev-utils' -import serverlessOpsCatalogPlugin from '../src' - -createDevApp({ - features: [serverlessOpsCatalogPlugin], -}) diff --git a/src/plugins/serverlessops-catalog/src/index.ts b/src/plugins/serverlessops-catalog/src/index.ts deleted file mode 100644 index 8f4e6d2..0000000 --- a/src/plugins/serverlessops-catalog/src/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { - SoCatalogTabbedIndexPage, - SoCatalogTabbedDirectoryIndexPage, - serverlessOpsCatalogPlugin as default, -} from './plugin'; diff --git a/src/plugins/serverlessops-catalog/src/plugin.test.ts b/src/plugins/serverlessops-catalog/src/plugin.test.ts deleted file mode 100644 index 89da1f8..0000000 --- a/src/plugins/serverlessops-catalog/src/plugin.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { - SoCatalogTabbedDirectoryIndexPage, - SoCatalogTabbedIndexPage, - serverlessOpsCatalogPlugin, -} from './plugin'; - -describe('catalog', () => { - it('should export plugin SoCatalogTabbedDirectoryIndexPage', () => { - expect(SoCatalogTabbedDirectoryIndexPage).toBeDefined(); - }); - it('should export plugin SoCatalogTabbedIndexPage', () => { - expect(SoCatalogTabbedIndexPage).toBeDefined(); - }); - it('should export default plugin surface', () => { - expect(serverlessOpsCatalogPlugin).toBeDefined(); - }); -}); diff --git a/src/plugins/serverlessops-catalog/src/plugin.tsx b/src/plugins/serverlessops-catalog/src/plugin.tsx deleted file mode 100644 index f0a6ccc..0000000 --- a/src/plugins/serverlessops-catalog/src/plugin.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { createElement } from 'react' -import { - createFrontendPlugin, - createRouteRef, - PageBlueprint, -} from '@backstage/frontend-plugin-api' - -export { TabbedCatalogIndexPage } from './components/TabbedCatalogIndexPage' - -const catalogIndexRouteRef = createRouteRef() -const tabbedCatalogRouteRef = createRouteRef() -const tabbedDirectoryRouteRef = createRouteRef() - -export const SoCatalogTabbedIndexPage = PageBlueprint.make({ - name: 'serverlessops-catalog-tabbed-index', - params: { - path: '/serverlessops-catalog/catalog', - routeRef: tabbedCatalogRouteRef, - loader: () => - import('./components/TabbedCatalogIndexPage').then(m => - createElement(m.TabbedCatalogIndexPage) - ), - }, -}) - -export const SoCatalogTabbedDirectoryIndexPage = PageBlueprint.make({ - name: 'serverlessops-catalog-tabbed-directory-index', - params: { - path: '/serverlessops-catalog/directory', - routeRef: tabbedDirectoryRouteRef, - loader: () => - import('./components/TabbedDirectoryIndexPage').then(m => - createElement(m.TabbedDirectoryIndexPage) - ), - }, -}) - -const serverlessOpsCatalogPlugin = createFrontendPlugin({ - pluginId: 'serverlessops-catalog', - info: { - packageJson: () => require('../../../package.json'), - }, - routes: { - catalogIndex: catalogIndexRouteRef, - tabbedCatalog: tabbedCatalogRouteRef, - tabbedDirectory: tabbedDirectoryRouteRef, - }, - extensions: [ - SoCatalogTabbedIndexPage, - SoCatalogTabbedDirectoryIndexPage, - ], -}) - -export { serverlessOpsCatalogPlugin } \ No newline at end of file diff --git a/src/yarn.lock b/src/yarn.lock index 9a95c55..4c98108 100644 --- a/src/yarn.lock +++ b/src/yarn.lock @@ -5121,6 +5121,43 @@ __metadata: languageName: unknown linkType: soft +"@internal/backstage-plugin-catalog-module-serverlessops@workspace:^, @internal/backstage-plugin-catalog-module-serverlessops@workspace:plugins/catalog-module-serverlessops": + version: 0.0.0-use.local + resolution: "@internal/backstage-plugin-catalog-module-serverlessops@workspace:plugins/catalog-module-serverlessops" + dependencies: + "@backstage/catalog-model": "backstage:^" + "@backstage/cli": "backstage:^" + "@backstage/core-app-api": "backstage:^" + "@backstage/core-components": "backstage:^" + "@backstage/core-plugin-api": "backstage:^" + "@backstage/frontend-dev-utils": "backstage:^" + "@backstage/frontend-plugin-api": "backstage:^" + "@backstage/plugin-api-docs": "backstage:^" + "@backstage/plugin-catalog": "backstage:^" + "@backstage/plugin-catalog-graph": "backstage:^" + "@backstage/plugin-catalog-react": "backstage:^" + "@backstage/plugin-org": "backstage:^" + "@backstage/plugin-techdocs": "backstage:^" + "@backstage/plugin-techdocs-module-addons-contrib": "backstage:^" + "@backstage/plugin-techdocs-react": "backstage:^" + "@backstage/test-utils": "backstage:^" + "@backstage/theme": "backstage:^" + "@backstage/types": "backstage:^" + "@material-ui/core": "npm:^4.9.13" + "@material-ui/icons": "npm:^4.9.1" + "@material-ui/lab": "npm:4.0.0-alpha.61" + "@testing-library/jest-dom": "npm:^6.0.0" + "@testing-library/react": "npm:^14.0.0" + "@testing-library/user-event": "npm:^14.0.0" + msw: "npm:^1.0.0" + react: "npm:^16.13.1 || ^17.0.0 || ^18.0.0" + react-use: "npm:^17.2.4" + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + languageName: unknown + linkType: soft + "@internal/backstage-plugin-scaffolder-backend-module-serverlessops@workspace:^, @internal/backstage-plugin-scaffolder-backend-module-serverlessops@workspace:plugins/scaffolder-backend-module-serverlessops": version: 0.0.0-use.local resolution: "@internal/backstage-plugin-scaffolder-backend-module-serverlessops@workspace:plugins/scaffolder-backend-module-serverlessops" @@ -5164,43 +5201,6 @@ __metadata: languageName: unknown linkType: soft -"@internal/backstage-plugin-serverlessops-catalog@workspace:^, @internal/backstage-plugin-serverlessops-catalog@workspace:plugins/serverlessops-catalog": - version: 0.0.0-use.local - resolution: "@internal/backstage-plugin-serverlessops-catalog@workspace:plugins/serverlessops-catalog" - dependencies: - "@backstage/catalog-model": "backstage:^" - "@backstage/cli": "backstage:^" - "@backstage/core-app-api": "backstage:^" - "@backstage/core-components": "backstage:^" - "@backstage/core-plugin-api": "backstage:^" - "@backstage/frontend-dev-utils": "backstage:^" - "@backstage/frontend-plugin-api": "backstage:^" - "@backstage/plugin-api-docs": "backstage:^" - "@backstage/plugin-catalog": "backstage:^" - "@backstage/plugin-catalog-graph": "backstage:^" - "@backstage/plugin-catalog-react": "backstage:^" - "@backstage/plugin-org": "backstage:^" - "@backstage/plugin-techdocs": "backstage:^" - "@backstage/plugin-techdocs-module-addons-contrib": "backstage:^" - "@backstage/plugin-techdocs-react": "backstage:^" - "@backstage/test-utils": "backstage:^" - "@backstage/theme": "backstage:^" - "@backstage/types": "backstage:^" - "@material-ui/core": "npm:^4.9.13" - "@material-ui/icons": "npm:^4.9.1" - "@material-ui/lab": "npm:4.0.0-alpha.61" - "@testing-library/jest-dom": "npm:^6.0.0" - "@testing-library/react": "npm:^14.0.0" - "@testing-library/user-event": "npm:^14.0.0" - msw: "npm:^1.0.0" - react: "npm:^16.13.1 || ^17.0.0 || ^18.0.0" - react-use: "npm:^17.2.4" - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - languageName: unknown - linkType: soft - "@internationalized/date@npm:^3.12.0, @internationalized/date@npm:^3.12.1, @internationalized/date@npm:^3.12.2": version: 3.12.2 resolution: "@internationalized/date@npm:3.12.2" @@ -12423,8 +12423,8 @@ __metadata: "@backstage/plugin-techdocs-module-addons-contrib": "backstage:^" "@backstage/plugin-user-settings": "backstage:^" "@backstage/ui": "backstage:^" + "@internal/backstage-plugin-catalog-module-serverlessops": "workspace:^" "@internal/backstage-plugin-scaffolder-entity-pickers": "workspace:^" - "@internal/backstage-plugin-serverlessops-catalog": "workspace:^" "@material-ui/core": "npm:^4.12.2" "@material-ui/icons": "npm:^4.9.1" "@playwright/test": "npm:^1.32.3" From 91038a9b1add511f3b9b5d45a753811a2fd0512e Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 2 Jul 2026 21:09:08 -0400 Subject: [PATCH 03/10] make pagination work in our catalog index pages --- src/app-config.yaml | 5 +++- .../catalog-module-serverlessops/package.json | 3 +- .../ApiCatalogIndexPageEntityList.tsx | 3 +- .../ComponentCatalogIndexPageEntityList.tsx | 3 +- .../DomainCatalogIndexPageEntityList.tsx | 3 +- .../LocationCatalogIndexPageEntityList.tsx | 3 +- .../ResourceCatalogIndexPageEntityList.tsx | 3 +- .../SystemCatalogIndexPageEntityList.tsx | 3 +- .../TabbedCatalogIndexPage.tsx | 20 ++++++++----- .../src/module.tsx | 29 +++++++++++++------ src/yarn.lock | 3 +- 11 files changed, 53 insertions(+), 25 deletions(-) diff --git a/src/app-config.yaml b/src/app-config.yaml index 6994143..8931094 100644 --- a/src/app-config.yaml +++ b/src/app-config.yaml @@ -9,7 +9,10 @@ app: # Configure the catalog index page to be the root page, this is normally mounted on /catalog - page:catalog: config: - path: / + pagination: + mode: offset + limit: 20 + #path: / - catalog-filter:catalog/kind: config: initialFilter: domain diff --git a/src/plugins/catalog-module-serverlessops/package.json b/src/plugins/catalog-module-serverlessops/package.json index f7f5471..b60fdc2 100644 --- a/src/plugins/catalog-module-serverlessops/package.json +++ b/src/plugins/catalog-module-serverlessops/package.json @@ -43,7 +43,8 @@ "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", - "react-use": "^17.2.4" + "react-use": "^17.2.4", + "zod": "^4.4.3" }, "peerDependencies": { "react": "^16.13.1 || ^17.0.0 || ^18.0.0", diff --git a/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ApiCatalogIndexPageEntityList.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ApiCatalogIndexPageEntityList.tsx index 178224d..ab131eb 100644 --- a/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ApiCatalogIndexPageEntityList.tsx +++ b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ApiCatalogIndexPageEntityList.tsx @@ -18,7 +18,7 @@ const defaultColumns: TableColumn[] = [ columnFactories.createSpecTypeColumn({ width: 'auto' }), columnFactories.createMetadataDescriptionColumn({ width: 'auto' }), ] -export function ApiCatalogIndexPageEntityList() { +export function ApiCatalogIndexPageEntityList({ pagination }: { pagination?: any }) { return ( ) } \ No newline at end of file diff --git a/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ComponentCatalogIndexPageEntityList.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ComponentCatalogIndexPageEntityList.tsx index 01eab36..6420832 100644 --- a/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ComponentCatalogIndexPageEntityList.tsx +++ b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ComponentCatalogIndexPageEntityList.tsx @@ -18,7 +18,7 @@ const defaultColumns: TableColumn[] = [ columnFactories.createMetadataDescriptionColumn({ width: 'auto' }), ] -export function ComponentCatalogIndexPageEntityList() { +export function ComponentCatalogIndexPageEntityList({ pagination }: { pagination?: any }) { return ( ) } \ No newline at end of file diff --git a/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/DomainCatalogIndexPageEntityList.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/DomainCatalogIndexPageEntityList.tsx index e66db94..074edce 100644 --- a/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/DomainCatalogIndexPageEntityList.tsx +++ b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/DomainCatalogIndexPageEntityList.tsx @@ -16,7 +16,7 @@ const defaultColumns: TableColumn[] = [ columnFactories.createMetadataDescriptionColumn({width: 'auto'}), ] -export function DomainCatalogIndexPageEntityList() { +export function DomainCatalogIndexPageEntityList({ pagination }: { pagination?: any }) { return ( ) } \ No newline at end of file diff --git a/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/LocationCatalogIndexPageEntityList.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/LocationCatalogIndexPageEntityList.tsx index b9ff38c..dc6ac9f 100644 --- a/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/LocationCatalogIndexPageEntityList.tsx +++ b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/LocationCatalogIndexPageEntityList.tsx @@ -7,7 +7,7 @@ import { UserListPicker, } from '@backstage/plugin-catalog-react'; -export function LocationCatalogIndexPageEntityList() { +export function LocationCatalogIndexPageEntityList({ pagination }: { pagination?: any }) { return ( ) } \ No newline at end of file diff --git a/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ResourceCatalogIndexPageEntityList.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ResourceCatalogIndexPageEntityList.tsx index 22ae44f..52ec15f 100644 --- a/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ResourceCatalogIndexPageEntityList.tsx +++ b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/ResourceCatalogIndexPageEntityList.tsx @@ -19,7 +19,7 @@ const defaultColumns: TableColumn[] = [ columnFactories.createMetadataDescriptionColumn({ width: 'auto' }), ] -export function ResourceCatalogIndexPageEntityList() { +export function ResourceCatalogIndexPageEntityList({ pagination }: { pagination?: any }) { return ( ) } \ No newline at end of file diff --git a/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/SystemCatalogIndexPageEntityList.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/SystemCatalogIndexPageEntityList.tsx index 1f489ee..a3c62ae 100644 --- a/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/SystemCatalogIndexPageEntityList.tsx +++ b/src/plugins/catalog-module-serverlessops/src/components/CatalogIndexPageEntityList/SystemCatalogIndexPageEntityList.tsx @@ -18,7 +18,7 @@ const defaultColumns: TableColumn[] = [ // columnFactories.createDomainColumn({ width: 'auto' }), columnFactories.createMetadataDescriptionColumn({ width: 'auto' }), ] -export function SystemCatalogIndexPageEntityList() { +export function SystemCatalogIndexPageEntityList({ pagination }: { pagination?: any }) { return ( ) } \ No newline at end of file diff --git a/src/plugins/catalog-module-serverlessops/src/components/TabbedCatalogIndexPage/TabbedCatalogIndexPage.tsx b/src/plugins/catalog-module-serverlessops/src/components/TabbedCatalogIndexPage/TabbedCatalogIndexPage.tsx index 9b4f919..9de34d9 100644 --- a/src/plugins/catalog-module-serverlessops/src/components/TabbedCatalogIndexPage/TabbedCatalogIndexPage.tsx +++ b/src/plugins/catalog-module-serverlessops/src/components/TabbedCatalogIndexPage/TabbedCatalogIndexPage.tsx @@ -9,8 +9,14 @@ import { SystemCatalogIndexPageEntityList } from '../CatalogIndexPageEntityList'; +type TabbedCatalogIndexPageProps = { + pagination?: { + mode?: 'offset' | 'cursor'; + limit?: number; + }; +}; -export function TabbedCatalogIndexPage() { +export function TabbedCatalogIndexPage({ pagination }: TabbedCatalogIndexPageProps) { const configApi = useApi(configApiRef); const organizationName = @@ -24,22 +30,22 @@ export function TabbedCatalogIndexPage() { > - + - + - + - + - + - + diff --git a/src/plugins/catalog-module-serverlessops/src/module.tsx b/src/plugins/catalog-module-serverlessops/src/module.tsx index 3f1c757..a6525d8 100644 --- a/src/plugins/catalog-module-serverlessops/src/module.tsx +++ b/src/plugins/catalog-module-serverlessops/src/module.tsx @@ -1,4 +1,5 @@ import { UserIcon } from '@backstage/core-components' +import { z } from 'zod' import { createFrontendModule, createRouteRef, @@ -7,15 +8,25 @@ import { const tabbedDirectoryRouteRef = createRouteRef() -export const SoCatalogTabbedIndexPage = PageBlueprint.make({ - params: { - path: '/catalog', - routeRef: createRouteRef({ aliasFor: 'catalog.catalogIndex' }), - loader: async () => { - const { TabbedCatalogIndexPage } = await import('./components/TabbedCatalogIndexPage') - return < TabbedCatalogIndexPage /> - } - } +export const SoCatalogTabbedIndexPage = PageBlueprint.makeWithOverrides({ + configSchema: { + pagination: z + .object({ + mode: z.enum(['offset', 'cursor']).optional(), + limit: z.number().optional(), + }) + .optional(), + }, + factory(originalFactory, { config }) { + return originalFactory({ + path: '/catalog', + routeRef: createRouteRef({ aliasFor: 'catalog.catalogIndex' }), + loader: async () => { + const { TabbedCatalogIndexPage } = await import('./components/TabbedCatalogIndexPage') + return + }, + }) + }, }) export const SoCatalogTabbedDirectoryIndexPage = PageBlueprint.make({ diff --git a/src/yarn.lock b/src/yarn.lock index 4c98108..a409ed5 100644 --- a/src/yarn.lock +++ b/src/yarn.lock @@ -5152,6 +5152,7 @@ __metadata: msw: "npm:^1.0.0" react: "npm:^16.13.1 || ^17.0.0 || ^18.0.0" react-use: "npm:^17.2.4" + zod: "npm:^4.4.3" peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 @@ -31562,7 +31563,7 @@ __metadata: languageName: node linkType: hard -"zod@npm:^3.25 || ^4.0, zod@npm:^3.25.76 || ^4.0.0, zod@npm:^4.0.0": +"zod@npm:^3.25 || ^4.0, zod@npm:^3.25.76 || ^4.0.0, zod@npm:^4.0.0, zod@npm:^4.4.3": version: 4.4.3 resolution: "zod@npm:4.4.3" checksum: 10c0/7ea31b558e88f9faf44f31dd185e2e1cbf51fed3081787fb96cc2534749b50c0acfc6da7f0922a7353ed092dd358c7d50c28ea96c94d04af64191bd33152eca3 From c0d710950200cd5b9571f23cc87ff356b698e94c Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 3 Jul 2026 18:10:13 -0400 Subject: [PATCH 04/10] Add support for GitHub related plugins --- cfn-parameters.json | 2 ++ src/app-config.production.yaml | 7 +++++++ template.yaml | 14 ++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/cfn-parameters.json b/cfn-parameters.json index 03508f8..2b85f54 100644 --- a/cfn-parameters.json +++ b/cfn-parameters.json @@ -28,6 +28,8 @@ "PgPassword": $secrets.POSTGRES_PASSWORD, "AuthGoogleClientId": $secrets.AUTH_GOOGLE_CLIENT_ID, "AuthGoogleClientSecret": $secrets.AUTH_GOOGLE_CLIENT_SECRET, + "AuthGithubClientId": $secrets.AUTH_GITHUB_CLIENT_ID, + "AuthGithubClientSecret": $secrets.AUTH_GITHUB_CLIENT_SECRET, "BackstageAppUrl": $vars.BACKSTAGE_APP_URL, "BackstageBackendUrl": $vars.BACKSTAGE_BACKEND_URL, "ServerlessOpsCatalogApiUrl": $vars.SERVERLESSOPS_CATALOG_API_URL, diff --git a/src/app-config.production.yaml b/src/app-config.production.yaml index 954ac2d..84479a9 100644 --- a/src/app-config.production.yaml +++ b/src/app-config.production.yaml @@ -47,6 +47,13 @@ auth: - resolver: emailMatchingUserEntityProfileEmail - resolver: emailLocalPartMatchingUserEntityName - resolver: emailMatchingUserEntityAnnotation + github: + production: + clientId: ${AUTH_GITHUB_CLIENT_ID} + clientSecret: ${AUTH_GITHUB_CLIENT_SECRET} + signIn: + resolvers: + - resolver: emailMatchingUserEntityProfileEmail integrations: github: diff --git a/template.yaml b/template.yaml index 54e5ee5..1613dfb 100644 --- a/template.yaml +++ b/template.yaml @@ -129,6 +129,16 @@ Parameters: Description: Google OAuth client secret NoEcho: true + AuthGithubClientId: + Type: String + Description: GitHub OAuth client ID + NoEcho: true + + AuthGithubClientSecret: + Type: String + Description: GitHub OAuth client secret + NoEcho: true + BackstageAppUrl: Type: String Description: URL of application frontend @@ -188,6 +198,10 @@ Resources: Value: !Ref AuthGoogleClientId - Name: AUTH_GOOGLE_CLIENT_SECRET Value: !Ref AuthGoogleClientSecret + - Name: AUTH_GITHUB_CLIENT_ID + Value: !Ref AuthGithubClientId + - Name: AUTH_GITHUB_CLIENT_SECRET + Value: !Ref AuthGithubClientSecret - Name: BACKSTAGE_APP_URL Value: !Ref BackstageAppUrl - Name: BACKSTAGE_BACKEND_URL From c4211a35da699128a234054805d25692d5368eaa Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 3 Jul 2026 18:13:04 -0400 Subject: [PATCH 05/10] Add GitHub Actions Plugin --- src/packages/app/package.json | 1 + src/packages/app/src/App.tsx | 8 ++++++- src/yarn.lock | 45 +++++++++++++++++++++++++++++++++-- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/packages/app/package.json b/src/packages/app/package.json index e94b66f..9a15143 100644 --- a/src/packages/app/package.json +++ b/src/packages/app/package.json @@ -14,6 +14,7 @@ "lint": "backstage-cli package lint" }, "dependencies": { + "@backstage-community/plugin-github-actions": "^1.2.0", "@backstage/cli": "backstage:^", "@backstage/core-components": "backstage:^", "@backstage/core-plugin-api": "backstage:^", diff --git a/src/packages/app/src/App.tsx b/src/packages/app/src/App.tsx index 07c87c1..6ae79a6 100644 --- a/src/packages/app/src/App.tsx +++ b/src/packages/app/src/App.tsx @@ -1,12 +1,17 @@ import { createApp } from '@backstage/frontend-defaults'; import catalogPlugin from '@backstage/plugin-catalog/alpha'; -import serverlessOpsCatalogModule from '@internal/backstage-plugin-catalog-module-serverlessops'; import { navModule } from './modules/nav'; import { configApiRef, googleAuthApiRef, useApi } from '@backstage/core-plugin-api'; import { SignInPageBlueprint } from '@backstage/plugin-app-react'; import { SignInPage } from '@backstage/core-components'; import { createFrontendModule } from '@backstage/frontend-plugin-api'; +// external plugins +import githubActionsPlugin from '@backstage-community/plugin-github-actions/alpha'; + +// local plugins +import serverlessOpsCatalogModule from '@internal/backstage-plugin-catalog-module-serverlessops'; + const signInPage = SignInPageBlueprint.make({ params: { loader: async () => props => { @@ -48,6 +53,7 @@ export default createApp({ features: [ catalogPlugin, navModule, + githubActionsPlugin, serverlessOpsCatalogModule, createFrontendModule({ pluginId: 'app', diff --git a/src/yarn.lock b/src/yarn.lock index a409ed5..9acbd78 100644 --- a/src/yarn.lock +++ b/src/yarn.lock @@ -1232,6 +1232,37 @@ __metadata: languageName: node linkType: hard +"@backstage-community/plugin-github-actions@npm:^1.2.0": + version: 1.2.0 + resolution: "@backstage-community/plugin-github-actions@npm:1.2.0" + dependencies: + "@backstage/catalog-model": "npm:^1.9.0" + "@backstage/core-compat-api": "npm:^0.5.12" + "@backstage/core-components": "npm:^0.18.11" + "@backstage/core-plugin-api": "npm:^1.12.7" + "@backstage/frontend-plugin-api": "npm:^0.17.2" + "@backstage/integration": "npm:^2.0.3" + "@backstage/integration-react": "npm:^1.2.19" + "@backstage/plugin-catalog-react": "npm:^3.1.0" + "@backstage/ui": "npm:^0.16.0" + "@material-ui/core": "npm:^4.12.2" + "@material-ui/lab": "npm:4.0.0-alpha.61" + "@octokit/rest": "npm:^19.0.3" + "@remixicon/react": "npm:^4.2.0" + "@types/react": "npm:^16.13.1 || ^17.0.0 || ^18.0.0" + git-url-parse: "npm:^14.0.0" + luxon: "npm:^3.0.0" + react-aria-components: "npm:^1.3.0" + react-use: "npm:^17.2.4" + zod: "npm:^4.0.0" + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: 10c0/dc02afa6552a48bc3ca671976b8f80d32c98a6da74a48325c14c57190aa923fb0faeb6c00008bd0b870a4355fa85bfd3dcf7512a77820a301d0a744b5ad039cb + languageName: node + linkType: hard + "@backstage/backend-app-api@npm:^1.7.1": version: 1.7.1 resolution: "@backstage/backend-app-api@npm:1.7.1" @@ -8466,7 +8497,7 @@ __metadata: languageName: node linkType: hard -"@remixicon/react@npm:^4.6.0": +"@remixicon/react@npm:^4.2.0, @remixicon/react@npm:^4.6.0": version: 4.9.0 resolution: "@remixicon/react@npm:4.9.0" peerDependencies: @@ -12400,6 +12431,7 @@ __metadata: version: 0.0.0-use.local resolution: "app@workspace:packages/app" dependencies: + "@backstage-community/plugin-github-actions": "npm:^1.2.0" "@backstage/cli": "backstage:^" "@backstage/core-components": "backstage:^" "@backstage/core-plugin-api": "backstage:^" @@ -18167,6 +18199,15 @@ __metadata: languageName: node linkType: hard +"git-url-parse@npm:^14.0.0": + version: 14.1.0 + resolution: "git-url-parse@npm:14.1.0" + dependencies: + git-up: "npm:^7.0.0" + checksum: 10c0/cd91547210eccdfaca92c41c5ab018c23a75e881f36aa8d7c46cef8e10dea790a455aeb4ca91426109fd5f645c6e874c0cf80a38be6a8675ed91abb08ed904d4 + languageName: node + linkType: hard + "git-url-parse@npm:^15.0.0": version: 15.0.0 resolution: "git-url-parse@npm:15.0.0" @@ -26116,7 +26157,7 @@ __metadata: languageName: node linkType: hard -"react-aria-components@npm:^1.14.0": +"react-aria-components@npm:^1.14.0, react-aria-components@npm:^1.3.0": version: 1.19.0 resolution: "react-aria-components@npm:1.19.0" dependencies: From a123616476bf277b87a3dfd4b93322ec69ba8a09 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 3 Jul 2026 18:20:41 -0400 Subject: [PATCH 06/10] Add Github deployments plugin --- src/packages/app/package.json | 1 + src/packages/app/src/App.tsx | 2 ++ src/yarn.lock | 28 ++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/src/packages/app/package.json b/src/packages/app/package.json index 9a15143..6cc9a1f 100644 --- a/src/packages/app/package.json +++ b/src/packages/app/package.json @@ -15,6 +15,7 @@ }, "dependencies": { "@backstage-community/plugin-github-actions": "^1.2.0", + "@backstage-community/plugin-github-deployments": "^1.2.0", "@backstage/cli": "backstage:^", "@backstage/core-components": "backstage:^", "@backstage/core-plugin-api": "backstage:^", diff --git a/src/packages/app/src/App.tsx b/src/packages/app/src/App.tsx index 6ae79a6..baed1a6 100644 --- a/src/packages/app/src/App.tsx +++ b/src/packages/app/src/App.tsx @@ -8,6 +8,7 @@ import { createFrontendModule } from '@backstage/frontend-plugin-api'; // external plugins import githubActionsPlugin from '@backstage-community/plugin-github-actions/alpha'; +import githubDeploymentsPlugin from '@backstage-community/plugin-github-deployments/alpha'; // local plugins import serverlessOpsCatalogModule from '@internal/backstage-plugin-catalog-module-serverlessops'; @@ -54,6 +55,7 @@ export default createApp({ catalogPlugin, navModule, githubActionsPlugin, + githubDeploymentsPlugin, serverlessOpsCatalogModule, createFrontendModule({ pluginId: 'app', diff --git a/src/yarn.lock b/src/yarn.lock index 9acbd78..967be1b 100644 --- a/src/yarn.lock +++ b/src/yarn.lock @@ -1263,6 +1263,33 @@ __metadata: languageName: node linkType: hard +"@backstage-community/plugin-github-deployments@npm:^1.2.0": + version: 1.2.0 + resolution: "@backstage-community/plugin-github-deployments@npm:1.2.0" + dependencies: + "@backstage/catalog-model": "npm:^1.9.0" + "@backstage/core-compat-api": "npm:^0.5.12" + "@backstage/core-components": "npm:^0.18.11" + "@backstage/core-plugin-api": "npm:^1.12.7" + "@backstage/errors": "npm:^1.3.1" + "@backstage/frontend-plugin-api": "npm:^0.17.2" + "@backstage/integration": "npm:^2.0.3" + "@backstage/integration-react": "npm:^1.2.19" + "@backstage/plugin-catalog-react": "npm:^3.1.0" + "@backstage/ui": "npm:^0.16.0" + "@octokit/graphql": "npm:^5.0.0" + "@remixicon/react": "npm:^4.2.0" + "@types/react": "npm:^16.13.1 || ^17.0.0 || ^18.0.0" + luxon: "npm:^3.0.0" + react-use: "npm:^17.2.4" + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: 10c0/e47a8077d7aa4df240a0cd11372d2c368a4fcd94d6964b7235ae91459ce530baf7aa4f3e77c23c20703fef1b3db5059f65e48ac0d2c1998dc191125c851438fc + languageName: node + linkType: hard + "@backstage/backend-app-api@npm:^1.7.1": version: 1.7.1 resolution: "@backstage/backend-app-api@npm:1.7.1" @@ -12432,6 +12459,7 @@ __metadata: resolution: "app@workspace:packages/app" dependencies: "@backstage-community/plugin-github-actions": "npm:^1.2.0" + "@backstage-community/plugin-github-deployments": "npm:^1.2.0" "@backstage/cli": "backstage:^" "@backstage/core-components": "backstage:^" "@backstage/core-plugin-api": "backstage:^" From 25d6fc472eb715a250b73a0561e5890eef42e2ed Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 3 Jul 2026 18:23:32 -0400 Subject: [PATCH 07/10] Add GitHub issues plugin --- src/packages/app/package.json | 1 + src/packages/app/src/App.tsx | 2 ++ src/yarn.lock | 32 +++++++++++++++++++++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/packages/app/package.json b/src/packages/app/package.json index 6cc9a1f..5bc9e7c 100644 --- a/src/packages/app/package.json +++ b/src/packages/app/package.json @@ -16,6 +16,7 @@ "dependencies": { "@backstage-community/plugin-github-actions": "^1.2.0", "@backstage-community/plugin-github-deployments": "^1.2.0", + "@backstage-community/plugin-github-issues": "^1.2.1", "@backstage/cli": "backstage:^", "@backstage/core-components": "backstage:^", "@backstage/core-plugin-api": "backstage:^", diff --git a/src/packages/app/src/App.tsx b/src/packages/app/src/App.tsx index baed1a6..e796c0c 100644 --- a/src/packages/app/src/App.tsx +++ b/src/packages/app/src/App.tsx @@ -9,6 +9,7 @@ import { createFrontendModule } from '@backstage/frontend-plugin-api'; // external plugins import githubActionsPlugin from '@backstage-community/plugin-github-actions/alpha'; import githubDeploymentsPlugin from '@backstage-community/plugin-github-deployments/alpha'; +import githubIssuesPlugin from '@backstage-community/plugin-github-issues/alpha'; // local plugins import serverlessOpsCatalogModule from '@internal/backstage-plugin-catalog-module-serverlessops'; @@ -56,6 +57,7 @@ export default createApp({ navModule, githubActionsPlugin, githubDeploymentsPlugin, + githubIssuesPlugin, serverlessOpsCatalogModule, createFrontendModule({ pluginId: 'app', diff --git a/src/yarn.lock b/src/yarn.lock index 967be1b..4473769 100644 --- a/src/yarn.lock +++ b/src/yarn.lock @@ -1290,6 +1290,35 @@ __metadata: languageName: node linkType: hard +"@backstage-community/plugin-github-issues@npm:^1.2.1": + version: 1.2.1 + resolution: "@backstage-community/plugin-github-issues@npm:1.2.1" + dependencies: + "@backstage/catalog-model": "npm:^1.9.0" + "@backstage/core-compat-api": "npm:^0.5.12" + "@backstage/core-components": "npm:^0.18.11" + "@backstage/core-plugin-api": "npm:^1.12.7" + "@backstage/errors": "npm:^1.3.1" + "@backstage/frontend-plugin-api": "npm:^0.17.2" + "@backstage/integration": "npm:^2.0.3" + "@backstage/integration-react": "npm:^1.2.19" + "@backstage/plugin-catalog-react": "npm:^3.1.0" + "@backstage/ui": "npm:^0.16.0" + "@material-ui/core": "npm:^4.12.4" + "@material-ui/lab": "npm:4.0.0-alpha.61" + "@remixicon/react": "npm:^4.2.0" + "@types/react": "npm:^16.13.1 || ^17.0.0 || ^18.0.0" + luxon: "npm:^3.0.0" + octokit: "npm:^3.0.0" + react-use: "npm:^17.4.0" + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: 10c0/33ea79713db40058c57315238b8a838aff3baf9054a8fe15986f03eb2bd4fffa39a3c961ea338b89a0bb715694cb2800e4668920e39b3e90753a38f7a4d323c7 + languageName: node + linkType: hard + "@backstage/backend-app-api@npm:^1.7.1": version: 1.7.1 resolution: "@backstage/backend-app-api@npm:1.7.1" @@ -12460,6 +12489,7 @@ __metadata: dependencies: "@backstage-community/plugin-github-actions": "npm:^1.2.0" "@backstage-community/plugin-github-deployments": "npm:^1.2.0" + "@backstage-community/plugin-github-issues": "npm:^1.2.1" "@backstage/cli": "backstage:^" "@backstage/core-components": "backstage:^" "@backstage/core-plugin-api": "backstage:^" @@ -26794,7 +26824,7 @@ __metadata: languageName: node linkType: hard -"react-use@npm:^17.2.4, react-use@npm:^17.3.2, react-use@npm:^17.5.1": +"react-use@npm:^17.2.4, react-use@npm:^17.3.2, react-use@npm:^17.4.0, react-use@npm:^17.5.1": version: 17.6.1 resolution: "react-use@npm:17.6.1" dependencies: From ddf4351886243a272f2a8f2fbaec46135be8b11f Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Sat, 4 Jul 2026 15:10:20 -0400 Subject: [PATCH 08/10] explicitly configure some entity content --- src/app-config.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/app-config.yaml b/src/app-config.yaml index 8931094..b84f7f5 100644 --- a/src/app-config.yaml +++ b/src/app-config.yaml @@ -19,6 +19,27 @@ app: - catalog-filter:catalog/list: config: initialFilter: all + + # Catalog page tabs + - page:catalog/entity: + config: + showNavItemIcons: true + - entity-content:catalog/overview: + config: + icon: catalog + group: false + - entity-content:api-docs/definition: + config: + icon: kind:api + group: false + - entity-content:api-docs/apis: + config: + icon: kind:api + group: false + - entity-content:techdocs: + config: + icon: techdocs + group: false - sub-page:scaffolder/templates: config: groups: From 4f6cf66ca5b480817ea2943836410778a7ee88d1 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Sat, 4 Jul 2026 15:15:20 -0400 Subject: [PATCH 09/10] add CI/CD entity page. based off of * @backstage-community/plugin-github-actions * @backstage-community/plugin-github-deployments --- src/app-config.yaml | 8 +++ .../CicdCatalogEntityContent.tsx | 54 +++++++++++++++++++ .../catalog-module-serverlessops/src/index.ts | 1 + .../src/module.tsx | 20 ++++++- 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/plugins/catalog-module-serverlessops/src/components/CatalogEntityContent/CicdCatalogEntityContent.tsx diff --git a/src/app-config.yaml b/src/app-config.yaml index b84f7f5..05dcce2 100644 --- a/src/app-config.yaml +++ b/src/app-config.yaml @@ -40,6 +40,14 @@ app: config: icon: techdocs group: false + # NOTE: Setting `disabled: true` causes to hide the page causes crashes. I assume it's + # related to not being fully ported to the new frontend system at the current time. As a + # result we're using this filter that will always fails. + - entity-content:github-actions: + config: + filter: + kind: false + - sub-page:scaffolder/templates: config: groups: diff --git a/src/plugins/catalog-module-serverlessops/src/components/CatalogEntityContent/CicdCatalogEntityContent.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogEntityContent/CicdCatalogEntityContent.tsx new file mode 100644 index 0000000..b60c4e3 --- /dev/null +++ b/src/plugins/catalog-module-serverlessops/src/components/CatalogEntityContent/CicdCatalogEntityContent.tsx @@ -0,0 +1,54 @@ +import { + useEntity, + MissingAnnotationEmptyState, +} from '@backstage/plugin-catalog-react'; +import { Grid, Typography } from '@material-ui/core'; +import { + EntityLatestGithubActionRunCard, + EntityRecentGithubActionsRunsCard, + isGithubActionsAvailable +} from '@backstage-community/plugin-github-actions'; +import { EntityGithubDeploymentsCard } from '@backstage-community/plugin-github-deployments'; + +export const CicdCatalogEntityContent = () => { + const { entity } = useEntity(); + if (!isGithubActionsAvailable(entity)) { + return ( + + ); + } + + return ( + + + Build + + + + + + + + Main branch + + + + + + + All branches + + + + + + + Deploy + + + + + + + ); +}; \ No newline at end of file diff --git a/src/plugins/catalog-module-serverlessops/src/index.ts b/src/plugins/catalog-module-serverlessops/src/index.ts index d08f350..8886024 100644 --- a/src/plugins/catalog-module-serverlessops/src/index.ts +++ b/src/plugins/catalog-module-serverlessops/src/index.ts @@ -1,3 +1,4 @@ export { + SoCicdCatalogEntityContent, serverlessOpsCatalogModule as default, } from './module'; diff --git a/src/plugins/catalog-module-serverlessops/src/module.tsx b/src/plugins/catalog-module-serverlessops/src/module.tsx index a6525d8..132381d 100644 --- a/src/plugins/catalog-module-serverlessops/src/module.tsx +++ b/src/plugins/catalog-module-serverlessops/src/module.tsx @@ -1,4 +1,5 @@ -import { UserIcon } from '@backstage/core-components' +import { EntityContentBlueprint } from '@backstage/plugin-catalog-react/alpha'; +import { GitHubIcon, UserIcon } from '@backstage/core-components' import { z } from 'zod' import { createFrontendModule, @@ -6,8 +7,24 @@ import { PageBlueprint, } from '@backstage/frontend-plugin-api' +const cicdRouteRef = createRouteRef() const tabbedDirectoryRouteRef = createRouteRef() +export const SoCicdCatalogEntityContent = EntityContentBlueprint.make({ + name: 'cicd', + params: { + path: 'cicd', + title: 'CI/CD', + filter: 'kind:component', + icon: , + routeRef: cicdRouteRef, + loader: async () => { + const { CicdCatalogEntityContent } = await import('./components/CatalogEntityContent/CicdCatalogEntityContent') + return + } + }, +}) + export const SoCatalogTabbedIndexPage = PageBlueprint.makeWithOverrides({ configSchema: { pagination: z @@ -48,5 +65,6 @@ export const serverlessOpsCatalogModule = createFrontendModule({ extensions: [ SoCatalogTabbedIndexPage, SoCatalogTabbedDirectoryIndexPage, + SoCicdCatalogEntityContent, ] }); From fbd76e438635edc298d780833fdad02051778ad4 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Sat, 4 Jul 2026 17:35:39 -0400 Subject: [PATCH 10/10] add entity activity page It shows issues but not PRs because @roadiehq/backstage-plugin-github-pull-requests hasn't released a version that supports the new frontend system --- src/app-config.yaml | 2 ++ src/packages/app/src/App.tsx | 1 - .../catalog-module-serverlessops/package.json | 1 + .../ActivityCatalogEntityContent.tsx | 13 +++++++++++++ .../catalog-module-serverlessops/src/index.ts | 1 + .../src/module.tsx | 18 ++++++++++++++++++ src/yarn.lock | 3 ++- 7 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 src/plugins/catalog-module-serverlessops/src/components/CatalogEntityContent/ActivityCatalogEntityContent.tsx diff --git a/src/app-config.yaml b/src/app-config.yaml index 05dcce2..ee8252f 100644 --- a/src/app-config.yaml +++ b/src/app-config.yaml @@ -47,6 +47,8 @@ app: config: filter: kind: false + - entity-content:github-issues/entity: + disabled: true - sub-page:scaffolder/templates: config: diff --git a/src/packages/app/src/App.tsx b/src/packages/app/src/App.tsx index e796c0c..3758a66 100644 --- a/src/packages/app/src/App.tsx +++ b/src/packages/app/src/App.tsx @@ -10,7 +10,6 @@ import { createFrontendModule } from '@backstage/frontend-plugin-api'; import githubActionsPlugin from '@backstage-community/plugin-github-actions/alpha'; import githubDeploymentsPlugin from '@backstage-community/plugin-github-deployments/alpha'; import githubIssuesPlugin from '@backstage-community/plugin-github-issues/alpha'; - // local plugins import serverlessOpsCatalogModule from '@internal/backstage-plugin-catalog-module-serverlessops'; diff --git a/src/plugins/catalog-module-serverlessops/package.json b/src/plugins/catalog-module-serverlessops/package.json index b60fdc2..b539135 100644 --- a/src/plugins/catalog-module-serverlessops/package.json +++ b/src/plugins/catalog-module-serverlessops/package.json @@ -43,6 +43,7 @@ "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", + "@remixicon/react": "^4.9.0", "react-use": "^17.2.4", "zod": "^4.4.3" }, diff --git a/src/plugins/catalog-module-serverlessops/src/components/CatalogEntityContent/ActivityCatalogEntityContent.tsx b/src/plugins/catalog-module-serverlessops/src/components/CatalogEntityContent/ActivityCatalogEntityContent.tsx new file mode 100644 index 0000000..1143a7e --- /dev/null +++ b/src/plugins/catalog-module-serverlessops/src/components/CatalogEntityContent/ActivityCatalogEntityContent.tsx @@ -0,0 +1,13 @@ +import { Grid } from '@material-ui/core'; +import { GithubIssuesCard } from '@backstage-community/plugin-github-issues' + +export const ActivityCatalogEntityContent = () => { + + return ( + + + + + + ); +}; \ No newline at end of file diff --git a/src/plugins/catalog-module-serverlessops/src/index.ts b/src/plugins/catalog-module-serverlessops/src/index.ts index 8886024..f941130 100644 --- a/src/plugins/catalog-module-serverlessops/src/index.ts +++ b/src/plugins/catalog-module-serverlessops/src/index.ts @@ -1,4 +1,5 @@ export { + SoActivityCatalogEntityContent, SoCicdCatalogEntityContent, serverlessOpsCatalogModule as default, } from './module'; diff --git a/src/plugins/catalog-module-serverlessops/src/module.tsx b/src/plugins/catalog-module-serverlessops/src/module.tsx index 132381d..a20955d 100644 --- a/src/plugins/catalog-module-serverlessops/src/module.tsx +++ b/src/plugins/catalog-module-serverlessops/src/module.tsx @@ -6,8 +6,10 @@ import { createRouteRef, PageBlueprint, } from '@backstage/frontend-plugin-api' +import { RiGitPullRequestLine } from "@remixicon/react" const cicdRouteRef = createRouteRef() +const activityRouteRef = createRouteRef() const tabbedDirectoryRouteRef = createRouteRef() export const SoCicdCatalogEntityContent = EntityContentBlueprint.make({ @@ -25,6 +27,21 @@ export const SoCicdCatalogEntityContent = EntityContentBlueprint.make({ }, }) +export const SoActivityCatalogEntityContent = EntityContentBlueprint.make({ + name: 'activity', + params: { + path: 'activity', + title: 'Activity', + filter: 'kind:component', + icon: , + routeRef: activityRouteRef, + loader: async () => { + const { ActivityCatalogEntityContent } = await import('./components/CatalogEntityContent/ActivityCatalogEntityContent') + return + } + }, +}) + export const SoCatalogTabbedIndexPage = PageBlueprint.makeWithOverrides({ configSchema: { pagination: z @@ -65,6 +82,7 @@ export const serverlessOpsCatalogModule = createFrontendModule({ extensions: [ SoCatalogTabbedIndexPage, SoCatalogTabbedDirectoryIndexPage, + SoActivityCatalogEntityContent, SoCicdCatalogEntityContent, ] }); diff --git a/src/yarn.lock b/src/yarn.lock index 4473769..e312db9 100644 --- a/src/yarn.lock +++ b/src/yarn.lock @@ -5233,6 +5233,7 @@ __metadata: "@material-ui/core": "npm:^4.9.13" "@material-ui/icons": "npm:^4.9.1" "@material-ui/lab": "npm:4.0.0-alpha.61" + "@remixicon/react": "npm:^4.9.0" "@testing-library/jest-dom": "npm:^6.0.0" "@testing-library/react": "npm:^14.0.0" "@testing-library/user-event": "npm:^14.0.0" @@ -8553,7 +8554,7 @@ __metadata: languageName: node linkType: hard -"@remixicon/react@npm:^4.2.0, @remixicon/react@npm:^4.6.0": +"@remixicon/react@npm:^4.2.0, @remixicon/react@npm:^4.6.0, @remixicon/react@npm:^4.9.0": version: 4.9.0 resolution: "@remixicon/react@npm:4.9.0" peerDependencies: