Commit Graph

27233 Commits

Author SHA1 Message Date
Fredrik Adelöw e5fcfcb2cb Add catalog model layers with JSON Schema based kind declarations
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
2026-04-13 16:54:15 +02:00
Fredrik Adelöw 774e641e45 Merge pull request #33111 from AmateurMind/fix/gitlab-discovery-topic-filter 2026-04-12 12:47:29 +02:00
Patrik Oldsberg 7ff3429bda Merge pull request #33831 from drodil/get_notifications_action
feat(notifications): action to get users notifications
2026-04-10 09:42:16 +02:00
Hellgren Heikki 4c1fd438b3 feat(notifications): action to get users notifications
useful for mcp for example to get the daily what is going on
status.

Signed-off-by: Hellgren Heikki <heikki.hellgren@op.fi>
2026-04-10 10:19:46 +03:00
Patrik Oldsberg 70336a127c Merge pull request #33664 from backstage/scaffolder-actions-single-table
scaffolder: migrate actions page to @backstage/ui components
2026-04-09 20:25:49 +02:00
Claire Peng ee0c95d971 Merge pull request #33820 from backstage/clairep/update_docs_openAPI
Clairep/update docs open api
2026-04-09 12:11:56 +01:00
Claire Peng 5185e919cf delete trailing whitespace
Signed-off-by: Claire Peng <clairep@spotify.com>
2026-04-09 11:42:10 +01:00
Claire Peng f713b2459b add note about API Base URL in api-docs plugin Readme
Signed-off-by: Claire Peng <clairep@spotify.com>
2026-04-09 10:57:56 +01:00
Fredrik Adelöw 36be7c9bd5 Merge pull request #33818 from backstage/maratd/remove-humanize-entity-ref-org
fix(org): replace deprecated humanizeEntityRef with Catalog Presentation API
2026-04-09 11:39:37 +02:00
Marat Dyatko f1f59b13e1 fix(org): replace deprecated humanizeEntityRef with Catalog Presentation API
Replace `humanizeEntityRef(parseEntityRef(owner), { defaultKind: 'group' })`
with `entityPresentationSnapshot(ref, { defaultKind: 'group' }).primaryTitle`
in the OwnershipCard's `useGetEntities` hook. This was the last remaining
usage of the deprecated function in the codebase.

Signed-off-by: Marat Dyatko <maratd@spotify.com>
Made-with: Cursor
Signed-off-by: Marat Dyatko <maratd@spotify.com>
Made-with: Cursor
Signed-off-by: Marat Dyatko <maratd@spotify.com>
Made-with: Cursor
2026-04-09 10:45:22 +02:00
Marat Dyatko 09e17c8a65 test(org): add queryParams coverage for OwnershipCard useGetEntities
The existing tests never exercised `getQueryParams` because the mock
catalog API always returned empty items. These new tests verify that the
generated query parameters include correctly humanized owner entity refs,
handle multiple owners, and group entities by kind and type.

Made-with: Cursor
Signed-off-by: Marat Dyatko <maratd@spotify.com>
Made-with: Cursor
2026-04-09 10:25:33 +02:00
Fredrik Adelöw 0dc2cf7e43 Merge pull request #33815 from suhr25/fix/scaffolder-after-zero-query-param
fix: correctly handle after=0 in task events endpoint
2026-04-09 09:45:29 +02:00
Fredrik Adelöw aba2f0a980 Merge pull request #33386 from mvanhorn/feat/catalog-graph-presentation-api
feat(catalog-graph): use Catalog Presentation API instead of humanizeEntityRef
2026-04-09 09:16:51 +02:00
Suhrid Marwah 1d95cd302d test(scaffolder): add test for after=0 query param handling
Signed-off-by: Suhrid Marwah <suhridmarwah07@gmail.com>
2026-04-09 10:54:11 +05:30
suhr25 4ec08648d7 Merge branch 'master' of https://github.com/backstage/backstage into fix/scaffolder-after-zero-query-param 2026-04-09 10:50:16 +05:30
Suhrid Marwah 6408e4aa8a fix(scaffolder): handle after=0 in task events polling endpoint
Signed-off-by: Suhrid Marwah <suhridmarwah07@gmail.com>
2026-04-09 10:27:15 +05:30
Matt Van Horn 8a49e11936 refactor(catalog-graph): migrate to entityPresentationSnapshot helper
Replace direct entityPresentationApiRef usage with the new
entityPresentationSnapshot helper from #33576. This fixes the type
safety concern where CompoundEntityRef was passed to forEntity()
which only accepts Entity | string.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-04-08 10:55:30 -07:00
Patrik Oldsberg 5b1ba4ee3e Merge pull request #33718 from UsainBloot/auth0-cache-profile
auth0: cache profile API responses during token refresh
2026-04-08 11:39:21 +02:00
github-actions[bot] 6c10d88c13 Version Packages (next) 2026-04-07 15:30:58 +00:00
Johan Persson fa232da324 refactor(catalog-react): migrate InspectEntityDialog from MUI to BUI
Replace Material UI components with Backstage UI (BUI) equivalents
across the InspectEntityDialog and all its tab pages (Overview,
Ancestry, Colocated, JSON, YAML).

