diff --git a/.changeset/nice-actors-cheer.md b/.changeset/nice-actors-cheer.md new file mode 100644 index 0000000000..918148ffb8 --- /dev/null +++ b/.changeset/nice-actors-cheer.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': patch +--- + +Adding a more sensible default order to the default filters diff --git a/.changeset/orange-poems-report.md b/.changeset/orange-poems-report.md deleted file mode 100644 index e93a7e8209..0000000000 --- a/.changeset/orange-poems-report.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -Adjusted the sticky scrolling of the new entity layout so that the info columns scrolls to the bottom more eagerly. diff --git a/.changeset/twenty-pumas-brush.md b/.changeset/twenty-pumas-brush.md new file mode 100644 index 0000000000..6306fe0607 --- /dev/null +++ b/.changeset/twenty-pumas-brush.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Adds onTabSelectionChange to ui header component. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 3147b02566..4f0e0ac47d 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -20,6 +20,8 @@ Before any of these commands can be run, you need to run `yarn install` in the p - Lint: Use `yarn lint --fix` in the project root to run the linter. - API reports: Before submitting a pull request with changes to any package in the workspace, run `yarn build:api-reports` in the project root to generate API reports for all packages. +You MUST NOT create a release by running `yarn changesets version` or `yarn release` as part of any changes. Releases are created by separate workflows. + All changes that affect the published version of packages in the `/packages` and `/plugins` directories must be accompanied by a changeset. See the guidelines in `/REVIEWING.md` for information on how to write good changesets. Changesets are stored in the `/.changeset` directory. Breaking changes must be accompanied by a `minor` version bump for packages that below version `1.0.0`, or a `major` version bump for packages that are at version `1.0.0` or higher. Never update ESLint, Prettier, or TypeScript configuration files unless specifically requested. diff --git a/docs/integrations/github/discovery.md b/docs/integrations/github/discovery.md index 5dd13a7bec..c56aed054b 100644 --- a/docs/integrations/github/discovery.md +++ b/docs/integrations/github/discovery.md @@ -37,32 +37,149 @@ backend.add(import('@backstage/plugin-catalog-backend-module-github')); ## Events Support -The catalog module for GitHub comes with events support enabled. -This will make it subscribe to its relevant topics (`github.push`, -`github.repository`) and expects these events to be published -via the `EventsService`. +The catalog module for GitHub comes with events support enabled. This will make it subscribe to its relevant topics (`github.push`, `github.repository`) and expects these events to be published via the `EventsService`. -Additionally, you should install the -[event router by `events-backend-module-github`](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-github/README.md) -which will route received events from the generic topic `github` to more specific ones -based on the event type (e.g., `github.push`). +### Prerequisites -In order to receive Webhook events by GitHub, you have to decide how you want them -to be ingested into Backstage and published to its `EventsService`. -You can decide between the following options (extensible): +There are two Prerequisites to use the builtin events support: -- [via HTTP endpoint](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md) -- [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md) +1. Creating a webhook in GitHub +2. Installing and configuring `@backstage/plugin-events-backend-module-github` + +#### Configure Webhooks in GitHub You can check the official docs to [configure your webhook](https://docs.github.com/en/developers/webhooks-and-events/webhooks/creating-webhooks) and to [secure your request](https://docs.github.com/en/developers/webhooks-and-events/webhooks/securing-your-webhooks). -The webhook(s) will need to be configured to react to `push` and -`repository` events. +The webhook(s) will need to be configured to react to `push` and `repository` events. -Certain actions like `transferred` by the `repository` event type -will not be supported when you use repository webhooks. -Please check the GitHubs documentation for these event types and -its actions. +:::note + +To receive the `repository.transferred` event, the new owner account must have the GitHub App installed, and the App must be subscribed to `repository` events. This event is only sent to the account where the ownership is transferred. + +::: + +When creating the webhook in GitHub the "Payload URL" will looks something along these lines: `https:///api/events/http/github` and the "Content Type" should be `application/json`. + +The GitHub Webhooks UI will send a trial event to validate it can connect when you save your new Webhook. It is possible to retry this trial event if it fails and you want to send it again. Additionally there is a Recent Deliveries tab you can use to validate that the events are being fired should you need to do any later troubleshooting. + +#### Install and Configure GitHub Events Module + +In order to use the built-in events support you'll need to install and configure `@backstage/plugin-events-backend-module-github`. This module will route received events from the generic topic `github` to more specific ones based on the event type (e.g., `github.push`). These more specific events are what the builtin events support is expecting. + +First we need to add the package: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-events-backend-module-github +``` + +Then we need to add it to your backend: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-events-backend')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-events-backend-module-github')); +/* highlight-add-end */ +``` + +Finally you will want to configure it: + +```yaml title="app-config.yaml +events: + modules: + github: + webhookSecret: ${GITHUB_WEBHOOK_SECRET} +``` + +Though this last step is technically optional, you'll want to include it to be sure the events being received are from GitHub and not from an external bad actor. + +The value of `${GITHUB_WEBHOOK_SECRET}` in this example would be the same that you used when creating the webhook on GitHub. + +### Events Setup using HTTP endpoint + +Using the HTTP endpoint for events just requires adding some additional configuration to your `app-config.yaml` as it is a built in feature of the Events backend, here's what that would look like: + +```yaml title="app-config.yaml +events: + http: + topics: + - github +``` + +This will then expose an endpoint like this: + +### Events Setup using AWS SQS module + +Alternatively to using the HTTP endpoint you can use the AWS SQS module, here's how. + +First we need to add the package: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugins-events-backend-module-aws-sqs +``` + +Then we need to add it to your backend: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-events-backend')); +backend.add(import('@backstage/plugin-events-backend-module-github')); +/* highlight-add-start */ +backend.add(import('@backstage/plugins-events-backend-module-aws-sqs')); +/* highlight-add-end */ +``` + +Finally you will want to configure it: + +```yaml title="app-config.yaml +events: + modules: + awsSqs: + awsSqsConsumingEventPublisher: + topics: + github: + queue: + url: 'https://sqs.us-east-2.amazonaws.com/123456789012/MyQueue' + region: us-east-2 +``` + +The [AWS SQS module `README`](https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-aws-sqs/README.md#configuration) has more details on the configuration options, the example above includes on the required options. + +### Events Setup using Google Pub/Sub module + +Alternatively to using the HTTP endpoint you can use the Google Pub/Sub module, here's how. + +First we need to add the package: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-events-backend-module-google-pubsub +``` + +Then we need to add it to your backend: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-events-backend')); +backend.add(import('@backstage/plugin-events-backend-module-github')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-events-backend-module-google-pubsub')); +/* highlight-add-end */ +``` + +Finally you will want to configure it: + +```yaml title="app-config.yaml +events: + modules: + googlePubSub: + googlePubSubConsumingEventPublisher: + subscriptions: + # A unique key for your subscription, to be used in logging and metrics + mySubscription: + # The fully qualified name of the subscription + subscriptionName: 'projects/my-google-project/subscriptions/github-enterprise-events' + # The event system topic to transfer to. This can also be just a plain string + targetTopic: 'github.{{ event.attributes.x-github-event }}' +``` + +The [Google Pub/Sub module `README`](https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-google-pubsub/README.md#configuration) has more details on the configuration options, the example above includes on the required options. ## Configuration diff --git a/docs/overview/roadmap.md b/docs/overview/roadmap.md index a61455a313..d9a03d9668 100644 --- a/docs/overview/roadmap.md +++ b/docs/overview/roadmap.md @@ -17,7 +17,7 @@ The initiatives listed below are planned for release within the next half-year, ### New Frontend System - Ready for Adoption -The [new fronted system](../frontend-system/index.md) still needs more work, and +The [new frontend system](../frontend-system/index.md) still needs more work, and the next milestone is to improve it to the point where there is enough confidence in the design to start encouraging adoption in the community. You can follow along with this work in the [meta issue](https://github.com/backstage/backstage/issues/19545). diff --git a/docs/tutorials/setup-opentelemetry.md b/docs/tutorials/setup-opentelemetry.md index 2008e0c5e8..4803933736 100644 --- a/docs/tutorials/setup-opentelemetry.md +++ b/docs/tutorials/setup-opentelemetry.md @@ -6,7 +6,7 @@ description: Tutorial to setup OpenTelemetry metrics and traces exporters in Bac Backstage uses [OpenTelemetry](https://opentelemetry.io/) to instrument its components by reporting traces and metrics. -This tutorial shows how to setup exporters in your Backstage backend package. For demonstration purposes we will use a Prometheus exporter, but you can adjust your solution to use another one that suits your needs; see for example the article on [OTLP exporters](https://opentelemetry.io/docs/instrumentation/js/exporters/). +This tutorial shows how to setup exporters in your Backstage backend package. For demonstration purposes we will use a Prometheus exporter, but you can adjust your solution to use another one that suits your needs; see for example the article on [OTLP exporters](https://opentelemetry.io/docs/instrumentation/js/exporters/). This tutorial also includes exporting traces using the JSON/HTTP exporter with Jaeger being the ideal target, but this too can be adjusted to fit your needs by seeing the supported tooling in the [OTLP exporters](https://opentelemetry.io/docs/instrumentation/js/exporters/) documentation. ## Install dependencies @@ -19,7 +19,8 @@ The `auto-instrumentations-node` will automatically create spans for code called yarn --cwd packages/backend add \ @opentelemetry/sdk-node \ @opentelemetry/auto-instrumentations-node \ - @opentelemetry/exporter-prometheus + @opentelemetry/exporter-prometheus \ + @opentelemetry/exporter-trace-otlp-http ``` ## Configure @@ -36,12 +37,20 @@ if (isMainThread) { getNodeAutoInstrumentations, } = require('@opentelemetry/auto-instrumentations-node'); const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus'); + const { + OTLPTraceExporter, + } = require('@opentelemetry/exporter-trace-otlp-http'); // By default exports the metrics on localhost:9464/metrics - const prometheus = new PrometheusExporter(); + const prometheusExporter = new PrometheusExporter(); + // We post the traces to localhost:4318/v1/traces + const otlpTraceExporter = new OTLPTraceExporter({ + // Default Jaeger URL trace endpoint. + url: 'http://localhost:4318/v1/traces', + }); const sdk = new NodeSDK({ - // You can add a traceExporter field here too - metricReader: prometheus, + metricReader: prometheusExporter, + traceExporter: otlpTraceExporter, instrumentations: [getNodeAutoInstrumentations()], }); @@ -105,6 +114,28 @@ For local development, you can add the required flag in your `packages/backend/p You can now start your Backstage instance as usual, using `yarn start` and you'll be able to see your metrics at: +### Troubleshooting + +If you are having issues getting metrics or traces working there are some helpful diagnostic tools from OpenTelemetry you can use that can help. + +First we need to the `@opentelemetry/api` package: + +```bash +yarn --cwd packages/backend add @opentelemetry/api +``` + +Then we want to add the following snippet before the `sdk.start()` call: + +```js +const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api'); + +diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG); +``` + +This will then add OpenTelemetry debug logs that you can then look at to help get a better idea of why something may not be working as expected. + +We don't recommend shipping this in production because of the log density. + ## Production Setup In your `.dockerignore`, add this line: diff --git a/microsite/data/plugins/signadot.yaml b/microsite/data/plugins/signadot.yaml new file mode 100644 index 0000000000..9b6b162901 --- /dev/null +++ b/microsite/data/plugins/signadot.yaml @@ -0,0 +1,10 @@ +--- +title: Signadot +author: Signadot +authorUrl: https://www.signadot.com/ +category: Kubernetes +description: View and manage lightweight ephemeral Kubernetes environments (Sandboxes) for testing microservices in pull requests and local development. +documentation: https://github.com/signadot/backstage-plugin +iconUrl: https://avatars.githubusercontent.com/u/57196635 +npmPackageName: '@signadot-lib/backstage-plugin' +addedDate: '2025-07-09' diff --git a/packages/app/src/apis.ts b/packages/app/src/apis.ts index 5d300d67cb..8a05f100bc 100644 --- a/packages/app/src/apis.ts +++ b/packages/app/src/apis.ts @@ -25,6 +25,7 @@ import { createApiFactory, discoveryApiRef, fetchApiRef, + identityApiRef, } from '@backstage/core-plugin-api'; import { AuthProxyDiscoveryApi } from './AuthProxyDiscoveryApi'; import { formDecoratorsApiRef } from '@backstage/plugin-scaffolder/alpha'; @@ -51,13 +52,15 @@ export const apis: AnyApiFactory[] = [ discoveryApi: discoveryApiRef, fetchApi: fetchApiRef, scmIntegrationsApi: scmIntegrationsApiRef, + identityApi: identityApiRef, }, - factory: ({ discoveryApi, fetchApi, scmIntegrationsApi }) => + factory: ({ discoveryApi, fetchApi, scmIntegrationsApi, identityApi }) => new ScaffolderClient({ useLongPollingLogs: true, discoveryApi, fetchApi, scmIntegrationsApi, + identityApi, }), }), diff --git a/packages/ui/report.api.md b/packages/ui/report.api.md index 7ef69560d1..6f6fc41fdb 100644 --- a/packages/ui/report.api.md +++ b/packages/ui/report.api.md @@ -29,7 +29,7 @@ import { Table as Table_2 } from '@tanstack/react-table'; import type { TabListProps as TabListProps_2 } from 'react-aria-components'; import type { TabPanelProps as TabPanelProps_2 } from 'react-aria-components'; import { TabProps } from 'react-aria-components'; -import type { TabsProps as TabsProps_2 } from 'react-aria-components'; +import { TabsProps as TabsProps_2 } from 'react-aria-components'; import { TdHTMLAttributes } from 'react'; import type { TextFieldProps as TextFieldProps_2 } from 'react-aria-components'; import { ThHTMLAttributes } from 'react'; @@ -1040,6 +1040,8 @@ export interface HeaderProps { // (undocumented) menuItems?: HeaderMenuItem[]; // (undocumented) + onTabSelectionChange?: TabsProps_2['onSelectionChange']; + // (undocumented) tabs?: HeaderTab[]; // (undocumented) title?: string; diff --git a/packages/ui/src/components/Header/Header.tsx b/packages/ui/src/components/Header/Header.tsx index e6aae08eeb..4f85d9096d 100644 --- a/packages/ui/src/components/Header/Header.tsx +++ b/packages/ui/src/components/Header/Header.tsx @@ -50,7 +50,7 @@ export const Header = (props: HeaderProps) => { /> {tabs && (
- + {tabs?.map(tab => ( diff --git a/packages/ui/src/components/Header/types.ts b/packages/ui/src/components/Header/types.ts index e1156c9a55..cf76929389 100644 --- a/packages/ui/src/components/Header/types.ts +++ b/packages/ui/src/components/Header/types.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +import { TabsProps } from 'react-aria-components'; + /** * Props for the main Header component. * @@ -26,6 +28,7 @@ export interface HeaderProps { customActions?: React.ReactNode; menuItems?: HeaderMenuItem[]; tabs?: HeaderTab[]; + onTabSelectionChange?: TabsProps['onSelectionChange']; } /** diff --git a/plugins/catalog/src/alpha/DefaultEntityContentLayout.tsx b/plugins/catalog/src/alpha/DefaultEntityContentLayout.tsx index a2be72bcdb..21276f424a 100644 --- a/plugins/catalog/src/alpha/DefaultEntityContentLayout.tsx +++ b/plugins/catalog/src/alpha/DefaultEntityContentLayout.tsx @@ -79,8 +79,7 @@ const useStyles = makeStyles< infoArea: { gridArea: 'info', position: 'sticky', - bottom: theme.spacing(3), - alignSelf: 'end', + top: theme.spacing(3), marginLeft: theme.spacing(3), }, contentArea: { diff --git a/plugins/catalog/src/alpha/filters.tsx b/plugins/catalog/src/alpha/filters.tsx index fcfbc394f2..d72e299fbb 100644 --- a/plugins/catalog/src/alpha/filters.tsx +++ b/plugins/catalog/src/alpha/filters.tsx @@ -133,13 +133,14 @@ const catalogListCatalogFilter = CatalogFilterBlueprint.makeWithOverrides({ }, }); +// this is the default order that the filters will be applied in export default [ - catalogTagCatalogFilter, catalogKindCatalogFilter, catalogTypeCatalogFilter, - catalogModeCatalogFilter, - catalogNamespaceCatalogFilter, - catalogLifecycleCatalogFilter, - catalogProcessingStatusCatalogFilter, catalogListCatalogFilter, + catalogModeCatalogFilter, + catalogLifecycleCatalogFilter, + catalogTagCatalogFilter, + catalogProcessingStatusCatalogFilter, + catalogNamespaceCatalogFilter, ];