74233 Commits

Author SHA1 Message Date
Fredrik Adelöw 4829e8961e fix(catalog-backend): split queryEntities list and count queries
The filtered CTE was referenced twice (count + data), preventing
Postgres 12+ from inlining it. This forced full materialization of
the filtered set before LIMIT could short-circuit. Split into two
separate queries run via Promise.all so the list CTE is only
referenced once and the planner can short-circuit on LIMIT.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 15:48:22 +02:00
Fredrik Adelöw 813608335f Merge pull request #34321 from backstage/freben/enter-prerelease-mode
Enter changeset prerelease mode
2026-05-20 11:21:53 +02:00
Fredrik Adelöw 34d86b8fe3 Enter changeset prerelease mode with tag "next"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 11:10:47 +02:00
Fredrik Adelöw cd8e20d7bb Merge pull request #34314 from backstage/freben/stitch-claim-transaction
Fix stitch queue race: wrap claim in transaction
2026-05-20 10:33:53 +02:00
Fredrik Adelöw 62dd4fc3bc Add changeset for renderInTestApp route matching fix
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 10:31:13 +02:00
Fredrik Adelöw a06003bc90 Switch to in-memory catalog client for entity page tests
Now that renderInTestApp properly sets up Route matching, the test can
use the real in-memory catalog client instead of jest stubs. The
in-memory client does actual ref-based lookups, verifying that
useEntityFromUrl receives correct route params end-to-end.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 10:28:18 +02:00
Fredrik Adelöw 1d10fc41e8 Update changeset and PR description to cover both fix sites
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 09:59:37 +02:00
Fredrik Adelöw dd52890773 Use ternary with await for consistent style and better stack traces
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 09:49:08 +02:00
Fredrik Adelöw 139a784ad4 Skip transaction wrapping when locking is not used
Only wrap the SELECT+UPDATE in a transaction for MySQL/PostgreSQL
where FOR UPDATE SKIP LOCKED is actually used. For sqlite3 the
transaction adds unnecessary BEGIN/COMMIT overhead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 09:44:31 +02:00
Fredrik Adelöw 95e107bc6e Wrap test element in Routes when mountedRoutes are provided
renderInTestApp disables app/routes, so the test element was rendered
without any Route matching. This meant useParams() always returned {}
even when initialRouteEntries and mountedRoutes were set — the mounted
routes only fed the route resolution API for link generation, never
created actual React Router <Route> matching for param extraction.

Wrap the test element in <Routes> with a <Route> for each mounted path
(plus a path="*" fallback), mirroring what the real AppRoutes extension
does via useRoutes(). This makes useParams() return real params when
initialRouteEntries matches a mounted route path.

Update entity page test href expectations to match the now-correct
production behavior where sub-route links resolve relative to the
matched parent Route, and replace synchronous getByTestId/getByText
with async findBy queries for lazy-loaded content.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 09:42:47 +02:00
Fredrik Adelöw a58bcdcb47 Add initialRouteEntries to fix flaky entity page test
The entity page resolves route params via useRouteRefParams. Without
initialRouteEntries, the MemoryRouter starts at '/' which doesn't
match the entity route pattern. On fast machines the mock entity
resolves before the useEffect error check fires, but on slow CI
runners the timing differs and the "No name provided!" error path
wins, causing the test to flake.