- Dialog shell uses BUI Dialog, DialogHeader, DialogBody, Tabs
- Horizontal tab bar replaces vertical MUI tabs
- Card sections use BUI Card, CardHeader, CardBody
- Key-value pairs rendered as semantic dl/dt/dd elements
- Copy buttons use BUI ButtonIcon with remixicon icons
- Help links use BUI ButtonLink
- Alerts use BUI Alert
- Tags use BUI TagGroup/Tag
- Accessible live region for copy confirmation
- Proper heading hierarchy (h2 for tab pages, h3 for cards, h4 for sections)
- Added OverviewPage tests for identity rendering, link detection, and tags

Signed-off-by: Johan Persson <johanopersson@gmail.com>
2026-04-07 17:20:34 +02:00
Matt Van Horn 416ad45fdd feat(catalog-graph): use Catalog Presentation API instead of humanizeEntityRef
Replace humanizeEntityRef with entityPresentationApiRef in CatalogGraphCard
and CatalogGraphPage for consistent entity display via the Catalog
Presentation API. Contributes to #20955.

Signed-off-by: Matt Van Horn <matt@osc.dev>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-04-07 07:40:43 -07:00
Patrik Oldsberg 894cd94312 Merge pull request #33699 from drodil/notifications_bui
feat(notifications): migrate to backstage ui
2026-04-07 16:28:07 +02:00
Patrik Oldsberg 55797b8cf4 Merge pull request #33748 from backstage/freben/permissions-cleanup-step-3-wip
Remove deprecated alpha exports from @backstage/plugin-catalog-node
2026-04-07 15:08:51 +02:00
Jack Palmer dfde6becee fix(auth0): skip profile cache when id_token has no sub claim
When the JWT id_token lacks a sub claim, the cache key would be
auth0-profile:undefined, causing all users without a sub to share
the same cached profile. Now skips caching entirely when sub is
missing and fetches the profile directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jack Palmer <jackpalmer@spotify.com>
2026-04-07 14:07:09 +01:00
Jack Palmer 44a42bf8e7 fix(auth0): use jose to decode id_token sub claim for cache key
Replace manual base64 JWT decoding with jose's decodeJwt for
correctness and consistency with other auth modules. Add jose
as a dependency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jack Palmer <jackpalmer@spotify.com>
2026-04-07 14:06:59 +01:00
Jonathan Roebuck ca3ef847f5 fix(auth0): use stable sub claim as cache key instead of refresh token
Auth0 rotates refresh tokens on each use, causing cache misses every
time. Use the user's sub claim from the ID token as the cache key
instead, which is stable per user.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
2026-04-07 14:05:41 +01:00
Jack Palmer b3bbd42f91 auth0: cache profile API responses during token refresh
Every page refresh triggers the auth0 authenticator to fetch the user
profile from Auth0's /userinfo API. Auth0 enforces strict rate limits on
this endpoint, causing failures at scale.

