diff --git a/.changeset/bigint-convert.md b/.changeset/bigint-convert.md index 7b07297ad3..fed91ad2c1 100644 --- a/.changeset/bigint-convert.md +++ b/.changeset/bigint-convert.md @@ -1,5 +1,5 @@ --- -'@backstage/kubernetes-react': patch +'@backstage/plugin-kubernetes-react': patch --- Fixed bug in string-to-integer conversion to properly handle decimal values with BigInt. diff --git a/.changeset/create-app-1737468383.md b/.changeset/create-app-1737468383.md new file mode 100644 index 0000000000..b50d431d4b --- /dev/null +++ b/.changeset/create-app-1737468383.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Bumped create-app version. diff --git a/.changeset/eight-cougars-collect-due.md b/.changeset/eight-cougars-collect-due.md new file mode 100644 index 0000000000..ff997f876a --- /dev/null +++ b/.changeset/eight-cougars-collect-due.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-kubernetes-cluster': patch +'@backstage/plugin-kubernetes-react': patch +--- + +Improved rendering of Kubernetes resources' metadata. diff --git a/.changeset/eight-cougars-collect.md b/.changeset/eight-cougars-collect.md new file mode 100644 index 0000000000..edaa18d826 --- /dev/null +++ b/.changeset/eight-cougars-collect.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Added `nestedValuesAsYaml` option to `StructuredMetadataTable` to render data as yaml. diff --git a/.changeset/eleven-mice-sleep.md b/.changeset/eleven-mice-sleep.md new file mode 100644 index 0000000000..d1b14aa098 --- /dev/null +++ b/.changeset/eleven-mice-sleep.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Ignore benign database conflict errors during stitching, now logged with debug level instead. diff --git a/.changeset/fair-rocks-dream.md b/.changeset/fair-rocks-dream.md new file mode 100644 index 0000000000..d1f7f3f0f7 --- /dev/null +++ b/.changeset/fair-rocks-dream.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Fixed an issue where invalid expressions or non-object values in `step.each` caused an error. diff --git a/.changeset/few-shrimps-kiss.md b/.changeset/few-shrimps-kiss.md new file mode 100644 index 0000000000..8135ade1b7 --- /dev/null +++ b/.changeset/few-shrimps-kiss.md @@ -0,0 +1,5 @@ +--- +'@backstage/canon': minor +--- + +This is the first alpha release for Canon. As part of this release we are introducing 5 layout components and 7 components. All theming is done through CSS variables. diff --git a/.changeset/fifty-turtles-count.md b/.changeset/fifty-turtles-count.md new file mode 100644 index 0000000000..76bea0dcaa --- /dev/null +++ b/.changeset/fifty-turtles-count.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Add missing route ref to the `/alpha` entity content extension. diff --git a/.changeset/grumpy-crews-sneeze.md b/.changeset/grumpy-crews-sneeze.md new file mode 100644 index 0000000000..92aeff14a8 --- /dev/null +++ b/.changeset/grumpy-crews-sneeze.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +The log message written when plugins fail to initialize now includes the error that caused the plugin startup to fail. diff --git a/.changeset/neat-singers-rhyme.md b/.changeset/neat-singers-rhyme.md new file mode 100644 index 0000000000..5c12339d84 --- /dev/null +++ b/.changeset/neat-singers-rhyme.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Fixed the file path pattern of many static assets output as part of the frontend build process, where there was an extra `.` before the extension, leading to names like `image-af7946b..png`. diff --git a/.changeset/odd-countries-vanish.md b/.changeset/odd-countries-vanish.md new file mode 100644 index 0000000000..4d56b1fdeb --- /dev/null +++ b/.changeset/odd-countries-vanish.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-ldap': patch +--- + +Make `ldapOrg` config key optional diff --git a/.changeset/olive-boxes-hide-backend-defaults.md b/.changeset/olive-boxes-hide-backend-defaults.md new file mode 100644 index 0000000000..9d4ff05f17 --- /dev/null +++ b/.changeset/olive-boxes-hide-backend-defaults.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': minor +--- + +This change introduces the `auditor` service implementation details. diff --git a/.changeset/olive-boxes-hide-backend-plugin-api.md b/.changeset/olive-boxes-hide-backend-plugin-api.md new file mode 100644 index 0000000000..32e4d41813 --- /dev/null +++ b/.changeset/olive-boxes-hide-backend-plugin-api.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-plugin-api': minor +--- + +This change introduces the `auditor` service definition. diff --git a/.changeset/olive-boxes-hide-backend-test-utils.md b/.changeset/olive-boxes-hide-backend-test-utils.md new file mode 100644 index 0000000000..41b2016f5d --- /dev/null +++ b/.changeset/olive-boxes-hide-backend-test-utils.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-test-utils': minor +--- + +This change introduces mocks for the `auditor` service. diff --git a/.changeset/olive-boxes-hide-catalog-backend.md b/.changeset/olive-boxes-hide-catalog-backend.md new file mode 100644 index 0000000000..09d88bf6e2 --- /dev/null +++ b/.changeset/olive-boxes-hide-catalog-backend.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': minor +--- + +This change integrates the `auditor` service into the Catalog plugin. diff --git a/.changeset/olive-boxes-hide-scaffolder-backend.md b/.changeset/olive-boxes-hide-scaffolder-backend.md new file mode 100644 index 0000000000..be67064091 --- /dev/null +++ b/.changeset/olive-boxes-hide-scaffolder-backend.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': minor +--- + +This change integrates the `auditor` service into the Scaffolder plugin. diff --git a/.changeset/olive-boxes-hide-scaffolder-node.md b/.changeset/olive-boxes-hide-scaffolder-node.md new file mode 100644 index 0000000000..f3c18f0991 --- /dev/null +++ b/.changeset/olive-boxes-hide-scaffolder-node.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-node': minor +--- + +This change introduces an optional `taskId` property to `TaskContext`. diff --git a/.changeset/pre.json b/.changeset/pre.json index b5c8383e80..46e41b0c24 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -196,5 +196,45 @@ "@backstage/plugin-user-settings-backend": "0.2.29", "@backstage/plugin-user-settings-common": "0.0.1" }, - "changesets": [] + "changesets": [ + "afraid-experts-explain", + "afraid-kids-jog", + "beige-dingos-destroy", + "bigint-convert", + "clean-squids-build", + "create-app-1737468383", + "curly-humans-prove", + "curvy-ways-play", + "cyan-grapes-confess", + "dry-flies-rhyme", + "dry-horses-report", + "eleven-mice-sleep", + "fair-mangos-sleep", + "few-shrimps-kiss", + "gentle-actors-sleep", + "green-jokes-provide", + "hungry-mirrors-sniff", + "loud-walls-build", + "old-moons-end", + "old-phones-rest", + "olive-boxes-hide-backend-defaults", + "olive-boxes-hide-backend-plugin-api", + "olive-boxes-hide-backend-test-utils", + "olive-boxes-hide-catalog-backend", + "olive-boxes-hide-scaffolder-backend", + "olive-boxes-hide-scaffolder-node", + "orange-brooms-lick", + "proud-dryers-act", + "proud-hornets-cheer", + "quiet-phones-sell", + "sharp-vans-protect", + "sharp-years-drive", + "short-vans-reflect", + "soft-planets-mate", + "tall-scissors-sip", + "tame-hats-shout", + "twelve-eyes-stare", + "warm-masks-ring", + "wise-apes-juggle" + ] } diff --git a/.changeset/soft-planets-mate.md b/.changeset/soft-planets-mate.md new file mode 100644 index 0000000000..94dd790f4b --- /dev/null +++ b/.changeset/soft-planets-mate.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-scaffolder-react': patch +--- + +Add schema output return type to the `makeFieldSchema` function return diff --git a/.changeset/witty-pets-march.md b/.changeset/witty-pets-march.md new file mode 100644 index 0000000000..163d146027 --- /dev/null +++ b/.changeset/witty-pets-march.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-plugin-api': patch +--- + +Allow route references to be installed in multiple app instances as long as their name is the same. diff --git a/.github/vale/config/vocabularies/Backstage/accept.txt b/.github/vale/config/vocabularies/Backstage/accept.txt index 34ea8cc894..9de05aab88 100644 --- a/.github/vale/config/vocabularies/Backstage/accept.txt +++ b/.github/vale/config/vocabularies/Backstage/accept.txt @@ -228,6 +228,7 @@ LocalStack lockdown lockfile lookbehind +lowercased lunr Luxon magiclink diff --git a/canon-docs/src/app/(docs)/theme/theming/page.mdx b/canon-docs/src/app/(docs)/theme/theming/page.mdx index 421b315a7b..3a16b533e9 100644 --- a/canon-docs/src/app/(docs)/theme/theming/page.mdx +++ b/canon-docs/src/app/(docs)/theme/theming/page.mdx @@ -27,10 +27,10 @@ example below on how to set your light and dark mode. lang="css" code={`/** Light theme **/ [data-theme='light'] { - --canon-accent: #1ed760; + --canon-bg-accent: #1ed760; --canon-bg: #fff; - --canon-surface-1: #f5f5f5; - --canon-surface-2: #000; + --canon-bg-elevated: #f5f5f5; + --canon-bg: #000; --canon-outline: #666; --canon-outline-focus: #ccc; --canon-text-primary: #f0f0f0; @@ -42,10 +42,10 @@ example below on how to set your light and dark mode. /** Dark theme **/ [data-theme='dark'] { - --canon-accent: #1ed760; + --canon-bg-accent: #1ed760; + --canon-bg: #000; + --canon-bg-elevated: #f5f5f5; --canon-bg: #000; - --canon-surface-1: #f5f5f5; - --canon-surface-2: #000; --canon-outline: #666; --canon-outline-focus: #ccc; --canon-text-primary: #fff; @@ -73,7 +73,7 @@ application to match your brand. - --canon-accent + --canon-bg-accent The accent color for the theme. @@ -85,13 +85,13 @@ application to match your brand. - --canon-surface-1 + --canon-bg-elevated The first surface color for the theme. - --canon-surface-2 + --canon-bg The second surface color for the theme. diff --git a/canon-docs/src/app/(playground)/playground/styles.module.css b/canon-docs/src/app/(playground)/playground/styles.module.css index 5280021836..8fdd79a1dd 100644 --- a/canon-docs/src/app/(playground)/playground/styles.module.css +++ b/canon-docs/src/app/(playground)/playground/styles.module.css @@ -30,7 +30,7 @@ .breakpointContent { height: 100%; border-radius: 4px; - border: 1px solid var(--canon-border-base); - background-color: var(--canon-background-base); + border: 1px solid var(--canon-border); + background-color: var(--canon-bg); padding: 16px; } diff --git a/canon-docs/src/app/globals.css b/canon-docs/src/app/globals.css index 5efc0407e7..71f7b8be9c 100644 --- a/canon-docs/src/app/globals.css +++ b/canon-docs/src/app/globals.css @@ -1,7 +1,7 @@ body { display: flex; flex-direction: row; - background-color: var(--canon-background); + background-color: var(--canon-bg); color: var(--canon-text-primary); transition: background-color 0.2s ease-in-out; @@ -41,8 +41,8 @@ iframe { } .ΝΌ2 .cm-gutters { - background-color: var(--canon-surface-2); - border-right: 1px solid var(--canon-border-base); + background-color: var(--canon-bg); + border-right: 1px solid var(--canon-border); transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out; } diff --git a/canon-docs/src/components/CodeBlock/styles.module.css b/canon-docs/src/components/CodeBlock/styles.module.css index e74714e07c..b5f005f962 100644 --- a/canon-docs/src/components/CodeBlock/styles.module.css +++ b/canon-docs/src/components/CodeBlock/styles.module.css @@ -1,6 +1,6 @@ .codeBlock { border-radius: 4px; - border: 1px solid var(--canon-border-base); + border: 1px solid var(--canon-border); position: relative; background: transparent; overflow-x: auto; @@ -15,7 +15,7 @@ } .title { - border-bottom: 1px solid var(--canon-border-base); + border-bottom: 1px solid var(--canon-border); padding: 12px 20px; font-size: 0.875rem; color: var(--canon-text-secondary); diff --git a/canon-docs/src/components/CustomTheme/customTheme.tsx b/canon-docs/src/components/CustomTheme/customTheme.tsx index 3d8ed394bd..6f76267725 100644 --- a/canon-docs/src/components/CustomTheme/customTheme.tsx +++ b/canon-docs/src/components/CustomTheme/customTheme.tsx @@ -11,13 +11,13 @@ import { createTheme } from '@uiw/codemirror-themes'; import { tags as t } from '@lezer/highlight'; const defaultTheme = `:root { - --canon-accent: #000; + --canon-bg-accent: #000; }`; const myTheme = createTheme({ theme: 'light', settings: { - background: 'var(--canon-surface-1)', + background: 'var(--canon-bg-elevated)', backgroundImage: '', foreground: '#6182B8', caret: '#5d00ff', diff --git a/canon-docs/src/components/CustomTheme/styles.module.css b/canon-docs/src/components/CustomTheme/styles.module.css index a4f51c8a1d..fdb2d00fba 100644 --- a/canon-docs/src/components/CustomTheme/styles.module.css +++ b/canon-docs/src/components/CustomTheme/styles.module.css @@ -4,9 +4,9 @@ right: 16px; width: 240px; height: 47px; - background-color: var(--canon-surface-1); + background-color: var(--canon-bg-elevated); border-radius: 0.375rem; - border: 1px solid var(--canon-border-base); + border: 1px solid var(--canon-border); display: flex; flex-direction: column; overflow: hidden; @@ -31,8 +31,8 @@ .header { height: 46px; flex-shrink: 0; - border-bottom: 1px solid var(--canon-border-base); - background-color: var(--canon-surface-1); + border-bottom: 1px solid var(--canon-border); + background-color: var(--canon-bg-elevated); display: flex; justify-content: space-between; align-items: center; @@ -65,7 +65,7 @@ height: 28px; padding: 0 8px; color: #fff; - background-color: var(--canon-surface-2); + background-color: var(--canon-bg); color: var(--canon-text-primary); transition: background-color 0.2s ease-in-out; border-radius: 0.25rem; diff --git a/canon-docs/src/components/HeadlessBanners/styles.module.css b/canon-docs/src/components/HeadlessBanners/styles.module.css index 6993f51943..1353f150bb 100644 --- a/canon-docs/src/components/HeadlessBanners/styles.module.css +++ b/canon-docs/src/components/HeadlessBanners/styles.module.css @@ -1,9 +1,9 @@ .container { display: flex; - background-color: var(--canon-surface-1); + background-color: var(--canon-bg-elevated); padding: var(--canon-space-6); - border-radius: var(--canon-border-radius-xs); - border: 1px solid var(--canon-border-base); + border-radius: var(--canon-radius-2); + border: 1px solid var(--canon-border); margin-bottom: var(--canon-space-6); gap: var(--canon-space-6); transition: background-color 0.2s ease-in-out; @@ -29,14 +29,14 @@ align-items: center; justify-content: center; cursor: pointer; - background-color: var(--canon-surface-2); - border: 1px solid var(--canon-border-base); - border-radius: var(--canon-border-radius-xs); + background-color: var(--canon-bg); + border: 1px solid var(--canon-border); + border-radius: var(--canon-radius-2); padding: 0 var(--canon-space-3); height: 28px; border-radius: 100px; margin-top: var(--canon-space-3); - font-size: var(--canon-font-size-body); + font-size: var(--canon-font-size-3); color: var(--canon-text-primary); gap: var(--canon-space-2); } diff --git a/canon-docs/src/components/IconLibrary/styles.module.css b/canon-docs/src/components/IconLibrary/styles.module.css index 40b177ced0..8cef221620 100644 --- a/canon-docs/src/components/IconLibrary/styles.module.css +++ b/canon-docs/src/components/IconLibrary/styles.module.css @@ -19,10 +19,10 @@ height: 80px; border: 1px solid #d3d3d3; border-radius: 0.5rem; - background-color: var(--canon-background); + background-color: var(--canon-bg); transition: background-color 0.2s ease-in-out; &:hover { - background-color: var(--canon-surface-1); + background-color: var(--canon-bg-elevated); } } diff --git a/canon-docs/src/components/Sidebar/Sidebar.module.css b/canon-docs/src/components/Sidebar/Sidebar.module.css index f3bdd3f2e7..43f1681812 100644 --- a/canon-docs/src/components/Sidebar/Sidebar.module.css +++ b/canon-docs/src/components/Sidebar/Sidebar.module.css @@ -11,8 +11,8 @@ width: 300px; height: 100vh; color: var(--canon-text-primary); - background-color: var(--canon-surface-1); - border-right: 1px solid var(--canon-border-base); + background-color: var(--canon-bg-elevated); + border-right: 1px solid var(--canon-border); padding-left: 20px; padding-right: 20px; transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out; @@ -44,7 +44,7 @@ .sectionTitle { font-family: var(--docs-font); - font-size: var(--canon-font-size-body); + font-size: var(--canon-font-size-3); font-weight: var(--canon-font-weight-bold); padding: 12px 0; } @@ -63,23 +63,23 @@ transition: background-color 0.2s ease-in-out; &:hover { - background-color: var(--canon-surface-2); + background-color: var(--canon-bg); } } .line.active { - background-color: var(--canon-surface-2); + background-color: var(--canon-bg); } .lineTitle { font-family: var(--docs-font); - font-size: var(--canon-font-size-body); + font-size: var(--canon-font-size-3); font-weight: var(--canon-font-weight-regular); color: var(--canon-text-primary); } .lineStatus { font-family: var(--docs-font); - font-size: var(--canon-font-size-body); + font-size: var(--canon-font-size-3); color: var(--canon-text-secondary); } diff --git a/canon-docs/src/components/Snippet/styles.module.css b/canon-docs/src/components/Snippet/styles.module.css index c56627b1e1..65bdc62d05 100644 --- a/canon-docs/src/components/Snippet/styles.module.css +++ b/canon-docs/src/components/Snippet/styles.module.css @@ -6,8 +6,8 @@ .preview { border-radius: 4px; - box-shadow: inset 0 0 0 1px var(--canon-border-base); - background-color: var(--canon-background); + box-shadow: inset 0 0 0 1px var(--canon-border); + background-color: var(--canon-bg); transition: all 0.2s ease-in-out; padding: 1px; position: relative; diff --git a/canon-docs/src/components/Table/styles.module.css b/canon-docs/src/components/Table/styles.module.css index df90566eee..7ac48709eb 100644 --- a/canon-docs/src/components/Table/styles.module.css +++ b/canon-docs/src/components/Table/styles.module.css @@ -15,7 +15,7 @@ */ .wrapper { - border: 1px solid var(--canon-border-base); + border: 1px solid var(--canon-border); border-radius: 4px; overflow: hidden; margin-bottom: 1rem; @@ -33,7 +33,7 @@ padding: 12px 16px !important; border: none !important; text-align: left; - background-color: var(--canon-surface-1) !important; + background-color: var(--canon-bg-elevated) !important; font-size: 16px; transition: background-color 0.2s ease-in-out; @@ -43,14 +43,14 @@ } .tableHeaderCell { - border-bottom: 1px solid var(--canon-border-base) !important; + border-bottom: 1px solid var(--canon-border) !important; font-weight: 500; font-size: 14px; } .tableRow { border: none; - border-bottom: 1px solid var(--canon-border-base); + border-bottom: 1px solid var(--canon-border); &:last-child { border-bottom: none; } @@ -59,7 +59,7 @@ .tableChip { display: inline-block; font-size: 14px !important; - border: 1px solid var(--canon-border-base); + border: 1px solid var(--canon-border); border-radius: 6px; padding: 0px 6px; height: 24px; diff --git a/canon-docs/src/components/Tabs/styles.module.css b/canon-docs/src/components/Tabs/styles.module.css index c331316353..8d898fd727 100644 --- a/canon-docs/src/components/Tabs/styles.module.css +++ b/canon-docs/src/components/Tabs/styles.module.css @@ -5,7 +5,7 @@ .list { display: flex; gap: var(--canon-space-6); - border-bottom: 1px solid var(--canon-border-base); + border-bottom: 1px solid var(--canon-border); position: relative; margin-bottom: var(--canon-space-6); } diff --git a/canon-docs/src/components/Toolbar/nav.module.css b/canon-docs/src/components/Toolbar/nav.module.css index c16ed3d02a..90730b1403 100644 --- a/canon-docs/src/components/Toolbar/nav.module.css +++ b/canon-docs/src/components/Toolbar/nav.module.css @@ -12,7 +12,7 @@ .tabsTheme { width: 142px; border-radius: 0.375rem; - background-color: var(--canon-surface-2); + background-color: var(--canon-bg); transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out; } @@ -28,7 +28,7 @@ height: 60px; font-family: var(--docs-font); color: var(--canon-text-secondary); - font-size: var(--canon-font-size-body); + font-size: var(--canon-font-size-3); font-weight: var(--canon-font-weight-bold); cursor: pointer; transition: color 0.2s ease-in-out; @@ -53,7 +53,7 @@ position: absolute; inset: 0.25rem 0; border-radius: 0.25rem; - outline: 2px solid var(--canon-surface-1); + outline: 2px solid var(--canon-bg-elevated); outline-offset: -1px; } } diff --git a/canon-docs/src/components/Toolbar/styles.module.css b/canon-docs/src/components/Toolbar/styles.module.css index ff3376cfc1..3b0378a03e 100644 --- a/canon-docs/src/components/Toolbar/styles.module.css +++ b/canon-docs/src/components/Toolbar/styles.module.css @@ -4,8 +4,8 @@ left: 0; right: 0; z-index: 10; - background-color: var(--canon-surface-1); - border-bottom: 1px solid var(--canon-border-base); + background-color: var(--canon-bg-elevated); + border-bottom: 1px solid var(--canon-border); height: 60px; display: flex; align-items: center; diff --git a/canon-docs/src/components/Toolbar/theme-name.module.css b/canon-docs/src/components/Toolbar/theme-name.module.css index c9700c571b..0ae2675e31 100644 --- a/canon-docs/src/components/Toolbar/theme-name.module.css +++ b/canon-docs/src/components/Toolbar/theme-name.module.css @@ -17,7 +17,7 @@ color: var(--color-gray-900); cursor: pointer; user-select: none; - background-color: var(--canon-surface-2); + background-color: var(--canon-bg); transition: background-color 0.2s ease-in-out; &:focus-visible { @@ -31,7 +31,7 @@ } .SelectValue { - font-size: var(--canon-font-size-body); + font-size: var(--canon-font-size-3); font-weight: var(--canon-font-weight-regular); } @@ -43,9 +43,9 @@ box-sizing: border-box; padding-block: 0.25rem; border-radius: 0.375rem; - background-color: var(--canon-surface-1); + background-color: var(--canon-bg-elevated); color: var(--color-gray-900); - border: 1px solid var(--canon-border-base); + border: 1px solid var(--canon-border); padding-inline: 0.25rem; transform-origin: var(--transform-origin); transition: transform 150ms, opacity 150ms; @@ -82,7 +82,7 @@ padding-block: 0.5rem; padding-left: 0.625rem; padding-right: 1rem; - font-size: var(--canon-font-size-body); + font-size: var(--canon-font-size-3); font-weight: var(--canon-font-weight-bold); display: grid; gap: 0.5rem; @@ -104,7 +104,7 @@ z-index: 0; position: relative; color: var(--color-gray-50); - background-color: var(--canon-surface-2); + background-color: var(--canon-bg); } &[data-highlighted]::before { diff --git a/canon-docs/src/components/Toolbar/theme.module.css b/canon-docs/src/components/Toolbar/theme.module.css index 2d17ffbac2..564f5be4ca 100644 --- a/canon-docs/src/components/Toolbar/theme.module.css +++ b/canon-docs/src/components/Toolbar/theme.module.css @@ -1,14 +1,14 @@ .tabs { border-radius: 0.375rem; width: 100%; - background-color: var(--canon-surface-2); + background-color: var(--canon-bg); transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out; } .tabsTheme { width: 100px; border-radius: 0.375rem; - background-color: var(--canon-surface-2); + background-color: var(--canon-bg); transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out; } @@ -57,7 +57,7 @@ position: absolute; inset: 0.25rem 0; border-radius: 0.25rem; - outline: 2px solid var(--canon-surface-1); + outline: 2px solid var(--canon-bg-elevated); outline-offset: -1px; } } @@ -76,7 +76,7 @@ width: var(--active-tab-width); height: 1.5rem; border-radius: 0.25rem; - background-color: var(--canon-surface-1); + background-color: var(--canon-bg-elevated); transition-property: translate, width, background-color; transition-duration: 200ms; transition-timing-function: ease-in-out; diff --git a/canon-docs/src/mdx-components.tsx b/canon-docs/src/mdx-components.tsx index eec8eec438..85df3315c4 100644 --- a/canon-docs/src/mdx-components.tsx +++ b/canon-docs/src/mdx-components.tsx @@ -77,11 +77,11 @@ export function useMDXComponents(components: MDXComponents): MDXComponents { diff --git a/canon-docs/yarn.lock b/canon-docs/yarn.lock index 28810f8911..912da3edc2 100644 --- a/canon-docs/yarn.lock +++ b/canon-docs/yarn.lock @@ -925,11 +925,11 @@ __metadata: linkType: hard "@types/node@npm:^20": - version: 20.17.12 - resolution: "@types/node@npm:20.17.12" + version: 20.17.16 + resolution: "@types/node@npm:20.17.16" dependencies: undici-types: ~6.19.2 - checksum: 0c0dbeb4e1480a23071ec38e97bb3d776e0ae9828174bf45f9edcf277caa955945cb10d31d84f7a73c66aaf92ae2e022be6331bd00a4bed1f2ad9639a411d17e + checksum: dd19c04c592b602f20448187b4b6ab0293f22173a8bbe53aa3b559188f078b5261d748a107b84ee0580e2074cda760049b13d6e210f9850039bead01cb666a3f languageName: node linkType: hard @@ -5368,22 +5368,22 @@ __metadata: linkType: hard "typescript@npm:^5": - version: 5.7.2 - resolution: "typescript@npm:5.7.2" + version: 5.7.3 + resolution: "typescript@npm:5.7.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: b55300c4cefee8ee380d14fa9359ccb41ff8b54c719f6bc49b424899d662a5ce62ece390ce769568c7f4d14af844085255e63788740084444eb12ef423b13433 + checksum: 6c38b1e989918e576f0307e6ee013522ea480dfce5f3ca85c9b2d8adb1edeffd37f4f30cd68de0c38a44563d12ba922bdb7e36aa2dac9c51de5d561e6e9a2e9c languageName: node linkType: hard "typescript@patch:typescript@^5#~builtin": - version: 5.7.2 - resolution: "typescript@patch:typescript@npm%3A5.7.2#~builtin::version=5.7.2&hash=5adc0c" + version: 5.7.3 + resolution: "typescript@patch:typescript@npm%3A5.7.3#~builtin::version=5.7.3&hash=5adc0c" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 803430c6da2ba73c25a21880d8d4f08a56d9d2444e6db2ea949ac4abceeece8e4a442b7b9b585db7d8a0b47ebda2060e45fe8ee8b8aca23e27ec1d4844987ee6 + checksum: 633cd749d6cd7bc842c6b6245847173bba99742a60776fae3c0fbcc0d1733cd51a733995e5f4dadd8afb0e64e57d3c7dbbeae953a072ee303940eca69e22f311 languageName: node linkType: hard diff --git a/contrib/docs/tutorials/help-im-behind-a-corporate-proxy.md b/contrib/docs/tutorials/help-im-behind-a-corporate-proxy.md index 56af70c3ae..4852443ecf 100644 --- a/contrib/docs/tutorials/help-im-behind-a-corporate-proxy.md +++ b/contrib/docs/tutorials/help-im-behind-a-corporate-proxy.md @@ -41,7 +41,7 @@ There are however some ways to get this to work without too much effort. yarn start ``` - The default for `global-agent` is to have a prefix on the variable names, hence the need for specifying it twice. + The default for `global-agent` is to have a prefix on the variable names, hence the need for specifying it twice. For further information about `HTTP(S)_PROXY` and `NO_PROXY` excludes, see [the global-agent documentation](https://github.com/gajus/global-agent) and [undici documentation](https://github.com/nodejs/undici). ## Configuration diff --git a/docs/backend-system/core-services/auditor.md b/docs/backend-system/core-services/auditor.md new file mode 100644 index 0000000000..d4cbf70325 --- /dev/null +++ b/docs/backend-system/core-services/auditor.md @@ -0,0 +1,87 @@ +--- +id: auditor +title: Auditor Service +sidebar_label: Auditor +description: Documentation for the Auditor service +--- + +## Overview + +This document describes the Auditor Service, a software service designed to record and report on security-relevant events within an application. This service utilizes the `winston` library for logging and provides a flexible way to capture and format audit events. + +## Key Features + +- Provides a standardized way to capture security events. +- Allows categorization of events by severity level. +- Supports detailed metadata for each event. +- Offers success/failure reporting for events. +- Integrates with authentication and plugin services for enhanced context. +- Uses `winston` for flexible log formatting and transport. +- Provides a service factory for easy integration with Backstage plugins. +- Supports configurable log transports (console, file). + +## How it Works + +The Auditor Service defines a core class, `Auditor`, which implements the `AuditorService` interface. This class uses `winston` to log audit events with varying levels of severity and associated metadata. It also integrates with authentication and plugin services to capture actor details and plugin context. + +The `auditorServiceFactory` creates an `Auditor` instance for the root context and provides a factory function for creating child loggers for individual plugins. This allows each plugin to have its own logger with inherited and additional metadata. + +## Usage Guidance + +The Auditor Service is designed for recording security-relevant events that require special attention or are subject to compliance regulations. These events often involve actions like: + +- User session management +- Data access and modification +- System configuration changes + +For general application logging that is not security-critical, you should use the standard `LoggerService` provided by Backstage. This helps to keep your audit logs focused and relevant. + +## Using the Service + +The Auditor Service can be accessed via dependency injection in your Backstage plugin. Here's an example of how to access the service and create an audit event within an Express route handler: + +```typescript +export async function createRouter( + options: RouterOptions, +): Promise { + const { auditor } = options; + + const router = Router(); + router.use(express.json()); + + router.post('/my-endpoint', async (req, res) => { + const auditorEvent = await auditor.createEvent({ + eventId: 'my-endpoint-call', + request: req, + meta: { + // ... metadata about the request + }, + }); + + try { + // ... process the request + + await auditorEvent.success(); + res.status(200).json({ message: 'Succeeded!' }); + } catch (error) { + await auditorEvent.fail({ error }); + res.status(500).json({ message: 'Failed!' }); + throw error; + } + }); + + return router; +} +``` + +In this example, an audit event is created for each request to `/my-endpoint`. The `success` or `fail` methods are called based on the outcome of processing the request. + +## Naming Conventions + +When defining `eventId` and `subEventId` for your audit events, follow these guidelines: + +- Use kebab-case (e.g., `user-login`, `file-download`, `fetch`, `entity-create`, `entity-update`). +- The `eventId` represents a logical group of similar events or operations. For example, "fetch" could be used as an `eventId` encompassing various fetch methods like `by-id` or `by-location`. +- Use `subEventId` to further categorize events within a logical group. For example, if the `eventId` is "fetch", the `subEventId` could be "by-id" or "by-location" to specify the method used for fetching. +- Avoid redundant prefixes related to the plugin ID, as that context is already provided. +- Choose names that clearly and concisely describe the event being audited. diff --git a/docs/features/software-catalog/references.md b/docs/features/software-catalog/references.md index 2240d376ce..9a5a037d6d 100644 --- a/docs/features/software-catalog/references.md +++ b/docs/features/software-catalog/references.md @@ -36,7 +36,13 @@ additional encoding: The name is always required. Depending on the context, you may be able to leave out the kind and/or namespace. If you do, it is contextual what values will be used, and the relevant documentation should specify which rule applies where. -All strings are case insensitive. + +Entity ref strings are frequently passed between systems as identifiers of +entities. In those cases the refs should always be complete (have all three +parts). The sender should ensure that the refs are always lowercased in an +`en-US` locale, preferably by using [the `stringifyEntityRef` function](https://backstage.io/docs/reference/catalog-model.stringifyentityref/) +which does this automatically. The receiver should treat incoming refs case +insensitively to avoid problems with senders who do not obey this rule. ```yaml # Example: diff --git a/docs/releases/v1.36.0-next.0-changelog.md b/docs/releases/v1.36.0-next.0-changelog.md new file mode 100644 index 0000000000..007b3b15f5 --- /dev/null +++ b/docs/releases/v1.36.0-next.0-changelog.md @@ -0,0 +1,2127 @@ +# Release v1.36.0-next.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.36.0-next.0](https://backstage.github.io/upgrade-helper/?to=1.36.0-next.0) + +## @backstage/backend-defaults@0.8.0-next.0 + +### Minor Changes + +- a4aa244: This change introduces the `auditor` service implementation details. + +### Patch Changes + +- f866b86: Internal refactor to use explicit `require` for lazy-loading dependency. +- a19cb2b: Added default implementation for the new `PermissionsRegistryService`. +- Updated dependencies + - @backstage/cli-node@0.2.13-next.0 + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/config-loader@1.9.6-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/backend-app-api@1.1.2-next.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/backend-plugin-api@1.2.0-next.0 + +### Minor Changes + +- a4aa244: This change introduces the `auditor` service definition. + +### Patch Changes + +- 9ddfd94: Added new `PermissionsRegistryService` that is used by plugins to register permissions, resource types, and rules into the permission system. This replaces the existing `createPermissionIntegrationRouter` from `@backstage/plugin-permission-node`. +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-permission-common@0.8.4 + +## @backstage/backend-test-utils@1.3.0-next.0 + +### Minor Changes + +- dd05a97: Added mocks for the new `PermissionsRegistryService`. +- a4aa244: This change introduces mocks for the `auditor` service. + +### Patch Changes + +- f866b86: Internal refactor to use explicit `require` for lazy-loading dependency. +- fb051f2: Sync feature installation compatibility logic with `@backstage/backend-app-api`. +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/backend-app-api@1.1.2-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/canon@0.1.0-next.0 + +### Minor Changes + +- 65f4acc: This is the first alpha release for Canon. As part of this release we are introducing 5 layout components and 7 components. All theming is done through CSS variables. + +## @backstage/cli@0.30.0-next.0 + +### Minor Changes + +- cb76663: **BREAKING**: Add support for native ESM in Node.js code. This changes the behavior of dynamic import expressions in Node.js code. Typically this can be fixed by replacing `import(...)` with `require(...)`, with an `as typeof import(...)` cast if needed for types. This is because dynamic imports will no longer be transformed to `require(...)` calls, but instead be left as-is. This in turn allows you to load ESM modules from CommonJS code using `import(...)`. + + This change adds support for the following in Node.js packages, across type checking, package builds, runtime transforms and Jest tests: + + - Dynamic imports that load ESM modules from CommonJS code. + - Both `.mjs` and `.mts` files as explicit ESM files, as well as `.cjs` and `.cts` as explicit CommonJS files. + - Support for the `"type": "module"` field in `package.json` to indicate that the package is an ESM package. + + There are a few caveats to be aware of: + + - To enable support for native ESM in tests, you need to run the tests with the `--experimental-vm-modules` flag enabled, typically via `NODE_OPTIONS='--experimental-vm-modules'`. + - Declaring a package as `"type": "module"` in `package.json` is supported, but in tests it will cause all local transitive dependencies to also be treated as ESM, regardless of whether they declare `"type": "module"` or not. + - Node.js has an [ESM interoperability layer with CommonJS](https://nodejs.org/docs/latest-v22.x/api/esm.html#interoperability-with-commonjs) that allows for imports from ESM to identify named exports in CommonJS packages. This interoperability layer is **only** enabled when importing packages with a `.cts` or `.cjs` extension. This is because the interoperability layer is not fully compatible with the NPM ecosystem, and would break package if it was enabled for `.js` files. + - Dynamic imports of CommonJS packages will vary in shape depending on the runtime, i.e. test vs local development, etc. It is therefore recommended to avoid dynamic imports of CommonJS packages and instead use `require`, or to use the explicit CommonJS extensions as mentioned above. If you do need to dynamically import CommonJS packages, avoid using `default` exports, as the shape of them vary across different environments and you would otherwise need to manually unwrap the import based on the shape of the module object. + +### Patch Changes + +- f21b125: Ensure that both global-agent and undici agents are enabled when proxying is enabled. +- Updated dependencies + - @backstage/cli-node@0.2.13-next.0 + - @backstage/config-loader@1.9.6-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/eslint-plugin@0.1.10 + - @backstage/integration@1.16.1 + - @backstage/release-manifests@0.0.12 + - @backstage/types@1.2.1 + +## @techdocs/cli@1.9.0-next.0 + +### Minor Changes + +- 8de3d2d: Allow configurable optional retries for publisher AWS S3 operations. + +### Patch Changes + +- 69f84ac: Internal update to work with dynamic imports. +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/plugin-techdocs-node@1.13.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## @backstage/plugin-catalog-backend@1.31.0-next.0 + +### Minor Changes + +- 8805f93: The catalog backend now supports the new `PermissionsRegistryService`, which can be used to add custom permission rules. +- a4aa244: This change integrates the `auditor` service into the Catalog plugin. + +### Patch Changes + +- c9139e1: Ignore benign database conflict errors during stitching, now logged with debug level instead. +- f178b12: Cleanup `refresh_state_references` for entity processors and providers that are no longer in control of a `refresh_state` row for entity +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-search-backend-module-catalog@0.3.1-next.0 + - @backstage/backend-openapi-utils@0.4.2-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-events-node@0.4.8-next.0 + - @backstage/plugin-permission-common@0.8.4 + - @backstage/plugin-search-common@1.2.17 + +## @backstage/plugin-scaffolder-backend@1.30.0-next.0 + +### Minor Changes + +- a4aa244: This change integrates the `auditor` service into the Scaffolder plugin. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.27 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.5-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + - @backstage/plugin-permission-common@0.8.4 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.6-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.7-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.6-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.6-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.6-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.6-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.5.6-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.7.2-next.0 + - @backstage/plugin-scaffolder-common@1.5.9 + +## @backstage/plugin-scaffolder-node@0.7.0-next.0 + +### Minor Changes + +- a4aa244: This change introduces an optional `taskId` property to `TaskContext`. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/types@1.2.1 + - @backstage/plugin-scaffolder-common@1.5.9 + +## @backstage/plugin-techdocs-node@1.13.0-next.0 + +### Minor Changes + +- 8de3d2d: Allow configurable optional retries for publisher AWS S3 operations. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/integration-aws-node@0.1.15 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/backend-app-api@1.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/config-loader@1.9.6-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/backend-dynamic-feature-service@0.5.4-next.0 + +### Patch Changes + +- 96c20cd: Make sure changes are successfully tracked before starting up scanner. +- Updated dependencies + - @backstage/cli-node@0.2.13-next.0 + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/config-loader@1.9.6-next.0 + - @backstage/plugin-catalog-backend@1.31.0-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/backend-app-api@1.1.2-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.30-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-events-backend@0.4.2-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + - @backstage/plugin-permission-common@0.8.4 + - @backstage/plugin-search-backend-node@1.3.8-next.0 + - @backstage/plugin-search-common@1.2.17 + +## @backstage/backend-openapi-utils@0.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/cli-node@0.2.13-next.0 + +### Patch Changes + +- cb76663: Added `type` field to `BackstagePackageJson` type. +- Updated dependencies + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/config-loader@1.9.6-next.0 + +### Patch Changes + +- f866b86: Internal refactor to use explicit `require` for lazy-loading dependency. +- Updated dependencies + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/core-compat-api@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/core-plugin-api@1.10.3 + - @backstage/version-bridge@1.0.10 + +## @backstage/create-app@0.5.25-next.0 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.15 + +## @backstage/dev-utils@1.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/app-defaults@1.5.16 + - @backstage/catalog-model@1.7.3 + - @backstage/core-app-api@1.15.4 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/integration-react@1.2.3 + - @backstage/theme@0.6.3 + - @backstage/plugin-catalog-react@1.15.2-next.0 + +## @backstage/frontend-app-api@0.10.5-next.0 + +### Patch Changes + +- 3e21b8d: Added `getNodesByRoutePath` method to the `AppTreeApi`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.15.4 + - @backstage/core-plugin-api@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/frontend-defaults@0.1.6-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.10 + +## @backstage/frontend-defaults@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/frontend-app-api@0.10.5-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-app@0.1.6-next.0 + +## @backstage/frontend-plugin-api@0.9.5-next.0 + +### Patch Changes + +- 3e21b8d: Added `getNodesByRoutePath` method to the `AppTreeApi`. +- Updated dependencies + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.10 + +## @backstage/frontend-test-utils@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/frontend-app-api@0.10.5-next.0 + - @backstage/config@1.3.2 + - @backstage/test-utils@1.7.4 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.10 + - @backstage/plugin-app@0.1.6-next.0 + +## @backstage/repo-tools@0.12.2-next.0 + +### Patch Changes + +- 98ddf05: The `api-reports` command is now also able to generate SQL reports, enabled by the `--sql-reports` flag. +- cb76663: Internal refactor to support native ESM. +- ecd01a9: Internal refactor of API report generation. +- Updated dependencies + - @backstage/cli-node@0.2.13-next.0 + - @backstage/config-loader@1.9.6-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @backstage/plugin-api-docs@0.12.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/plugin-catalog@1.26.2-next.0 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-catalog-react@1.15.2-next.0 + - @backstage/plugin-permission-react@0.4.30 + +## @backstage/plugin-app@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/integration-react@1.2.3 + - @backstage/theme@0.6.3 + - @backstage/plugin-permission-react@0.4.30 + +## @backstage/plugin-app-backend@0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.6-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.30-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-app-node@0.1.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.6-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + +## @backstage/plugin-app-visualizer@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + +## @backstage/plugin-auth-backend@0.24.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.3.5-next.0 + - @backstage/plugin-auth-backend-module-auth0-provider@0.1.5-next.0 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.3.3-next.0 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.5-next.0 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.5-next.0 + - @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.1.5-next.0 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.5-next.0 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.5-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.5-next.0 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.2.5-next.0 + - @backstage/plugin-auth-backend-module-google-provider@0.2.5-next.0 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.2.5-next.0 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.3.5-next.0 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.5-next.0 + - @backstage/plugin-auth-backend-module-oidc-provider@0.3.5-next.0 + - @backstage/plugin-auth-backend-module-okta-provider@0.1.5-next.0 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.2.5-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-auth-backend@0.24.3-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/errors@1.2.7 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-github-provider@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/errors@1.2.7 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-auth-backend@0.24.3-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-okta-provider@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/plugin-auth-node@0.5.7-next.0 + +## @backstage/plugin-auth-node@0.5.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog@1.26.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-react@1.8.6-next.0 + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/integration-react@1.2.3 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-catalog-react@1.15.2-next.0 + - @backstage/plugin-permission-react@0.4.30 + - @backstage/plugin-scaffolder-common@1.5.9 + - @backstage/plugin-search-common@1.2.17 + +## @backstage/plugin-catalog-backend-module-aws@0.4.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/plugin-kubernetes-common@0.9.3-next.0 + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/integration-aws-node@0.1.15 + - @backstage/plugin-catalog-common@1.1.3 + +## @backstage/plugin-catalog-backend-module-azure@0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/integration@1.16.1 + - @backstage/plugin-catalog-common@1.1.3 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/backend-openapi-utils@0.4.2-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration@1.16.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.27 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.9.3-next.0 + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + +## @backstage/plugin-catalog-backend-module-gerrit@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + +## @backstage/plugin-catalog-backend-module-github@0.7.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.31.0-next.0 + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration@1.16.1 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-backend-module-github@0.7.10-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.6.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration@1.16.1 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-catalog-backend-module-gitlab@0.6.3-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.6.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/plugin-catalog-backend@1.31.0-next.0 + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.8-next.0 + - @backstage/plugin-permission-common@0.8.4 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.3 + +## @backstage/plugin-catalog-backend-module-logs@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.31.0-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.6.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.3 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.7-next.0 + +### Patch Changes + +- 7fc6f7c: Fix `resolveUrl` for split openapi definition relative path +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/integration@1.16.1 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.3 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-scaffolder-common@1.5.9 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.5.5-next.0 + +### Patch Changes + +- 4e073c7: Use new `PermissionsRegistryService` instead of the deprecated `catalogPermissionExtensionPoint`. +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/errors@1.2.7 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.7 + - @backstage/plugin-permission-common@0.8.4 + +## @backstage/plugin-catalog-graph@0.4.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-react@1.15.2-next.0 + +## @backstage/plugin-catalog-import@0.12.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/integration-react@1.2.3 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-catalog-react@1.15.2-next.0 + +## @backstage/plugin-catalog-node@1.15.2-next.0 + +### Patch Changes + +- 4a941e7: Deprecated the alpha `catalogPermissionExtensionPoint` and related types, since the same functionality is now available via the new `PermissionsRegistryService`. +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-permission-common@0.8.4 + +## @backstage/plugin-catalog-react@1.15.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/frontend-test-utils@0.2.6-next.0 + - @backstage/integration-react@1.2.3 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.10 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-permission-common@0.8.4 + - @backstage/plugin-permission-react@0.4.30 + +## @backstage/plugin-devtools@0.1.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/plugin-devtools-common@0.1.15 + - @backstage/plugin-permission-react@0.4.30 + +## @backstage/plugin-devtools-backend@0.5.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/config-loader@1.9.6-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-devtools-common@0.1.15 + - @backstage/plugin-permission-common@0.8.4 + +## @backstage/plugin-events-backend@0.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/backend-openapi-utils@0.4.2-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/plugin-events-backend-module-azure@0.2.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.2.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/plugin-events-backend-module-github@0.2.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/plugin-events-backend-module-gitlab@0.2.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/plugin-events-backend-test-utils@0.1.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/plugin-events-node@0.4.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-home@0.8.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.15.4 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/theme@0.6.3 + - @backstage/plugin-catalog-react@1.15.2-next.0 + - @backstage/plugin-home-react@0.1.22 + +## @backstage/plugin-kubernetes@0.12.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-react@0.5.4-next.0 + - @backstage/plugin-kubernetes-common@0.9.3-next.0 + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/plugin-catalog-react@1.15.2-next.0 + +## @backstage/plugin-kubernetes-backend@0.19.3-next.0 + +### Patch Changes + +- ac0e1ac: Fixed the lack of `secrets` to fetch from the kubernetes api by adding option to specify additional Objects which are not part of Default Objects +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/plugin-kubernetes-common@0.9.3-next.0 + - @backstage/plugin-kubernetes-node@0.2.3-next.0 + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-permission-common@0.8.4 + +## @backstage/plugin-kubernetes-cluster@0.0.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-react@0.5.4-next.0 + - @backstage/plugin-kubernetes-common@0.9.3-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/plugin-catalog-react@1.15.2-next.0 + +## @backstage/plugin-kubernetes-common@0.9.3-next.0 + +### Patch Changes + +- ac0e1ac: Fixed the lack of `secrets` to fetch from the kubernetes api by adding option to specify additional Objects which are not part of Default Objects +- Updated dependencies + - @backstage/catalog-model@1.7.3 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.8.4 + +## @backstage/plugin-kubernetes-node@0.2.3-next.0 + +### Patch Changes + +- ac0e1ac: Fixed the lack of `secrets` to fetch from the kubernetes api by adding option to specify additional Objects which are not part of Default Objects +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.9.3-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/types@1.2.1 + +## @backstage/plugin-kubernetes-react@0.5.4-next.0 + +### Patch Changes + +- f35a754: Fixed bug in string-to-integer conversion to properly handle decimal values with BigInt. +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.9.3-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-notifications@0.5.2-next.0 + +### Patch Changes + +- 438c36c: added topic filter for notifications +- Updated dependencies + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.3 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-signals-react@0.0.9 + +## @backstage/plugin-notifications-backend@0.5.2-next.0 + +### Patch Changes + +- 438c36c: added topic filter for notifications +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.12-next.0 + - @backstage/plugin-signals-node@0.1.17-next.0 + +## @backstage/plugin-notifications-backend-module-email@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.12-next.0 + +## @backstage/plugin-notifications-node@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-signals-node@0.1.17-next.0 + +## @backstage/plugin-org@0.6.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-catalog-react@1.15.2-next.0 + +## @backstage/plugin-org-react@0.1.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/plugin-catalog-react@1.15.2-next.0 + +## @backstage/plugin-permission-backend@0.5.54-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-permission-common@0.8.4 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-permission-common@0.8.4 + +## @backstage/plugin-permission-node@0.8.8-next.0 + +### Patch Changes + +- 049d5d4: The returned router from `createPermissionIntegrationRouter` is now mutable, allowing for permissions and resources to be added after creation of the router. +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-permission-common@0.8.4 + +## @backstage/plugin-proxy-backend@0.5.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-proxy-node@0.1.1-next.0 + +## @backstage/plugin-proxy-node@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + +## @backstage/plugin-scaffolder@1.27.5-next.0 + +### Patch Changes + +- 3107f1f: Fixed a bug in the BitbucketRepoBranchPicker component that crashed the scaffolder +- 3edf7e7: Add schema output return type to the `makeFieldSchema` function return +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.14.4-next.0 + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/integration-react@1.2.3 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-catalog-react@1.15.2-next.0 + - @backstage/plugin-permission-react@0.4.30 + - @backstage/plugin-scaffolder-common@1.5.9 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.6-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.6-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.27 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + +## @backstage/plugin-scaffolder-backend-module-github@0.5.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.7.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.12-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-scaffolder-node-test-utils@0.1.19-next.0 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-test-utils@1.3.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-react@1.14.4-next.0 + +### Patch Changes + +- 3edf7e7: Add schema output return type to the `makeFieldSchema` function return +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/theme@0.6.3 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.10 + - @backstage/plugin-catalog-react@1.15.2-next.0 + - @backstage/plugin-permission-react@0.4.30 + - @backstage/plugin-scaffolder-common@1.5.9 + +## @backstage/plugin-search@1.4.23-next.0 + +### Patch Changes + +- 63e1012: Added new extension points to extend search filters `SearchFilterBlueprint` and `SearchFilterResultTypeBlueprint` +- Updated dependencies + - @backstage/plugin-search-react@1.8.6-next.0 + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.10 + - @backstage/plugin-catalog-react@1.15.2-next.0 + - @backstage/plugin-search-common@1.2.17 + +## @backstage/plugin-search-backend@1.8.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/backend-openapi-utils@0.4.2-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.8.4 + - @backstage/plugin-search-backend-node@1.3.8-next.0 + - @backstage/plugin-search-common@1.2.17 + +## @backstage/plugin-search-backend-module-catalog@0.3.1-next.0 + +### Patch Changes + +- eee8d76: Modified the logic for generating the location URL by encoding the entity property values with `encodeURIComponent`. This enhancement improves the safety and reliability of the URL. +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-permission-common@0.8.4 + - @backstage/plugin-search-backend-node@1.3.8-next.0 + - @backstage/plugin-search-common@1.2.17 + +## @backstage/plugin-search-backend-module-elasticsearch@1.6.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/plugin-search-backend-node@1.3.8-next.0 + - @backstage/plugin-search-common@1.2.17 + +## @backstage/plugin-search-backend-module-explore@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.8-next.0 + - @backstage/plugin-search-common@1.2.17 + +## @backstage/plugin-search-backend-module-pg@0.5.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.8-next.0 + - @backstage/plugin-search-common@1.2.17 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.8-next.0 + - @backstage/plugin-search-common@1.2.17 + +## @backstage/plugin-search-backend-module-techdocs@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/plugin-techdocs-node@1.13.0-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-permission-common@0.8.4 + - @backstage/plugin-search-backend-node@1.3.8-next.0 + - @backstage/plugin-search-common@1.2.17 + +## @backstage/plugin-search-backend-node@1.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.8.4 + - @backstage/plugin-search-common@1.2.17 + +## @backstage/plugin-search-react@1.8.6-next.0 + +### Patch Changes + +- 63e1012: Added new extension points to extend search filters `SearchFilterBlueprint` and `SearchFilterResultTypeBlueprint` +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/theme@0.6.3 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.10 + - @backstage/plugin-search-common@1.2.17 + +## @backstage/plugin-signals-backend@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + - @backstage/plugin-signals-node@0.1.17-next.0 + +## @backstage/plugin-signals-node@0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + +## @backstage/plugin-techdocs@1.12.2-next.0 + +### Patch Changes + +- f4be934: Changed the base URL in addLinkClickListener from window.location.origin to app.baseUrl for improved path handling. This fixes an issue where Backstage, when running on a subpath, was unable to handle non-Backstage URLs of the same origin correctly. + +- 1f40e6b: Add optional props to `TechDocCustomHome` to allow for more flexibility: + + ```tsx + import { TechDocsCustomHome } from '@backstage/plugin-techdocs'; + //... + + const options = { emptyRowsWhenPaging: false }; + const linkDestination = (entity: Entity): string | undefined => { + return entity.metadata.annotations?.['external-docs']; + }; + const techDocsTabsConfig = [ + { + label: 'Recommended Documentation', + panels: [ + { + title: 'Golden Path', + description: 'Documentation about standards to follow', + panelType: 'DocsCardGrid', + panelProps: { CustomHeader: () => }, + filterPredicate: entity => + entity?.metadata?.tags?.includes('golden-path') ?? false, + }, + { + title: 'Recommended', + description: 'Useful documentation', + panelType: 'InfoCardGrid', + panelProps: { + CustomHeader: () => + linkDestination: linkDestination, + }, + filterPredicate: entity => + entity?.metadata?.tags?.includes('recommended') ?? false, + }, + ], + }, + { + label: 'Browse All', + panels: [ + { + description: 'Browse all docs', + filterPredicate: filterEntity, + panelType: 'TechDocsIndexPage', + title: 'All', + panelProps: { PageWrapper: React.Fragment, CustomHeader: React.Fragment, options: options }, + }, + ], + }, + ]; + + const AppRoutes = () => { + + ) => ({children})} + /> + } + /> + ; + }; + ``` + + Add new Grid option called `InfoCardGrid` which is a more customizable card option for the Docs grid. + + ```tsx + entity.metadata['external-docs']} + /> + ``` + + Expose existing `CustomDocsPanel` so that it can be used independently if desired. + + ```tsx + const panels: PanelConfig[] = [ + { + description: '', + filterPredicate: entity => {}, + panelType: 'InfoCardGrid', + title: 'Standards', + panelProps: { + CustomHeader: () => + linkDestination: linkDestination, + }, + }, + { + description: '', + filterPredicate: entity => {}, + panelType: 'DocsCardGrid', + title: 'Contribute', + }, + ]; + { + panels.map((config, index) => ( + + )); + } + ``` + +- Updated dependencies + - @backstage/plugin-search-react@1.8.6-next.0 + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/integration-react@1.2.3 + - @backstage/theme@0.6.3 + - @backstage/plugin-auth-react@0.1.11 + - @backstage/plugin-catalog-react@1.15.2-next.0 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.13 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.45-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-react@1.8.6-next.0 + - @backstage/plugin-techdocs@1.12.2-next.0 + - @backstage/core-app-api@1.15.4 + - @backstage/core-plugin-api@1.10.3 + - @backstage/integration-react@1.2.3 + - @backstage/test-utils@1.7.4 + - @backstage/plugin-catalog@1.26.2-next.0 + - @backstage/plugin-catalog-react@1.15.2-next.0 + - @backstage/plugin-techdocs-react@1.2.13 + +## @backstage/plugin-techdocs-backend@1.11.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/plugin-techdocs-node@1.13.0-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-permission-common@0.8.4 + - @backstage/plugin-search-backend-module-techdocs@0.3.6-next.0 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-user-settings@0.8.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/core-app-api@1.15.4 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.3 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-react@1.15.2-next.0 + - @backstage/plugin-signals-react@0.0.9 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.2.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-signals-node@0.1.17-next.0 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.106-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.30.0-next.0 + - @backstage/plugin-notifications@0.5.2-next.0 + - @backstage/plugin-search-react@1.8.6-next.0 + - @backstage/plugin-search@1.4.23-next.0 + - @backstage/plugin-techdocs@1.12.2-next.0 + - @backstage/plugin-scaffolder@1.27.5-next.0 + - @backstage/plugin-scaffolder-react@1.14.4-next.0 + - @backstage/frontend-app-api@0.10.5-next.0 + - @backstage/app-defaults@1.5.16 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.15.4 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/integration-react@1.2.3 + - @backstage/theme@0.6.3 + - @backstage/plugin-api-docs@0.12.4-next.0 + - @backstage/plugin-auth-react@0.1.11 + - @backstage/plugin-catalog@1.26.2-next.0 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-catalog-graph@0.4.16-next.0 + - @backstage/plugin-catalog-import@0.12.10-next.0 + - @backstage/plugin-catalog-react@1.15.2-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.13 + - @backstage/plugin-devtools@0.1.24-next.0 + - @backstage/plugin-home@0.8.5-next.0 + - @backstage/plugin-kubernetes@0.12.4-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.22-next.0 + - @backstage/plugin-org@0.6.36-next.0 + - @backstage/plugin-permission-react@0.4.30 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-signals@0.0.15 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.20 + - @backstage/plugin-techdocs-react@1.2.13 + - @backstage/plugin-user-settings@0.8.19-next.0 + +## example-app-next@0.0.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.30.0-next.0 + - @backstage/plugin-notifications@0.5.2-next.0 + - @backstage/plugin-search-react@1.8.6-next.0 + - @backstage/plugin-search@1.4.23-next.0 + - @backstage/plugin-techdocs@1.12.2-next.0 + - @backstage/plugin-scaffolder@1.27.5-next.0 + - @backstage/plugin-scaffolder-react@1.14.4-next.0 + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/frontend-app-api@0.10.5-next.0 + - @backstage/app-defaults@1.5.16 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.15.4 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/frontend-defaults@0.1.6-next.0 + - @backstage/integration-react@1.2.3 + - @backstage/theme@0.6.3 + - @backstage/plugin-api-docs@0.12.4-next.0 + - @backstage/plugin-app@0.1.6-next.0 + - @backstage/plugin-app-visualizer@0.1.16-next.0 + - @backstage/plugin-auth-react@0.1.11 + - @backstage/plugin-catalog@1.26.2-next.0 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-catalog-graph@0.4.16-next.0 + - @backstage/plugin-catalog-import@0.12.10-next.0 + - @backstage/plugin-catalog-react@1.15.2-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.13 + - @backstage/plugin-home@0.8.5-next.0 + - @backstage/plugin-kubernetes@0.12.4-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.22-next.0 + - @backstage/plugin-org@0.6.36-next.0 + - @backstage/plugin-permission-react@0.4.30 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-signals@0.0.15 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.20 + - @backstage/plugin-techdocs-react@1.2.13 + - @backstage/plugin-user-settings@0.8.19-next.0 + +## app-next-example-plugin@0.0.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/core-components@0.16.3 + +## example-backend@0.0.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/plugin-notifications-backend@0.5.2-next.0 + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/plugin-catalog-backend@1.31.0-next.0 + - @backstage/plugin-kubernetes-backend@0.19.3-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.5-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-backend@1.30.0-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.7-next.0 + - @backstage/plugin-search-backend-module-catalog@0.3.1-next.0 + - @backstage/plugin-devtools-backend@0.5.2-next.0 + - @backstage/plugin-permission-backend@0.5.54-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.5-next.0 + - @backstage/plugin-search-backend@1.8.2-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/plugin-app-backend@0.4.5-next.0 + - @backstage/plugin-auth-backend@0.24.3-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.5-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.5-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.5-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.5-next.0 + - @backstage/plugin-events-backend@0.4.2-next.0 + - @backstage/plugin-permission-common@0.8.4 + - @backstage/plugin-proxy-backend@0.5.11-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.5.6-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.7-next.0 + - @backstage/plugin-search-backend-module-explore@0.2.8-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.3.6-next.0 + - @backstage/plugin-search-backend-node@1.3.8-next.0 + - @backstage/plugin-signals-backend@0.3.1-next.0 + - @backstage/plugin-techdocs-backend@1.11.6-next.0 + +## example-backend-legacy@0.2.107-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/plugin-catalog-backend@1.31.0-next.0 + - @backstage/plugin-kubernetes-backend@0.19.3-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.5-next.0 + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-backend@1.30.0-next.0 + - @backstage/plugin-search-backend-module-catalog@0.3.1-next.0 + - @backstage/plugin-permission-backend@0.5.54-next.0 + - @backstage/plugin-search-backend@1.8.2-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration@1.16.1 + - @backstage/plugin-app-backend@0.4.5-next.0 + - @backstage/plugin-auth-backend@0.24.3-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.5-next.0 + - @backstage/plugin-events-backend@0.4.2-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + - @backstage/plugin-permission-common@0.8.4 + - @backstage/plugin-proxy-backend@0.5.11-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.6-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.7.2-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.5.6-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.6.5-next.0 + - @backstage/plugin-search-backend-module-explore@0.2.8-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.41-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.3.6-next.0 + - @backstage/plugin-search-backend-node@1.3.8-next.0 + - @backstage/plugin-signals-backend@0.3.1-next.0 + - @backstage/plugin-signals-node@0.1.17-next.0 + - @backstage/plugin-techdocs-backend@1.11.6-next.0 + +## e2e-test@0.2.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.25-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @internal/frontend@0.0.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.10 + +## @internal/scaffolder@0.0.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.14.4-next.0 + - @backstage/frontend-plugin-api@0.9.5-next.0 + +## techdocs-cli-embedded-app@0.2.105-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.30.0-next.0 + - @backstage/plugin-techdocs@1.12.2-next.0 + - @backstage/app-defaults@1.5.16 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.15.4 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/integration-react@1.2.3 + - @backstage/test-utils@1.7.4 + - @backstage/theme@0.6.3 + - @backstage/plugin-catalog@1.26.2-next.0 + - @backstage/plugin-techdocs-react@1.2.13 + +## @internal/plugin-todo-list-backend@1.0.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-auth-node@0.5.7-next.0 diff --git a/docs/tooling/cli/02-build-system.md b/docs/tooling/cli/02-build-system.md index 8f9b086c33..f3b29e979d 100644 --- a/docs/tooling/cli/02-build-system.md +++ b/docs/tooling/cli/02-build-system.md @@ -515,6 +515,7 @@ The Backstage tooling supports [ECMAScript modules (ESM)](https://nodejs.org/doc - To enable support for native ESM in tests, you need to run the tests with the `--experimental-vm-modules` flag enabled, typically via `NODE_OPTIONS='--experimental-vm-modules'`. - Declaring a package as `"type": "module"` in `package.json` is supported, but in tests it will cause all local transitive dependencies to also be treated as ESM, regardless of whether they declare `"type": "module"` or not. +- When running tests with coverage enabled the default `babel` coverage provider can mess with the hoisting of named exports. This can be worked around by using the `v8` provider instead by setting `"coverageProvider": "v8"` in the Jest configuration, although note that the `v8` provider is a fair bit slower than the `babel` one. - Node.js has an [ESM interoperability layer with CommonJS](https://nodejs.org/docs/latest-v22.x/api/esm.html#interoperability-with-commonjs) that allows for imports from ESM to identify named exports in CommonJS packages. This interoperability layer is **only** enabled when importing packages with a `.cts` or `.cjs` extension. This is because the interoperability layer is not fully compatible with the NPM ecosystem, and would break package if it was enabled for `.js` files. - Dynamic imports of CommonJS packages will vary in shape depending on the runtime, i.e. test vs local development, etc. It is therefore recommended to avoid dynamic imports of CommonJS packages and instead use `require`, or to use the explicit CommonJS extensions as mentioned above. If you do need to dynamically import CommonJS packages, avoid using `default` exports, as the shape of them vary across different environments and you would otherwise need to manually unwrap the import based on the shape of the module object. diff --git a/microsite/data/plugins/digital.ai-deploy.yaml b/microsite/data/plugins/digital.ai-deploy.yaml index 6077f59fa7..a36dd08ffb 100644 --- a/microsite/data/plugins/digital.ai-deploy.yaml +++ b/microsite/data/plugins/digital.ai-deploy.yaml @@ -4,7 +4,7 @@ author: digital.ai authorUrl: https://digital.ai/ category: CI/CD description: The plugin offers integration with Digital.ai Deploy and backstage components and services. It provide access to deployments and reports. -documentation: https://docs.digital.ai/bundle/devops-deploy-version-v.24.1/page/deploy/concept/xl-deploy-backstage-overview.html +documentation: https://docs.digital.ai/deploy/docs/concept/xl-deploy-backstage-overview iconUrl: /img/digital.ai-deploy.svg npmPackageName: '@digital.ai/plugin-dai-deploy' tags: diff --git a/microsite/data/plugins/digital.ai-release.yaml b/microsite/data/plugins/digital.ai-release.yaml index 288a95a123..4407b26ac7 100644 --- a/microsite/data/plugins/digital.ai-release.yaml +++ b/microsite/data/plugins/digital.ai-release.yaml @@ -4,7 +4,7 @@ author: digital.ai authorUrl: https://digital.ai/ category: CI/CD description: The plugin offers integration with Digital.ai Release and backstage. It provide access to active releases, templates and manage workflow executions. -documentation: https://docs.digital.ai/bundle/devops-release-version-v.24.1/page/release/concept/release-backstage-overview.html +documentation: https://docs.digital.ai/release/docs/concept/release-backstage-overview iconUrl: /img/digital.ai-release.svg npmPackageName: '@digital-ai/plugin-dai-release' tags: diff --git a/package.json b/package.json index 41b8529c70..11b419d3fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "1.35.0", + "version": "1.36.0-next.0", "private": true, "repository": { "type": "git", diff --git a/packages/app-next-example-plugin/CHANGELOG.md b/packages/app-next-example-plugin/CHANGELOG.md index 9872fb08ad..0bb209a797 100644 --- a/packages/app-next-example-plugin/CHANGELOG.md +++ b/packages/app-next-example-plugin/CHANGELOG.md @@ -1,5 +1,13 @@ # app-next-example-plugin +## 0.0.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/core-components@0.16.3 + ## 0.0.19 ### Patch Changes diff --git a/packages/app-next-example-plugin/package.json b/packages/app-next-example-plugin/package.json index 8cbf4734aa..19c2d1afcf 100644 --- a/packages/app-next-example-plugin/package.json +++ b/packages/app-next-example-plugin/package.json @@ -1,6 +1,6 @@ { "name": "app-next-example-plugin", - "version": "0.0.19", + "version": "0.0.20-next.0", "description": "Backstage internal example plugin", "backstage": { "role": "frontend-plugin", diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index 54231823cf..147ec312ed 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,50 @@ # example-app-next +## 0.0.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.30.0-next.0 + - @backstage/plugin-notifications@0.5.2-next.0 + - @backstage/plugin-search-react@1.8.6-next.0 + - @backstage/plugin-search@1.4.23-next.0 + - @backstage/plugin-techdocs@1.12.2-next.0 + - @backstage/plugin-scaffolder@1.27.5-next.0 + - @backstage/plugin-scaffolder-react@1.14.4-next.0 + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/frontend-app-api@0.10.5-next.0 + - @backstage/app-defaults@1.5.16 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.15.4 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/frontend-defaults@0.1.6-next.0 + - @backstage/integration-react@1.2.3 + - @backstage/theme@0.6.3 + - @backstage/plugin-api-docs@0.12.4-next.0 + - @backstage/plugin-app@0.1.6-next.0 + - @backstage/plugin-app-visualizer@0.1.16-next.0 + - @backstage/plugin-auth-react@0.1.11 + - @backstage/plugin-catalog@1.26.2-next.0 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-catalog-graph@0.4.16-next.0 + - @backstage/plugin-catalog-import@0.12.10-next.0 + - @backstage/plugin-catalog-react@1.15.2-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.13 + - @backstage/plugin-home@0.8.5-next.0 + - @backstage/plugin-kubernetes@0.12.4-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.22-next.0 + - @backstage/plugin-org@0.6.36-next.0 + - @backstage/plugin-permission-react@0.4.30 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-signals@0.0.15 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.20 + - @backstage/plugin-techdocs-react@1.2.13 + - @backstage/plugin-user-settings@0.8.19-next.0 + ## 0.0.19 ### Patch Changes diff --git a/packages/app-next/package.json b/packages/app-next/package.json index 27ad7a36fe..2710335f4c 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.19", + "version": "0.0.20-next.0", "backstage": { "role": "frontend" }, diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index e3313f2517..b4730f5142 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,46 @@ # example-app +## 0.2.106-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.30.0-next.0 + - @backstage/plugin-notifications@0.5.2-next.0 + - @backstage/plugin-search-react@1.8.6-next.0 + - @backstage/plugin-search@1.4.23-next.0 + - @backstage/plugin-techdocs@1.12.2-next.0 + - @backstage/plugin-scaffolder@1.27.5-next.0 + - @backstage/plugin-scaffolder-react@1.14.4-next.0 + - @backstage/frontend-app-api@0.10.5-next.0 + - @backstage/app-defaults@1.5.16 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.15.4 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/integration-react@1.2.3 + - @backstage/theme@0.6.3 + - @backstage/plugin-api-docs@0.12.4-next.0 + - @backstage/plugin-auth-react@0.1.11 + - @backstage/plugin-catalog@1.26.2-next.0 + - @backstage/plugin-catalog-common@1.1.3 + - @backstage/plugin-catalog-graph@0.4.16-next.0 + - @backstage/plugin-catalog-import@0.12.10-next.0 + - @backstage/plugin-catalog-react@1.15.2-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.13 + - @backstage/plugin-devtools@0.1.24-next.0 + - @backstage/plugin-home@0.8.5-next.0 + - @backstage/plugin-kubernetes@0.12.4-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.22-next.0 + - @backstage/plugin-org@0.6.36-next.0 + - @backstage/plugin-permission-react@0.4.30 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-signals@0.0.15 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.20 + - @backstage/plugin-techdocs-react@1.2.13 + - @backstage/plugin-user-settings@0.8.19-next.0 + ## 0.2.105 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 2bc2cb0980..e3cb08924f 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.105", + "version": "0.2.106-next.0", "backstage": { "role": "frontend" }, diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index ed176965bd..ee77fb93cd 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/backend-app-api +## 1.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/config-loader@1.9.6-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.5.7-next.0 + ## 1.1.1 ### Patch Changes diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 2d54845036..e2c3cd3cbb 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-app-api", - "version": "1.1.1", + "version": "1.1.2-next.0", "description": "Core API used by Backstage backend apps", "backstage": { "role": "node-library" diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.ts b/packages/backend-app-api/src/wiring/BackendInitializer.ts index aa48c26877..6bec5439ec 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.ts @@ -34,7 +34,7 @@ import type { } from '../../../backend-plugin-api/src/wiring/types'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import type { InternalServiceFactory } from '../../../backend-plugin-api/src/services/system/types'; -import { ForwardedError, ConflictError } from '@backstage/errors'; +import { ForwardedError, ConflictError, assertError } from '@backstage/errors'; import { instanceMetadataServiceRef, featureDiscoveryServiceRef, @@ -405,8 +405,9 @@ export class BackendInitializer { // Once the plugin and all modules have been initialized, we can signal that the plugin has stared up successfully const lifecycleService = await this.#getPluginLifecycleImpl(pluginId); await lifecycleService.startup(); - } catch (error) { - initLogger.onPluginFailed(pluginId); + } catch (error: unknown) { + assertError(error); + initLogger.onPluginFailed(pluginId, error); throw error; } }), diff --git a/packages/backend-app-api/src/wiring/createInitializationLogger.ts b/packages/backend-app-api/src/wiring/createInitializationLogger.ts index 2a472dec5b..e623d43074 100644 --- a/packages/backend-app-api/src/wiring/createInitializationLogger.ts +++ b/packages/backend-app-api/src/wiring/createInitializationLogger.ts @@ -27,7 +27,7 @@ export function createInitializationLogger( rootLogger?: RootLoggerService, ): { onPluginStarted(pluginId: string): void; - onPluginFailed(pluginId: string): void; + onPluginFailed(pluginId: string, error: Error): void; onAllStarted(): void; } { const logger = rootLogger?.child({ type: 'initialization' }); @@ -68,14 +68,15 @@ export function createInitializationLogger( starting.delete(pluginId); started.add(pluginId); }, - onPluginFailed(pluginId: string) { + onPluginFailed(pluginId: string, error: Error) { starting.delete(pluginId); const status = starting.size > 0 ? `, waiting for ${starting.size} other plugins to finish before shutting down the process` : ''; logger?.error( - `Plugin '${pluginId}' threw an error during startup${status}`, + `Plugin '${pluginId}' threw an error during startup${status}.`, + error, ); }, onAllStarted() { diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index 4e9e13062d..9f2dcb4914 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/backend-defaults +## 0.8.0-next.0 + +### Minor Changes + +- a4aa244: This change introduces the `auditor` service implementation details. + +### Patch Changes + +- f866b86: Internal refactor to use explicit `require` for lazy-loading dependency. +- a19cb2b: Added default implementation for the new `PermissionsRegistryService`. +- Updated dependencies + - @backstage/cli-node@0.2.13-next.0 + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/config-loader@1.9.6-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/backend-app-api@1.1.2-next.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + ## 0.7.0 ### Minor Changes diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index b9452d05ca..e66d7a06f1 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-defaults", - "version": "0.7.0", + "version": "0.8.0-next.0", "description": "Backend defaults used by Backstage backend apps", "backstage": { "role": "node-library" @@ -20,6 +20,7 @@ "license": "Apache-2.0", "exports": { ".": "./src/index.ts", + "./auditor": "./src/entrypoints/auditor/index.ts", "./auth": "./src/entrypoints/auth/index.ts", "./cache": "./src/entrypoints/cache/index.ts", "./database": "./src/entrypoints/database/index.ts", @@ -44,6 +45,9 @@ "types": "src/index.ts", "typesVersions": { "*": { + "auditor": [ + "src/entrypoints/auditor/index.ts" + ], "auth": [ "src/entrypoints/auth/index.ts" ], diff --git a/packages/backend-defaults/report-auditor.api.md b/packages/backend-defaults/report-auditor.api.md new file mode 100644 index 0000000000..353b6f241f --- /dev/null +++ b/packages/backend-defaults/report-auditor.api.md @@ -0,0 +1,111 @@ +## API Report File for "@backstage/backend-defaults" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { AuditorService } from '@backstage/backend-plugin-api'; +import type { AuditorServiceCreateEventOptions } from '@backstage/backend-plugin-api'; +import type { AuditorServiceEvent } from '@backstage/backend-plugin-api'; +import type { AuditorServiceEventSeverityLevel } from '@backstage/backend-plugin-api'; +import type { AuthService } from '@backstage/backend-plugin-api'; +import type { Format } from 'logform'; +import type { HttpAuthService } from '@backstage/backend-plugin-api'; +import type { JsonObject } from '@backstage/types'; +import type { PluginMetadataService } from '@backstage/backend-plugin-api'; +import type { Request as Request_2 } from 'express'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; +import * as winston from 'winston'; + +// @public +export type AuditorEvent = { + plugin: string; + eventId: string; + severityLevel: AuditorServiceEventSeverityLevel; + actor: AuditorEventActorDetails; + meta?: JsonObject; + request?: AuditorEventRequest; +} & AuditorEventStatus; + +// @public (undocumented) +export type AuditorEventActorDetails = { + actorId?: string; + ip?: string; + hostname?: string; + userAgent?: string; +}; + +// @public +export type AuditorEventOptions = { + eventId: string; + severityLevel?: AuditorServiceEventSeverityLevel; + request?: Request_2; + meta?: TMeta; +} & AuditorEventStatus; + +// @public (undocumented) +export type AuditorEventRequest = { + url: string; + method: string; +}; + +// @public (undocumented) +export type AuditorEventStatus = + | { + status: 'initiated'; + } + | { + status: 'succeeded'; + } + | { + status: 'failed'; + error: string; + }; + +// @public +export type AuditorLogFunction = (event: AuditorEvent) => void | Promise; + +// @public +export const auditorServiceFactory: ServiceFactory< + AuditorService, + 'plugin', + 'singleton' +>; + +// @public +export class DefaultAuditorService implements AuditorService { + static create( + logFn: AuditorLogFunction, + deps: { + auth: AuthService; + httpAuth: HttpAuthService; + plugin: PluginMetadataService; + }, + ): DefaultAuditorService; + // (undocumented) + createEvent( + options: AuditorServiceCreateEventOptions, + ): Promise; +} + +// @public +export class WinstonRootAuditorService { + static create( + options?: WinstonRootAuditorServiceOptions, + ): WinstonRootAuditorService; + // (undocumented) + forPlugin(deps: { + auth: AuthService; + httpAuth: HttpAuthService; + plugin: PluginMetadataService; + }): AuditorService; +} + +// @public +export type WinstonRootAuditorServiceOptions = { + meta?: JsonObject; + format?: Format; + transports?: winston.transport[]; +}; + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/backend-defaults/src/CreateBackend.ts b/packages/backend-defaults/src/CreateBackend.ts index de53409658..d618c94138 100644 --- a/packages/backend-defaults/src/CreateBackend.ts +++ b/packages/backend-defaults/src/CreateBackend.ts @@ -15,6 +15,7 @@ */ import { Backend, createSpecializedBackend } from '@backstage/backend-app-api'; +import { auditorServiceFactory } from '@backstage/backend-defaults/auditor'; import { authServiceFactory } from '@backstage/backend-defaults/auth'; import { cacheServiceFactory } from '@backstage/backend-defaults/cache'; import { databaseServiceFactory } from '@backstage/backend-defaults/database'; @@ -36,6 +37,7 @@ import { userInfoServiceFactory } from '@backstage/backend-defaults/userInfo'; import { eventsServiceFactory } from '@backstage/plugin-events-node'; export const defaultServiceFactories = [ + auditorServiceFactory, authServiceFactory, cacheServiceFactory, rootConfigServiceFactory, diff --git a/packages/backend-defaults/src/entrypoints/auditor/DefaultAuditorService.test.ts b/packages/backend-defaults/src/entrypoints/auditor/DefaultAuditorService.test.ts new file mode 100644 index 0000000000..c960a1daa2 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/auditor/DefaultAuditorService.test.ts @@ -0,0 +1,144 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { mockServices } from '@backstage/backend-test-utils'; +import { DefaultAuditorService } from './DefaultAuditorService'; + +const mockDeps = { + auth: mockServices.auth.mock(), + httpAuth: mockServices.httpAuth.mock(), + plugin: { + getId: () => 'test', + }, +}; + +describe('DefaultAuditorService', () => { + it('creates a auditor instance with default options', () => { + const auditor = DefaultAuditorService.create(jest.fn(), mockDeps); + expect(auditor).toBeInstanceOf(DefaultAuditorService); + }); + + it('should log a status "initiated" using createEvent', async () => { + const logFn = jest.fn(); + const auditor = DefaultAuditorService.create(logFn, mockDeps); + + await auditor.createEvent({ + eventId: 'test-event', + }); + + expect(logFn).toHaveBeenCalledWith({ + eventId: 'test-event', + status: 'initiated', + plugin: 'test', + severityLevel: 'low', + actor: {}, + }); + }); + + it('should log a status "succeeded" using createEvent', async () => { + const logFn = jest.fn(); + const auditor = DefaultAuditorService.create(logFn, mockDeps); + + const auditorEvent = await auditor.createEvent({ + eventId: 'test-event', + }); + + await auditorEvent.success(); + + expect(logFn).toHaveBeenCalledTimes(2); + expect(logFn).toHaveBeenLastCalledWith({ + eventId: 'test-event', + status: 'succeeded', + plugin: 'test', + severityLevel: 'low', + actor: {}, + }); + }); + + it('should log a status "failed"', async () => { + const logFn = jest.fn(); + const auditor = DefaultAuditorService.create(logFn, mockDeps); + + const auditorEvent = await auditor.createEvent({ + eventId: 'test-event', + }); + + const error = new Error('error'); + await auditorEvent.fail({ error }); + + expect(logFn).toHaveBeenCalledTimes(2); + expect(logFn).toHaveBeenLastCalledWith({ + eventId: 'test-event', + status: 'failed', + error: error.toString(), + plugin: 'test', + severityLevel: 'low', + actor: {}, + }); + }); + + it('should use root meta', async () => { + const logFn = jest.fn(); + const auditor = DefaultAuditorService.create(logFn, mockDeps); + + const auditorEvent = await auditor.createEvent({ + eventId: 'test-event', + meta: { + initiated: 'test', + }, + }); + + await auditorEvent.success({ meta: { succeeded: 'test' } }); + + const error = new Error('error'); + await auditorEvent.fail({ error, meta: { failed: 'test' } }); + + expect(logFn).toHaveBeenCalledTimes(3); + expect(logFn).toHaveBeenNthCalledWith(1, { + eventId: 'test-event', + status: 'initiated', + meta: { + initiated: 'test', + }, + plugin: 'test', + severityLevel: 'low', + actor: {}, + }); + expect(logFn).toHaveBeenNthCalledWith(2, { + eventId: 'test-event', + status: 'succeeded', + meta: { + initiated: 'test', + succeeded: 'test', + }, + plugin: 'test', + severityLevel: 'low', + actor: {}, + }); + expect(logFn).toHaveBeenNthCalledWith(3, { + eventId: 'test-event', + status: 'failed', + meta: { + initiated: 'test', + failed: 'test', + }, + error: error.toString(), + plugin: 'test', + severityLevel: 'low', + actor: {}, + }); + }); +}); diff --git a/packages/backend-defaults/src/entrypoints/auditor/DefaultAuditorService.ts b/packages/backend-defaults/src/entrypoints/auditor/DefaultAuditorService.ts new file mode 100644 index 0000000000..79e206e305 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/auditor/DefaultAuditorService.ts @@ -0,0 +1,230 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { + AuditorService, + AuditorServiceCreateEventOptions, + AuditorServiceEvent, + AuditorServiceEventSeverityLevel, + AuthService, + BackstageCredentials, + HttpAuthService, + PluginMetadataService, +} from '@backstage/backend-plugin-api'; +import { ForwardedError } from '@backstage/errors'; +import type { JsonObject } from '@backstage/types'; +import type { Request } from 'express'; + +/** @public */ +export type AuditorEventActorDetails = { + actorId?: string; + ip?: string; + hostname?: string; + userAgent?: string; +}; + +/** @public */ +export type AuditorEventRequest = { + url: string; + method: string; +}; + +/** @public */ +export type AuditorEventStatus = + | { status: 'initiated' } + | { status: 'succeeded' } + | { + status: 'failed'; + error: string; + }; + +/** + * Options for creating an auditor event. + * + * @public + */ +export type AuditorEventOptions = { + /** + * Use kebab-case to name audit events (e.g., "user-login", "file-download"). + * + * The `pluginId` already provides plugin/module context, so avoid redundant prefixes in the `eventId`. + */ + eventId: string; + + severityLevel?: AuditorServiceEventSeverityLevel; + + /** (Optional) The associated HTTP request, if applicable. */ + request?: Request; + + /** (Optional) Additional metadata relevant to the event, structured as a JSON object. */ + meta?: TMeta; +} & AuditorEventStatus; + +/** + * Common fields of an audit event. + * + * @public + */ +export type AuditorEvent = { + plugin: string; + eventId: string; + severityLevel: AuditorServiceEventSeverityLevel; + actor: AuditorEventActorDetails; + meta?: JsonObject; + request?: AuditorEventRequest; +} & AuditorEventStatus; + +/** + * Logging function used by the auditor. + * @public + */ +export type AuditorLogFunction = (event: AuditorEvent) => void | Promise; + +/** + * A {@link @backstage/backend-plugin-api#AuditorService} implementation that logs events using a provided callback. + * + * @public + * + * @example + * ```ts + * export const auditorServiceFactory = createServiceFactory({ + * service: coreServices.auditor, + * deps: { + * logger: coreServices.logger, + * auth: coreServices.auth, + * httpAuth: coreServices.httpAuth, + * plugin: coreServices.pluginMetadata, + * }, + * factory({ logger, plugin, auth, httpAuth }) { + * const auditLogger = logger.child({ isAuditEvent: true }); + * return DefaultAuditorService.create( + * event => auditLogger.info(`${event.plugin}.${event.eventId}`, event), + * { plugin, auth, httpAuth }, + * ); + * }, + * }); + * ``` + */ +export class DefaultAuditorService implements AuditorService { + private readonly logFn: AuditorLogFunction; + private readonly auth: AuthService; + private readonly httpAuth: HttpAuthService; + private readonly plugin: PluginMetadataService; + + private constructor( + logFn: AuditorLogFunction, + deps: { + auth: AuthService; + httpAuth: HttpAuthService; + plugin: PluginMetadataService; + }, + ) { + this.logFn = logFn; + this.auth = deps.auth; + this.httpAuth = deps.httpAuth; + this.plugin = deps.plugin; + } + + /** + * Creates a {@link DefaultAuditorService} instance. + */ + static create( + logFn: AuditorLogFunction, + deps: { + auth: AuthService; + httpAuth: HttpAuthService; + plugin: PluginMetadataService; + }, + ): DefaultAuditorService { + return new DefaultAuditorService(logFn, deps); + } + + private async log( + options: AuditorEventOptions, + ): Promise { + const { eventId, severityLevel = 'low', request, meta, ...rest } = options; + + await this.logFn({ + plugin: this.plugin.getId(), + eventId, + severityLevel, + actor: { + actorId: await this.getActorId(request), + ip: request?.ip, + hostname: request?.hostname, + userAgent: request?.get('user-agent'), + }, + request: request + ? { + url: request?.originalUrl, + method: request?.method, + } + : undefined, + meta: Object.keys(meta ?? {}).length === 0 ? undefined : meta, + ...rest, + }); + } + + async createEvent( + options: AuditorServiceCreateEventOptions, + ): Promise { + await this.log({ ...options, status: 'initiated' }); + + return { + success: async params => { + await this.log({ + ...options, + meta: { ...options.meta, ...params?.meta }, + status: 'succeeded', + }); + }, + fail: async params => { + await this.log({ + ...options, + ...params, + error: String(params.error), + meta: { ...options.meta, ...params?.meta }, + status: 'failed', + }); + }, + }; + } + + private async getActorId( + request?: Request, + ): Promise { + let credentials: BackstageCredentials = + await this.auth.getOwnServiceCredentials(); + + if (request) { + try { + credentials = await this.httpAuth.credentials(request); + } catch (error) { + throw new ForwardedError('Could not resolve credentials', error); + } + } + + if (this.auth.isPrincipal(credentials, 'user')) { + return credentials.principal.userEntityRef; + } + + if (this.auth.isPrincipal(credentials, 'service')) { + return credentials.principal.subject; + } + + return undefined; + } +} diff --git a/packages/backend-defaults/src/entrypoints/auditor/WinstonRootAuditorService.test.ts b/packages/backend-defaults/src/entrypoints/auditor/WinstonRootAuditorService.test.ts new file mode 100644 index 0000000000..2d9a959c64 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/auditor/WinstonRootAuditorService.test.ts @@ -0,0 +1,169 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { mockServices } from '@backstage/backend-test-utils'; +import { WinstonRootAuditorService } from './WinstonRootAuditorService'; +import { DefaultAuditorService } from './DefaultAuditorService'; + +describe('WinstonRootAuditorService', () => { + it('creates a auditor instance with default options', () => { + const auditor = WinstonRootAuditorService.create(); + expect(auditor).toBeInstanceOf(WinstonRootAuditorService); + }); + + it('creates a child logger', () => { + const auditor = WinstonRootAuditorService.create(); + const childLogger = auditor.forPlugin({ + auth: mockServices.auth.mock(), + httpAuth: mockServices.httpAuth.mock(), + plugin: { + getId: () => 'test-plugin', + }, + }); + expect(childLogger).toBeInstanceOf(DefaultAuditorService); + }); + + it('should log a status "initiated" using createEvent', async () => { + const pluginId = 'test-plugin'; + + const auditor = WinstonRootAuditorService.create().forPlugin({ + auth: mockServices.auth.mock(), + httpAuth: mockServices.httpAuth.mock(), + plugin: { + getId: () => pluginId, + }, + }); + // workaround to spy on private method + const auditorSpy = jest.spyOn(auditor as any, 'log'); + + await auditor.createEvent({ + eventId: 'test-event', + }); + + expect(auditorSpy).toHaveBeenCalledWith({ + eventId: 'test-event', + status: 'initiated', + }); + }); + + it('should log a status "succeeded" using createEvent', async () => { + const pluginId = 'test-plugin'; + + const auditor = WinstonRootAuditorService.create().forPlugin({ + auth: mockServices.auth.mock(), + httpAuth: mockServices.httpAuth.mock(), + plugin: { + getId: () => pluginId, + }, + }); + // workaround to spy on private method + const auditorSpy = jest.spyOn(auditor as any, 'log'); + + const auditorEvent = await auditor.createEvent({ + eventId: 'test-event', + }); + + await auditorEvent.success(); + + expect(auditorSpy).toHaveBeenCalledTimes(2); + expect(auditorSpy).toHaveBeenLastCalledWith({ + eventId: 'test-event', + meta: {}, + status: 'succeeded', + }); + }); + + it('should log a status "failed"', async () => { + const pluginId = 'test-plugin'; + + const auditor = WinstonRootAuditorService.create().forPlugin({ + auth: mockServices.auth.mock(), + httpAuth: mockServices.httpAuth.mock(), + plugin: { + getId: () => pluginId, + }, + }); + // workaround to spy on private method + const auditorSpy = jest.spyOn(auditor as any, 'log'); + + const auditorEvent = await auditor.createEvent({ + eventId: 'test-event', + }); + + const error = new Error('error'); + await auditorEvent.fail({ error }); + + expect(auditorSpy).toHaveBeenCalledTimes(2); + expect(auditorSpy).toHaveBeenLastCalledWith({ + eventId: 'test-event', + meta: {}, + status: 'failed', + error: error.toString(), + }); + }); + + it('should use root meta', async () => { + const pluginId = 'test-plugin'; + + const auditor = WinstonRootAuditorService.create().forPlugin({ + auth: mockServices.auth.mock(), + httpAuth: mockServices.httpAuth.mock(), + plugin: { + getId: () => pluginId, + }, + }); + // workaround to spy on private method + const auditorSpy = jest.spyOn(auditor as any, 'log'); + + const auditorEvent = await auditor.createEvent({ + eventId: 'test-event', + meta: { + initiated: 'test', + }, + }); + + await auditorEvent.success({ meta: { succeeded: 'test' } }); + + const error = new Error('error'); + await auditorEvent.fail({ error, meta: { failed: 'test' } }); + + expect(auditorSpy).toHaveBeenCalledTimes(3); + expect(auditorSpy).toHaveBeenNthCalledWith(1, { + eventId: 'test-event', + status: 'initiated', + meta: { + initiated: 'test', + }, + }); + expect(auditorSpy).toHaveBeenNthCalledWith(2, { + eventId: 'test-event', + status: 'succeeded', + meta: { + initiated: 'test', + succeeded: 'test', + }, + }); + expect(auditorSpy).toHaveBeenNthCalledWith(3, { + eventId: 'test-event', + status: 'failed', + meta: { + initiated: 'test', + failed: 'test', + }, + error: error.toString(), + }); + }); +}); diff --git a/packages/backend-defaults/src/entrypoints/auditor/WinstonRootAuditorService.ts b/packages/backend-defaults/src/entrypoints/auditor/WinstonRootAuditorService.ts new file mode 100644 index 0000000000..6ea5d02606 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/auditor/WinstonRootAuditorService.ts @@ -0,0 +1,119 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { + AuditorService, + AuthService, + HttpAuthService, + PluginMetadataService, +} from '@backstage/backend-plugin-api'; +import type { JsonObject } from '@backstage/types'; +import type { Format } from 'logform'; +import * as winston from 'winston'; +import { WinstonLogger } from '../rootLogger'; +import { DefaultAuditorService } from './DefaultAuditorService'; + +/** @public */ +export const defaultFormatter = winston.format.combine( + winston.format.timestamp({ + format: 'YYYY-MM-DD HH:mm:ss', + }), + winston.format.errors({ stack: true }), + winston.format.splat(), + winston.format.json(), +); + +/** + * Adds `isAuditEvent` field + * + * @public + */ +export const auditorFieldFormat = winston.format(info => { + return { ...info, isAuditEvent: true }; +})(); + +/** + * Options for creating a {@link WinstonRootAuditorService}. + * @public + */ +export type WinstonRootAuditorServiceOptions = { + meta?: JsonObject; + format?: Format; + transports?: winston.transport[]; +}; + +/** + * An implementation of the {@link @backstage/backend-plugin-api#AuditorService} that logs events using a separate winston logger. + * + * @public + * + * @example + * ```ts + * export const auditorServiceFactory = createServiceFactory({ + * service: coreServices.auditor, + * deps: { + * auth: coreServices.auth, + * httpAuth: coreServices.httpAuth, + * plugin: coreServices.pluginMetadata, + * }, + * createRootContext() { + * return WinstonRootAuditorService.create(); + * }, + * factory({ plugin, auth, httpAuth }, root) { + * return root.forPlugin({ plugin, auth, httpAuth }); + * }, + * }); + * ``` + */ +export class WinstonRootAuditorService { + private constructor(private readonly winstonLogger: WinstonLogger) {} + + /** + * Creates a {@link WinstonRootAuditorService} instance. + */ + static create( + options?: WinstonRootAuditorServiceOptions, + ): WinstonRootAuditorService { + let winstonLogger = WinstonLogger.create({ + meta: { + service: 'backstage', + }, + level: 'info', + format: winston.format.combine( + auditorFieldFormat, + options?.format ?? defaultFormatter, + ), + transports: options?.transports, + }); + + if (options?.meta) { + winstonLogger = winstonLogger.child(options.meta) as WinstonLogger; + } + + return new WinstonRootAuditorService(winstonLogger); + } + + forPlugin(deps: { + auth: AuthService; + httpAuth: HttpAuthService; + plugin: PluginMetadataService; + }): AuditorService { + return DefaultAuditorService.create( + e => this.winstonLogger.info(`${e.plugin}.${e.eventId}`, e), + deps, + ); + } +} diff --git a/packages/backend-defaults/src/entrypoints/auditor/auditorServiceFactory.ts b/packages/backend-defaults/src/entrypoints/auditor/auditorServiceFactory.ts new file mode 100644 index 0000000000..1323ac5d76 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/auditor/auditorServiceFactory.ts @@ -0,0 +1,47 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + coreServices, + createServiceFactory, +} from '@backstage/backend-plugin-api'; +import { DefaultAuditorService } from './DefaultAuditorService'; + +/** + * Plugin-level auditing. + * + * See {@link @backstage/code-plugin-api#AuditorService} + * and {@link https://backstage.io/docs/backend-system/core-services/auditor | the service docs} + * for more information. + * + * @public + */ +export const auditorServiceFactory = createServiceFactory({ + service: coreServices.auditor, + deps: { + logger: coreServices.logger, + auth: coreServices.auth, + httpAuth: coreServices.httpAuth, + plugin: coreServices.pluginMetadata, + }, + factory({ logger, plugin, auth, httpAuth }) { + const auditLogger = logger.child({ isAuditEvent: true }); + return DefaultAuditorService.create( + event => auditLogger.info(`${event.plugin}.${event.eventId}`, event), + { plugin, auth, httpAuth }, + ); + }, +}); diff --git a/packages/backend-defaults/src/entrypoints/auditor/index.ts b/packages/backend-defaults/src/entrypoints/auditor/index.ts new file mode 100644 index 0000000000..3231c6a571 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/auditor/index.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export type { + AuditorEvent, + AuditorEventActorDetails, + AuditorEventOptions, + AuditorEventRequest, + AuditorEventStatus, + AuditorLogFunction, +} from './DefaultAuditorService'; +export { DefaultAuditorService } from './DefaultAuditorService'; +export { auditorServiceFactory } from './auditorServiceFactory'; +export { WinstonRootAuditorService } from './WinstonRootAuditorService'; +export type { WinstonRootAuditorServiceOptions } from './WinstonRootAuditorService'; diff --git a/packages/backend-dynamic-feature-service/CHANGELOG.md b/packages/backend-dynamic-feature-service/CHANGELOG.md index 5a6c944b96..31c18fa2ad 100644 --- a/packages/backend-dynamic-feature-service/CHANGELOG.md +++ b/packages/backend-dynamic-feature-service/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/backend-dynamic-feature-service +## 0.5.4-next.0 + +### Patch Changes + +- 96c20cd: Make sure changes are successfully tracked before starting up scanner. +- Updated dependencies + - @backstage/cli-node@0.2.13-next.0 + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/config-loader@1.9.6-next.0 + - @backstage/plugin-catalog-backend@1.31.0-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.7.0-next.0 + - @backstage/backend-app-api@1.1.2-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.30-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-events-backend@0.4.2-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + - @backstage/plugin-permission-common@0.8.4 + - @backstage/plugin-search-backend-node@1.3.8-next.0 + - @backstage/plugin-search-common@1.2.17 + ## 0.5.3 ### Patch Changes diff --git a/packages/backend-dynamic-feature-service/package.json b/packages/backend-dynamic-feature-service/package.json index 7737bd7dd3..f30c57f90b 100644 --- a/packages/backend-dynamic-feature-service/package.json +++ b/packages/backend-dynamic-feature-service/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-dynamic-feature-service", - "version": "0.5.3", + "version": "0.5.4-next.0", "description": "Backstage dynamic feature service", "backstage": { "role": "node-library" diff --git a/packages/backend-legacy/CHANGELOG.md b/packages/backend-legacy/CHANGELOG.md index 75d8c6aee4..ea646c22ba 100644 --- a/packages/backend-legacy/CHANGELOG.md +++ b/packages/backend-legacy/CHANGELOG.md @@ -1,5 +1,45 @@ # example-backend-legacy +## 0.2.107-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/plugin-catalog-backend@1.31.0-next.0 + - @backstage/plugin-kubernetes-backend@0.19.3-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.5-next.0 + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-backend@1.30.0-next.0 + - @backstage/plugin-search-backend-module-catalog@0.3.1-next.0 + - @backstage/plugin-permission-backend@0.5.54-next.0 + - @backstage/plugin-search-backend@1.8.2-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration@1.16.1 + - @backstage/plugin-app-backend@0.4.5-next.0 + - @backstage/plugin-auth-backend@0.24.3-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.5-next.0 + - @backstage/plugin-events-backend@0.4.2-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + - @backstage/plugin-permission-common@0.8.4 + - @backstage/plugin-proxy-backend@0.5.11-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.6-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.7.2-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.5.6-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.6.5-next.0 + - @backstage/plugin-search-backend-module-explore@0.2.8-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.41-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.3.6-next.0 + - @backstage/plugin-search-backend-node@1.3.8-next.0 + - @backstage/plugin-signals-backend@0.3.1-next.0 + - @backstage/plugin-signals-node@0.1.17-next.0 + - @backstage/plugin-techdocs-backend@1.11.6-next.0 + ## 0.2.106 ### Patch Changes diff --git a/packages/backend-legacy/package.json b/packages/backend-legacy/package.json index 20c8f30223..b3f71edb1e 100644 --- a/packages/backend-legacy/package.json +++ b/packages/backend-legacy/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-legacy", - "version": "0.2.106", + "version": "0.2.107-next.0", "backstage": { "role": "backend" }, diff --git a/packages/backend-openapi-utils/CHANGELOG.md b/packages/backend-openapi-utils/CHANGELOG.md index b36bca9ce2..38805bb484 100644 --- a/packages/backend-openapi-utils/CHANGELOG.md +++ b/packages/backend-openapi-utils/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/backend-openapi-utils +## 0.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + ## 0.4.1 ### Patch Changes diff --git a/packages/backend-openapi-utils/package.json b/packages/backend-openapi-utils/package.json index bc49759d75..4453d4338a 100644 --- a/packages/backend-openapi-utils/package.json +++ b/packages/backend-openapi-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-openapi-utils", - "version": "0.4.1", + "version": "0.4.2-next.0", "description": "OpenAPI typescript support.", "backstage": { "role": "node-library" diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md index f9f9f66954..54f195ca71 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/backend-plugin-api +## 1.2.0-next.0 + +### Minor Changes + +- a4aa244: This change introduces the `auditor` service definition. + +### Patch Changes + +- 9ddfd94: Added new `PermissionsRegistryService` that is used by plugins to register permissions, resource types, and rules into the permission system. This replaces the existing `createPermissionIntegrationRouter` from `@backstage/plugin-permission-node`. +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-permission-common@0.8.4 + ## 1.1.1 ### Patch Changes diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index ca051e3bc0..9c78a6cd15 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-plugin-api", - "version": "1.1.1", + "version": "1.2.0-next.0", "description": "Core API used by Backstage backend plugins", "backstage": { "role": "node-library" diff --git a/packages/backend-plugin-api/report.api.md b/packages/backend-plugin-api/report.api.md index 82b62b4de0..a4f9b9fa1d 100644 --- a/packages/backend-plugin-api/report.api.md +++ b/packages/backend-plugin-api/report.api.md @@ -26,6 +26,35 @@ import { Readable } from 'stream'; import type { Request as Request_2 } from 'express'; import type { Response as Response_2 } from 'express'; +// @public +export interface AuditorService { + // (undocumented) + createEvent( + options: AuditorServiceCreateEventOptions, + ): Promise; +} + +// @public (undocumented) +export type AuditorServiceCreateEventOptions = { + eventId: string; + severityLevel?: AuditorServiceEventSeverityLevel; + request?: Request_2; + meta?: JsonObject; +}; + +// @public (undocumented) +export type AuditorServiceEvent = { + success(options?: { meta?: JsonObject }): Promise; + fail(options: { meta?: JsonObject; error: Error }): Promise; +}; + +// @public +export type AuditorServiceEventSeverityLevel = + | 'low' + | 'medium' + | 'high' + | 'critical'; + // @public export interface AuthService { authenticate( @@ -185,6 +214,7 @@ export namespace coreServices { const httpRouter: ServiceRef; const lifecycle: ServiceRef; const logger: ServiceRef; + const auditor: ServiceRef; const permissions: ServiceRef; const permissionsRegistry: ServiceRef< PermissionsRegistryService, diff --git a/packages/backend-plugin-api/src/services/definitions/AuditorService.ts b/packages/backend-plugin-api/src/services/definitions/AuditorService.ts new file mode 100644 index 0000000000..c98fe65df3 --- /dev/null +++ b/packages/backend-plugin-api/src/services/definitions/AuditorService.ts @@ -0,0 +1,73 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { JsonObject } from '@backstage/types'; +import type { Request } from 'express'; + +/** + * low (default): normal usage + * medium: accessing write endpoints + * high: non-root permission changes + * critical: root permission changes + * @public + */ +export type AuditorServiceEventSeverityLevel = + | 'low' + | 'medium' + | 'high' + | 'critical'; + +/** @public */ +export type AuditorServiceCreateEventOptions = { + /** + * Use kebab-case to name audit events (e.g., "user-login", "file-download", "fetch"). Represents a logical group of similar events or operations. For example, "fetch" could be used as an eventId encompassing various fetch methods like "by-id" or "by-location". + * + * The `pluginId` already provides plugin/module context, so avoid redundant prefixes in the `eventId`. + */ + eventId: string; + + /** (Optional) The severity level for the audit event. */ + severityLevel?: AuditorServiceEventSeverityLevel; + + /** (Optional) The associated HTTP request, if applicable. */ + request?: Request; + + /** + * (Optional) Additional metadata relevant to the event, structured as a JSON object. + * This could include a `queryType` field, using kebab-case, for variations within the main event (e.g., "by-id", "by-user"). + * For example, if the `eventId` is "fetch", the `queryType` in `meta` could be "by-id" or "by-location". + */ + meta?: JsonObject; +}; + +/** @public */ +export type AuditorServiceEvent = { + success(options?: { meta?: JsonObject }): Promise; + fail(options: { meta?: JsonObject; error: Error }): Promise; +}; + +/** + * A service that provides an auditor facility. + * + * See the {@link https://backstage.io/docs/backend-system/core-services/auditor | service documentation} for more details. + * + * @public + */ +export interface AuditorService { + createEvent( + options: AuditorServiceCreateEventOptions, + ): Promise; +} diff --git a/packages/backend-plugin-api/src/services/definitions/coreServices.ts b/packages/backend-plugin-api/src/services/definitions/coreServices.ts index 52adaefd53..8c8c6c0f82 100644 --- a/packages/backend-plugin-api/src/services/definitions/coreServices.ts +++ b/packages/backend-plugin-api/src/services/definitions/coreServices.ts @@ -161,6 +161,19 @@ export namespace coreServices { import('./LoggerService').LoggerService >({ id: 'core.logger' }); + /** + * Plugin-level auditing. + * + * See {@link AuditorService} + * and {@link https://backstage.io/docs/backend-system/core-services/auditor | the service docs} + * for more information. + * + * @public + */ + export const auditor = createServiceRef< + import('./AuditorService').AuditorService + >({ id: 'core.auditor' }); + /** * Permission system integration for authorization of user actions. * diff --git a/packages/backend-plugin-api/src/services/definitions/index.ts b/packages/backend-plugin-api/src/services/definitions/index.ts index 95cd37a089..d6346cbe4e 100644 --- a/packages/backend-plugin-api/src/services/definitions/index.ts +++ b/packages/backend-plugin-api/src/services/definitions/index.ts @@ -14,36 +14,39 @@ * limitations under the License. */ -export { coreServices } from './coreServices'; +export type { + AuditorService, + AuditorServiceCreateEventOptions, + AuditorServiceEvent, + AuditorServiceEventSeverityLevel, +} from './AuditorService'; export type { AuthService, BackstageCredentials, - BackstageUserPrincipal, - BackstageServicePrincipal, + BackstageNonePrincipal, BackstagePrincipalAccessRestrictions, BackstagePrincipalTypes, - BackstageNonePrincipal, + BackstageServicePrincipal, + BackstageUserPrincipal, } from './AuthService'; export type { CacheService, CacheServiceOptions, CacheServiceSetOptions, } from './CacheService'; -export type { RootConfigService } from './RootConfigService'; export type { DatabaseService } from './DatabaseService'; export type { DiscoveryService } from './DiscoveryService'; -export type { RootHealthService } from './RootHealthService'; +export type { HttpAuthService } from './HttpAuthService'; export type { HttpRouterService, HttpRouterServiceAuthPolicy, } from './HttpRouterService'; -export type { HttpAuthService } from './HttpAuthService'; export type { LifecycleService, - LifecycleServiceStartupHook, - LifecycleServiceStartupOptions, LifecycleServiceShutdownHook, LifecycleServiceShutdownOptions, + LifecycleServiceStartupHook, + LifecycleServiceStartupOptions, } from './LifecycleService'; export type { LoggerService } from './LoggerService'; export type { @@ -55,6 +58,8 @@ export type { PermissionsRegistryServiceAddResourceTypeOptions, } from './PermissionsRegistryService'; export type { PluginMetadataService } from './PluginMetadataService'; +export type { RootConfigService } from './RootConfigService'; +export type { RootHealthService } from './RootHealthService'; export type { RootHttpRouterService } from './RootHttpRouterService'; export type { RootLifecycleService } from './RootLifecycleService'; export type { RootLoggerService } from './RootLoggerService'; @@ -69,15 +74,16 @@ export type { SchedulerServiceTaskScheduleDefinitionConfig, } from './SchedulerService'; export type { + UrlReaderService, UrlReaderServiceReadTreeOptions, UrlReaderServiceReadTreeResponse, UrlReaderServiceReadTreeResponseDirOptions, UrlReaderServiceReadTreeResponseFile, - UrlReaderServiceReadUrlResponse, UrlReaderServiceReadUrlOptions, + UrlReaderServiceReadUrlResponse, UrlReaderServiceSearchOptions, UrlReaderServiceSearchResponse, UrlReaderServiceSearchResponseFile, - UrlReaderService, } from './UrlReaderService'; export type { BackstageUserInfo, UserInfoService } from './UserInfoService'; +export { coreServices } from './coreServices'; diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index 9f4fda8306..f0d59590a8 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/backend-test-utils +## 1.3.0-next.0 + +### Minor Changes + +- dd05a97: Added mocks for the new `PermissionsRegistryService`. +- a4aa244: This change introduces mocks for the `auditor` service. + +### Patch Changes + +- f866b86: Internal refactor to use explicit `require` for lazy-loading dependency. +- fb051f2: Sync feature installation compatibility logic with `@backstage/backend-app-api`. +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/backend-app-api@1.1.2-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-events-node@0.4.8-next.0 + ## 1.2.1 ### Patch Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 2f49179273..030f470557 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-test-utils", - "version": "1.2.1", + "version": "1.3.0-next.0", "description": "Test helpers library for Backstage backends", "backstage": { "role": "node-library" diff --git a/packages/backend-test-utils/report.api.md b/packages/backend-test-utils/report.api.md index e6f0667535..b358b268dc 100644 --- a/packages/backend-test-utils/report.api.md +++ b/packages/backend-test-utils/report.api.md @@ -8,6 +8,7 @@ /// /// +import { AuditorService } from '@backstage/backend-plugin-api'; import { AuthService } from '@backstage/backend-plugin-api'; import { Backend } from '@backstage/backend-app-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; @@ -153,6 +154,15 @@ export function mockErrorHandler(): ErrorRequestHandler< // @public export namespace mockServices { + // (undocumented) + export namespace auditor { + const // (undocumented) + factory: () => ServiceFactory; + const // (undocumented) + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; + } // (undocumented) export function auth(options?: { pluginId?: string; diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/next/services/mockServices.ts index 91b53c4acc..15026d5dda 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/next/services/mockServices.ts @@ -21,6 +21,7 @@ import { httpRouterServiceFactory } from '@backstage/backend-defaults/httpRouter import { lifecycleServiceFactory } from '@backstage/backend-defaults/lifecycle'; import { loggerServiceFactory } from '@backstage/backend-defaults/logger'; import { permissionsServiceFactory } from '@backstage/backend-defaults/permissions'; +import { permissionsRegistryServiceFactory } from '@backstage/backend-defaults/permissionsRegistry'; import { rootHealthServiceFactory } from '@backstage/backend-defaults/rootHealth'; import { rootHttpRouterServiceFactory } from '@backstage/backend-defaults/rootHttpRouter'; import { rootLifecycleServiceFactory } from '@backstage/backend-defaults/rootLifecycle'; @@ -47,13 +48,13 @@ import { eventsServiceRef, } from '@backstage/plugin-events-node'; import { JsonObject } from '@backstage/types'; +import { Knex } from 'knex'; import { MockAuthService } from './MockAuthService'; import { MockHttpAuthService } from './MockHttpAuthService'; import { MockRootLoggerService } from './MockRootLoggerService'; import { MockUserInfoService } from './MockUserInfoService'; import { mockCredentials } from './mockCredentials'; -import { Knex } from 'knex'; -import { permissionsRegistryServiceFactory } from '@backstage/backend-defaults/permissionsRegistry'; +import { auditorServiceFactory } from '@backstage/backend-defaults/auditor'; /** @internal */ function createLoggerMock() { @@ -221,6 +222,19 @@ export namespace mockServices { })); } + export namespace auditor { + export const factory = () => auditorServiceFactory; + + export const mock = simpleMock(coreServices.auditor, () => ({ + createEvent: jest.fn(async _ => { + return { + success: jest.fn(), + fail: jest.fn(), + }; + }), + })); + } + export function auth(options?: { pluginId?: string; disableDefaultAuthPolicy?: boolean; diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.ts index c8190b734b..20d02cf880 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.ts +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.ts @@ -67,6 +67,7 @@ export interface TestBackend extends Backend { export const defaultServiceFactories = [ mockServices.auth.factory(), + mockServices.auditor.factory(), mockServices.cache.factory(), mockServices.rootConfig.factory(), mockServices.database.factory(), diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 0998097c73..7ac873d818 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,43 @@ # example-backend +## 0.0.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.8-next.0 + - @backstage/plugin-notifications-backend@0.5.2-next.0 + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/plugin-catalog-backend@1.31.0-next.0 + - @backstage/plugin-kubernetes-backend@0.19.3-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.5-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/plugin-scaffolder-backend@1.30.0-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.7-next.0 + - @backstage/plugin-search-backend-module-catalog@0.3.1-next.0 + - @backstage/plugin-devtools-backend@0.5.2-next.0 + - @backstage/plugin-permission-backend@0.5.54-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.5-next.0 + - @backstage/plugin-search-backend@1.8.2-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/plugin-app-backend@0.4.5-next.0 + - @backstage/plugin-auth-backend@0.24.3-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.5-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.5-next.0 + - @backstage/plugin-auth-node@0.5.7-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.5-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.5-next.0 + - @backstage/plugin-events-backend@0.4.2-next.0 + - @backstage/plugin-permission-common@0.8.4 + - @backstage/plugin-proxy-backend@0.5.11-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.5.6-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.7-next.0 + - @backstage/plugin-search-backend-module-explore@0.2.8-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.3.6-next.0 + - @backstage/plugin-search-backend-node@1.3.8-next.0 + - @backstage/plugin-signals-backend@0.3.1-next.0 + - @backstage/plugin-techdocs-backend@1.11.6-next.0 + ## 0.0.34 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index 120a202bd8..0cf4567667 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.0.34", + "version": "0.0.35-next.0", "backstage": { "role": "backend" }, diff --git a/packages/canon/.storybook/preview.tsx b/packages/canon/.storybook/preview.tsx index 867461818b..fbc319ccea 100644 --- a/packages/canon/.storybook/preview.tsx +++ b/packages/canon/.storybook/preview.tsx @@ -29,43 +29,43 @@ const preview: Preview = { }, viewport: { viewports: { - xs: { - name: 'XSmall', + initial: { + name: 'Initial', styles: { width: '320px', height: '100%', }, }, - small: { - name: 'Small', + xs: { + name: 'Extra Small', styles: { width: '640px', height: '100%', }, }, - medium: { - name: 'Medium', + sm: { + name: 'Small', styles: { width: '768px', height: '100%', }, }, - large: { - name: 'Large', + md: { + name: 'Medium', styles: { width: '1024px', height: '100%', }, }, - xlarge: { - name: 'XLarge', + lg: { + name: 'Large', styles: { width: '1280px', height: '100%', }, }, - '2xl': { - name: '2XL', + xl: { + name: 'Extra Large', styles: { width: '1536px', height: '100%', @@ -85,12 +85,11 @@ const preview: Preview = { defaultTheme: 'Light', }), Story => { - document.body.style.backgroundColor = 'var(--canon-background)'; + document.body.style.backgroundColor = 'var(--canon-bg)'; const docsStoryElements = document.getElementsByClassName('docs-story'); Array.from(docsStoryElements).forEach(element => { - (element as HTMLElement).style.backgroundColor = - 'var(--canon-background)'; + (element as HTMLElement).style.backgroundColor = 'var(--canon-bg)'; }); return ( diff --git a/packages/canon/.storybook/themes/backstage.css b/packages/canon/.storybook/themes/backstage.css index 3e8cc85a56..92884fa4e7 100644 --- a/packages/canon/.storybook/themes/backstage.css +++ b/packages/canon/.storybook/themes/backstage.css @@ -54,35 +54,35 @@ [data-theme-name='legacy'][data-theme='light'] { /* Colors */ - --canon-accent: #2e77d0; - --canon-background: #f8f8f8; - --canon-surface-1: #fff; - --canon-surface-2: #f4f4f4; + --canon-bg-accent: #2e77d0; + --canon-bg: #f8f8f8; + --canon-bg-elevated: #fff; + --canon-bg: #f4f4f4; /* Text colors */ --canon-text-primary: #000; - --canon-text-primary-on-accent: #fff; + --canon-fg-accent: #fff; --canon-text-secondary: #646464; } [data-theme-name='legacy'][data-theme='dark'] { /* Colors */ - --canon-accent: #fff; - --canon-background: #000; - --canon-surface-1: #121212; - --canon-surface-2: #1a1a1a; + --canon-bg-accent: #fff; + --canon-bg: #000; + --canon-bg-elevated: #121212; + --canon-bg: #1a1a1a; /* Borders */ - --canon-border-base: rgba(255, 255, 255, 0.2); + --canon-border: rgba(255, 255, 255, 0.2); --canon-border-warning: #f50000; - --canon-border-error: #f87503; - --canon-border-selected: #25d262; + --canon-border-danger: #f87503; + --canon-border-focus: #25d262; /* States - Add more states */ - --canon-error: #f50000; + --canon-fg-danger: #f50000; /* Text colors */ --canon-text-primary: #fff; - --canon-text-primary-on-accent: #000; + --canon-fg-accent: #000; --canon-text-secondary: #b3b3b3; } diff --git a/packages/canon/CHANGELOG.md b/packages/canon/CHANGELOG.md new file mode 100644 index 0000000000..ea2b912e5d --- /dev/null +++ b/packages/canon/CHANGELOG.md @@ -0,0 +1,7 @@ +# @backstage/canon + +## 0.1.0-next.0 + +### Minor Changes + +- 65f4acc: This is the first alpha release for Canon. As part of this release we are introducing 5 layout components and 7 components. All theming is done through CSS variables. diff --git a/packages/canon/README.md b/packages/canon/README.md index a8bf36d7be..0783d01736 100644 --- a/packages/canon/README.md +++ b/packages/canon/README.md @@ -1,6 +1,6 @@ # @backstage/canon -_This package was created through the Backstage CLI_. +Canon is a UI component library for Backstage. ## Installation @@ -10,3 +10,9 @@ Install the package via Yarn: cd # if within a monorepo yarn add @backstage/canon ``` + +## Documentation + +- [Canon Documentation](https://canon.backstage.io) +- [Backstage Readme](https://github.com/backstage/backstage/blob/master/README.md) +- [Backstage Documentation](https://backstage.io/docs) diff --git a/packages/canon/package.json b/packages/canon/package.json index eb2cfff709..2ac1189ea3 100644 --- a/packages/canon/package.json +++ b/packages/canon/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/canon", - "version": "0.0.0", + "version": "0.1.0-next.0", "backstage": { "role": "web-library" }, @@ -9,11 +9,10 @@ "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "private": true, "keywords": [ "backstage" ], - "homepage": "https://backstage.io", + "homepage": "https://canon.backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", @@ -28,9 +27,9 @@ ], "scripts": { "build": "yarn build:app && yarn build:css", - "build-storybook": "storybook build", "build:app": "backstage-cli package build", "build:css": "node scripts/build-css.mjs", + "build-storybook": "storybook build", "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", diff --git a/packages/canon/report.api.md b/packages/canon/report.api.md index 0c8abe0cc1..8899f6ad45 100644 --- a/packages/canon/report.api.md +++ b/packages/canon/report.api.md @@ -68,7 +68,7 @@ export interface BoxProps extends UtilityProps { } // @public (undocumented) -export type Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'; +export type Breakpoint = 'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'; // @public (undocumented) export const Button: React_2.ForwardRefExoticComponent< @@ -101,12 +101,6 @@ export interface ButtonProps { // @public (undocumented) export interface CanonContextProps { - // (undocumented) - breakpoint: Breakpoint; - // (undocumented) - getResponsiveValue: ( - value: string | Partial>, - ) => string; // (undocumented) icons: IconMap; } diff --git a/packages/canon/src/components/Box/Box.stories.tsx b/packages/canon/src/components/Box/Box.stories.tsx index d11f9fbab7..bf4b8ae5de 100644 --- a/packages/canon/src/components/Box/Box.stories.tsx +++ b/packages/canon/src/components/Box/Box.stories.tsx @@ -382,7 +382,7 @@ export const BorderRadius: Story = { export const Border: Story = { args: { style: { - background: 'var(--canon-surface-1)', + background: 'var(--canon-bg-elevated)', color: 'var(--canon-text-primary)', padding: '4px 8px', width: '80px', diff --git a/packages/canon/src/components/Button/Button.stories.tsx b/packages/canon/src/components/Button/Button.stories.tsx index 728098970c..8661dc927d 100644 --- a/packages/canon/src/components/Button/Button.stories.tsx +++ b/packages/canon/src/components/Button/Button.stories.tsx @@ -114,7 +114,7 @@ export const Responsive: Story = { args: { children: 'Button', variant: { - xs: 'primary', + initial: 'primary', sm: 'secondary', md: 'tertiary', }, diff --git a/packages/canon/src/components/Button/Button.tsx b/packages/canon/src/components/Button/Button.tsx index 2e2371f82a..c44d81dc15 100644 --- a/packages/canon/src/components/Button/Button.tsx +++ b/packages/canon/src/components/Button/Button.tsx @@ -18,9 +18,10 @@ import React, { forwardRef } from 'react'; import { Icon } from '../Icon'; -import { ButtonProps } from './types'; -import { useCanon } from '../../contexts/canon'; import clsx from 'clsx'; +import { useResponsiveValue } from '../../hooks/useResponsiveValue'; + +import type { ButtonProps } from './types'; /** @public */ export const Button = forwardRef( @@ -37,11 +38,9 @@ export const Button = forwardRef( ...rest } = props; - const { getResponsiveValue } = useCanon(); - // Get the responsive value for the variant - const responsiveSize = getResponsiveValue(size); - const responsiveVariant = getResponsiveValue(variant); + const responsiveSize = useResponsiveValue(size); + const responsiveVariant = useResponsiveValue(variant); return (