Adding initialRouteEntries ensures the router starts at a URL that
matches /catalog/:namespace/:kind/:name, so route params are always
available regardless of timing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 08:41:04 +02:00
Fredrik Adelöw 479d78ed5c Revert to catalogApiMock.mock(), only keep Entity type annotation
The InMemoryCatalogClient + initialRouteEntries approach didn't work
because route params weren't being resolved by the test harness,
causing getEntityByRef to receive an empty ref. The original mock
with getEntityByRef: async () => entityMock works correctly. The
only change from master is adding the Entity type annotation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 08:34:28 +02:00
Fredrik Adelöw afc872aac6 Fix implicit any types on transaction callback parameters
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 08:06:37 +02:00
Fredrik Adelöw 6713e9fe72 Apply same transaction fix to getProcessableEntities
Same FOR UPDATE SKIP LOCKED race: the processing loop's claim query
had the SELECT and UPDATE as separate auto-committed statements.
The existing caller already wraps in a transaction, but this makes
the function self-protecting if called without one.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 00:09:16 +02:00
Fredrik Adelöw ac1a4ab3c9 Type entityMock as Entity and remove casts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 00:02:02 +02:00
Fredrik Adelöw e5da0ab00f fix(catalog): fix flaky entity page test by providing initial route and in-memory catalog
The test rendered at '/' instead of a URL matching the entity route
pattern, causing useEntityFromUrl to sometimes fail to extract route
params. Use initialRouteEntries to start at the correct entity URL,
and switch from catalogApiMock.mock() to catalogApiMock() for a
working in-memory catalog client.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 23:58:21 +02:00
Fredrik Adelöw c5057b79e3 Add migration test for search extended statistics
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 23:37:56 +02:00
Fredrik Adelöw f328b6f37e Merge pull request #34316 from backstage/freben/fix-empty-each-tests
fix: correct postgres env var casing in deploy_packages workflow
2026-05-19 23:34:19 +02:00
Fredrik Adelöw 8abfa78e4c Revert eachSupportedId guard — env var fix is sufficient
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 23:23:37 +02:00
Fredrik Adelöw 2c53691962 Fix postgres env var casing in deploy_packages workflow
The env vars used lowercase postgres18/postgres14 instead of uppercase
POSTGRES18/POSTGRES14, which didn't match the names expected by
TestDatabases. This caused all postgres-only test suites to see no
available databases and crash.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 23:21:47 +02:00
Patrik Oldsberg 6733eb1823 Merge pull request #34313 from backstage/worktree-v1.51-release-notes
Add v1.51.0 release notes
2026-05-19 23:21:12 +02:00
Fredrik Adelöw 03f0f3f953 Add changeset
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 23:19:18 +02:00
Fredrik Adelöw 1cbc3241a1 fix(backend-test-utils): prevent suite crash when no databases are available
When eachSupportedId() returned an empty array, describe.each([]) would
throw and crash the entire test suite. Return a placeholder ID instead,
so individual tests fail with a clear error rather than preventing the
entire suite from running.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 23:19:07 +02:00
Fredrik Adelöw 39c5fbb633 Add extended statistics on search(key, value) for planner accuracy
The search table is an EAV schema where key and value are highly
correlated, but standard single-column statistics can't model this.
This caused the planner to underestimate compound filter queries by
up to 1300x, choosing materialize-then-sort plans instead of LIMIT
short-circuit index scans.

CREATE STATISTICS captures the (key, value) correlation via
dependencies, ndistinct, and most-common-values metadata. The planner
then correctly estimates row counts and chooses the index-driven plan.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 23:11:19 +02:00
Fredrik Adelöw 32548ad82c Use .modify() for conditional FOR UPDATE SKIP LOCKED
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 22:33:18 +02:00
Fredrik Adelöw d42f1ab765 Skip wrapping in transaction when caller already provides one
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 22:21:27 +02:00
benjdlambert 757bbfdbae restore changelog links in release notes
Signed-off-by: benjdlambert <ben@blam.sh>
2026-05-19 22:18:27 +02:00
Fredrik Adelöw 774d69884a Wrap stitch queue claim in a transaction to hold row locks
The SELECT FOR UPDATE SKIP LOCKED and the subsequent UPDATE of
next_stitch_at now run inside a single transaction. Previously the
row locks were released after the SELECT auto-committed, allowing
another worker to claim the same rows before the UPDATE ran.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 22:12:59 +02:00
benjdlambert 9683a46b57 address PR review feedback on v1.51.0 release notes
Signed-off-by: benjdlambert <ben@blam.sh>
2026-05-19 21:27:06 +02:00
Ben Lambert cfb9f07c28 Merge pull request #34228 from backstage/changeset-release/master 2026-05-19 21:21:29 +02:00
benjdlambert 82c81085b1 add v1.51.0 release notes
Signed-off-by: benjdlambert <ben@blam.sh>
2026-05-19 20:47:20 +02:00
github-actions[bot] b97fcb0a93 Version Packages 2026-05-19 18:28:24 +00:00
Patrik Oldsberg 0a44fb3cb8 Merge pull request #33895 from ganievs/fix-valkey-cluster-client
fix: use iovalkey Cluster for Valkey cluster mode
2026-05-19 20:14:27 +02:00
Ben Lambert e16b564c6f Merge pull request #34310 from backstage/copilot/copy-commits-from-pr-34066
MCP structured responses, OIDC error improvements, catalog model reference config
2026-05-19 20:12:47 +02:00
benjdlambert 3f5e7ec2b4 Improve MCP safeStringify, OIDC error messages, and catalog model reference config
Signed-off-by: benjdlambert <ben@blam.sh>
2026-05-19 19:27:45 +02:00
Ben Lambert a5a269c27a Merge pull request #34300 from backstage/github-omit-suspended-rest
feat(catalog-backend-module-github): add experimental REST-based suspended user check
2026-05-19 19:19:59 +02:00
Love Kumar Chauhan ca8951ae87 fix(mcp-actions-backend): return structured content and remove markdown formatting in tool responses
This change aligns the MCP tool execution responses with the specification by returning plain text in the 'content' array and providing the raw JSON in a new 'structuredContent' field. It also removes the unnecessary Markdown code block formatting that was previously added to tool results.