Add a createAuth0Authenticator factory that accepts an optional
CacheService to cache profile responses with a 1-minute TTL. The module
now uses the cached variant by default. The existing auth0Authenticator
export remains available for use without caching.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jack Palmer <jackpalmer@spotify.com>
2026-04-07 14:05:41 +01:00
Fredrik Adelöw 587981973c Merge pull request #33576 from backstage/maratd/replace-humanize-entity-ref
Replace deprecated humanizeEntityRef with Catalog Presentation API
2026-04-07 14:28:39 +02:00
Patrik Oldsberg 972edbc0eb Merge pull request #33747 from backstage/freben/migrate-techdocs-from-alpha-catalog-service-ref
Migrate techdocs plugins from alpha to stable catalogServiceRef
2026-04-07 13:54:08 +02:00
Fredrik Adelöw 7a031965b1 Remove deprecated alpha exports from @backstage/plugin-catalog-node
Removes the long-deprecated re-exports from the /alpha entry point that
were only kept for backwards compatibility:

- catalogServiceRef (the CatalogApi-based legacy one)
- CatalogLocationsExtensionPoint / catalogLocationsExtensionPoint
- CatalogProcessingExtensionPoint / catalogProcessingExtensionPoint
- CatalogAnalysisExtensionPoint / catalogAnalysisExtensionPoint

All of these have non-alpha equivalents that should be used directly.

Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
2026-04-07 13:20:02 +02:00
Fredrik Adelöw 5917638dcd Merge pull request #33753 from backstage/freben/locationlocation
catalog-backend: persist location_entity_ref in locations table
2026-04-07 12:59:38 +02:00
Marat Dyatko b32ab39670 Fix unsafe type casts via shared entityPresentationSnapshot utility
Extract entityPresentationSnapshot helper to eliminate unsafe `as Entity`
casts when passing CompoundEntityRef to EntityPresentationApi.forEntity(),
which only accepts Entity | string. The helper safely discriminates input
types and stringifies CompoundEntityRef before calling the API.

- Add entityPresentationSnapshot as a public export from catalog-react
- Remove duplicated getEntityTitle/getTitle helpers across 5 files
- Fix useAsync dependency array in TemplateFormPreviewer
- Update TSDoc across all presentation API surfaces to reference the
  new helper
- Update entity-presentation.md docs with usage guidance and migration
  table