Fixes #34052

Signed-off-by: Love Kumar Chauhan <lovechauhan6564@gmail.com>

Co-authored-by: benjdlambert <3645856+benjdlambert@users.noreply.github.com>
Signed-off-by: benjdlambert <ben@blam.sh>
2026-05-19 18:48:50 +02:00
Ben Lambert 381cf2ae10 Merge pull request #34308 from backstage/freben/cached-service-cleanup
Fix cache eviction race in CachedUserInfoService
2026-05-19 18:37:27 +02:00
Ben Lambert 359d5a502f Merge pull request #34016 from backstage/benjdlambert/api-v1beta2-mcp-server 2026-05-19 16:01:11 +02:00
Ben Lambert 484c073be9 Merge pull request #34261 from backstage/session/scheming-finch-ks70 2026-05-19 16:00:41 +02:00
MT Lewis 7c43925d68 feat(catalog-backend-module-github): remove @public tags from non-public github library functions
Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>
2026-05-19 14:45:34 +01:00
MT Lewis 253c014cc1 feat(catalog-backend-module-github): memoize isGitHubEnterprise check
We should mostly get these for free because of the
GitHub conditional request caching, but this is a
nice safety net and also probably saves us some
time.

Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>
2026-05-19 14:45:34 +01:00
MT Lewis 91d7d91317 feat(catalog-backend-module-github): restore previous sequential processing of connection nodes
Keeping this change as minimal as possible for
this first phase, will restore the parallel
processing in a later iteration.

Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>
2026-05-19 14:45:33 +01:00
MT Lewis 340977de5e feat(catalog-backend-module-github): rename options_ to wrappedOptions
Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>
2026-05-19 14:45:33 +01:00
MT Lewis d745f1c39c feat(catalog-backend-module-github): add experimental REST-based suspended user check
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>
2026-05-19 14:45:33 +01:00
Fredrik Adelöw 97d3bd4c7b Add changeset for cached service cleanup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 15:27:22 +02:00
Fredrik Adelöw 4b4a614c5c Guard cache eviction on identity and use createDeferred in test
Only delete the cache entry on error if the map still holds the same
promise, preventing a stale rejection from evicting a newer entry.
Also switch the test to createDeferred for readability.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 15:26:58 +02:00
Fredrik Adelöw 6eacdc036e Merge pull request #34252 from backstage/freben/lazy-permission-user
permission: cache user info, clean up PolicyQueryUser, drop getPluginRequestToken
2026-05-19 15:20:48 +02:00
Patrik Oldsberg 1dbc1543f4 Merge pull request #34299 from backstage/rugvip/nav-item-gone
frontend-plugin-api: remove NavItemBlueprint
2026-05-19 14:44:58 +02:00
Fredrik Adelöw a9f5560b49 Address review feedback: use fake timers and type the shared cache map
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 14:44:28 +02:00