Made-with: Cursor
Signed-off-by: Marat Dyatko <maratd@spotify.com>
2026-04-07 12:41:29 +02:00
Patrik Oldsberg adf228cb16 Merge pull request #33720 from backstage/rugvip/add-to-error-utility
errors: add `toError` utility and migrate usages
2026-04-07 12:00:01 +02:00
Ben Lambert 5af48e77af feat(scaffolder): Migrate scaffolder to use permissions registry (#33740)
* feat(scaffolder-node): add PermissionResourceRef definitions for scaffolder resource types

Signed-off-by: benjdlambert <ben@blam.sh>

* feat(scaffolder-backend): migrate to PermissionsRegistryService with fallback

Signed-off-by: benjdlambert <ben@blam.sh>

* feat(scaffolder-backend): wire permissionsRegistry in ScaffolderPlugin

Signed-off-by: benjdlambert <ben@blam.sh>

* test(scaffolder-backend): verify permissions metadata endpoint returns all scaffolder permissions

Signed-off-by: benjdlambert <ben@blam.sh>

* chore: add changesets for scaffolder permissions registry migration

Signed-off-by: benjdlambert <ben@blam.sh>

* chore: format scaffolder-node alpha exports

Signed-off-by: benjdlambert <ben@blam.sh>

* fix: correct scaffolder-node changeset to patch for sub-1.0 package

Signed-off-by: benjdlambert <ben@blam.sh>

* refactor(scaffolder-backend): simplify by removing fallback path and making permissionsRegistry required

Signed-off-by: benjdlambert <ben@blam.sh>

* chore: update scaffolder-node API report

Signed-off-by: benjdlambert <ben@blam.sh>

---------

Signed-off-by: benjdlambert <ben@blam.sh>
2026-04-06 19:10:43 +02:00
Gabriel Dugny 282c11475f fix: OAuth 2.0 Protected Resource Metadata returning local endpoint (fix #33062) (#33092)
* fix: OAuth 2.0 Protected Resource Metadata returning local endpoint (fix #33062)

Signed-off-by: Gabriel Dugny <gabriel.dugny@believe.com>

* chore: add basic regression test

Signed-off-by: Gabriel Dugny <gabriel.dugny@believe.com>

---------

Signed-off-by: Gabriel Dugny <gabriel.dugny@believe.com>
2026-04-06 19:04:12 +02:00
Fredrik Adelöw dd48192606 Merge pull request #33410 from lokeshkaki/feat/bitbucket-cloud-scm-events
feat(catalog-backend-module-bitbucket-cloud): add Bitbucket Cloud SCM event translation and bridge wiring
2026-04-06 11:15:13 +02:00
Fredrik Adelöw 42d0a2749a Clarify migration comment: nullable-first is about NOT NULL without DEFAULT
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
2026-04-05 14:22:09 +02:00
Fredrik Adelöw 6941ae10f3 Add literal-value assertion for location_entity_ref in store test
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
2026-04-05 10:37:32 +02:00
Fredrik Adelöw 2514e30734 Fix misleading comment about bootstrap row in migration test
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
2026-04-04 22:57:11 +02:00
Fredrik Adelöw 51c45e7ae3 Remove per-batch round trips for Postgres unnest migration
The Postgres unnest UPDATE uses a fixed-size SQL string; only the array
bindings grow. The planner executes it with an index nested-loop (O(N)),
so batching only adds network round trips without reducing work. Run the
entire backfill in a single statement.

MySQL keeps its MYSQL_BATCH_SIZE=1000 because the UNION ALL SQL text
grows linearly with batch size, so smaller packets are important there.

Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
2026-04-04 22:41:29 +02:00
Fredrik Adelöw b21576575d Use string column and stringifyEntityRef for location_entity_ref
Switch the migration column type from text to string (varchar(255)),
since entity refs are always short. Also use stringifyEntityRef in
computeLocationEntityRef to handle lowercasing canonically.

Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
2026-04-04 22:24:36 +02:00
Fredrik Adelöw d16311f310 catalog-backend: persist location_entity_ref in locations table
Adds a migration that populates a new `location_entity_ref` column on the
`locations` table with the full entity ref of the corresponding
`kind: Location` entity (e.g. `location:default/generated-<sha1hex>`).
Postgres uses an unnest-based batch UPDATE; other engines use a
transaction-wrapped per-row loop.

All code paths in DefaultLocationStore that previously recomputed the hash
from type+target now read `location_entity_ref` directly from the DB row
instead. New rows written by `createLocation` and `#createLocationsByExactUrl`
have the column populated at insert time.

This is step 1 of migrating Location entity names to be based on the stable
row UUID rather than a hash of the mutable target URL.

Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
2026-04-04 22:19:26 +02:00
Kurt King ea0d31a1bc Merge branch 'master' of https://github.com/backstage/backstage into migrate-google-pubsub-alpha-metrics 2026-04-04 13:33:39 -06:00
Fredrik Adelöw 98d9a75dc2 Merge pull request #33632 from wpessers/feat/github-catalog-backend-extensiont/add-retry-to-github-client
feat(catalog): add retries to octokit client
2026-04-04 17:20:22 +02:00
Fredrik Adelöw 323da94780 Use mockCredentials in CachedEntityLoader tests and simplify cache key
Replace hand-crafted BackstageCredentials objects with mockCredentials
from @backstage/backend-test-utils, which have proper toString() methods.
Simplify getCacheKey to use String(credentials) directly and remove the
auth service dependency from CachedEntityLoader.

Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
2026-04-04 13:52:58 +02:00
Patrik Oldsberg 67fcc5a689 scaffolder: sync selected action with URL hash
Reflect the currently selected action in the URL hash so that users can
deep-link to a specific action on the actions page. On load the hash is
read to pre-select and scroll to the matching action.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-04-04 11:28:47 +02:00
Fredrik Adelöw e7fdf2997f Address Copilot review: fix pagination test and add credentials assertion
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
2026-04-03 23:23:42 +02:00
Fredrik Adelöw 999f308ad5 Call getOwnServiceCredentials per request, not once per loop
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
2026-04-03 23:06:47 +02:00
Fredrik Adelöw 52a45c308b Address review feedback
- Move getOwnServiceCredentials() before the pagination loop in DefaultTechDocsCollatorFactory
- Fix stale test comment that referenced the deleted MSW /entities handler

Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
2026-04-03 23:05:02 +02:00
Fredrik Adelöw 7d9d185654 Inline catalog from options directly in createRouter
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
2026-04-03 22:58:20 +02:00