Xcmetrics new frontend support#9454
Open
TishG wants to merge 7 commits into
Open
Conversation
Signed-off-by: Tish Griffiths <38973991+TishG@users.noreply.github.com>
Signed-off-by: Tish Griffiths <38973991+TishG@users.noreply.github.com>
Signed-off-by: Tish Griffiths <38973991+TishG@users.noreply.github.com>
Contributor
Changed Packages
|
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR adds support for Backstage’s new frontend system for the XCMetrics plugin (via an /alpha entrypoint), improves local development by providing an in-memory dev API implementation, and bumps the workspace to Backstage 1.51.2.
Changes:
- Added a new frontend-system plugin entrypoint at
@backstage-community/plugin-xcmetrics/alphausing@backstage/frontend-plugin-api - Added a deterministic-ish in-memory
DevXcmetricsApiand wired it into the dev app to run without a backend - Updated Backstage release references (
backstage.json, Yarn plugin, lockfile) and documented new usage
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| workspaces/xcmetrics/yarn.lock | Adds @backstage/frontend-plugin-api and updates lock entries for Backstage 1.51.2. |
| workspaces/xcmetrics/plugins/xcmetrics/src/alpha.tsx | Introduces the new frontend-system plugin export (page + API extensions). |
| workspaces/xcmetrics/plugins/xcmetrics/package.json | Adds exports/typesVersions for /alpha and includes new dependency. |
| workspaces/xcmetrics/plugins/xcmetrics/dev/index.tsx | Overrides the real API with an in-memory dev implementation for local runs. |
| workspaces/xcmetrics/plugins/xcmetrics/dev/DevXcmetricsApi.ts | Adds in-memory implementation for plugin dev without backend. |
| workspaces/xcmetrics/plugins/xcmetrics/README.md | Documents the new frontend system /alpha registration path. |
| workspaces/xcmetrics/package.json | Adds a workspace dev script for starting the plugin. |
| workspaces/xcmetrics/backstage.json | Bumps Backstage version to 1.51.2. |
| workspaces/xcmetrics/app-config.yaml | Adds example app config + proxy for local usage. |
| workspaces/xcmetrics/.yarnrc.yml | Updates Backstage Yarn plugin URL to 1.51.2. |
| workspaces/xcmetrics/.changeset/xcmetrics-new-frontend-support.md | Adds a changeset for the /alpha export. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+128
to
+136
| day: start.toISODate()!, | ||
| startTimestamp: start.toISO({ suppressMilliseconds: true })!, | ||
| endTimestamp: end.toISO({ suppressMilliseconds: true })!, | ||
| compilationEndTimestamp: compilationEnd.toISO({ | ||
| suppressMilliseconds: true, | ||
| })!, | ||
| startTimestampMicroseconds: start.toSeconds(), | ||
| endTimestampMicroseconds: end.toSeconds(), | ||
| compilationEndTimestampMicroseconds: compilationEnd.toSeconds(), |
Comment on lines
+156
to
+169
| const count = intBetween(5, targetNames.length); | ||
| let cursor = build.startTimestampMicroseconds; | ||
|
|
||
| return Array.from({ length: count }, (_, index) => { | ||
| const targetDuration = between(0.5, build.duration / count); | ||
| const compileDuration = targetDuration * between(0.4, 0.85); | ||
| const startMicro = cursor; | ||
| const endMicro = startMicro + targetDuration; | ||
| const compilationEndMicro = startMicro + compileDuration; | ||
| cursor = endMicro; | ||
|
|
||
| return { | ||
| id: `${build.id}_T${pad(index)}`, | ||
| name: targetNames[index], |
Comment on lines
+203
to
+208
| const createErrors = (build: Build): BuildError[] => | ||
| Array.from({ length: build.errorCount }, (_, index) => ({ | ||
| id: `${build.id}_E${pad(index)}`, | ||
| buildIdentifier: build.id, | ||
| parentIdentifier: `${build.id}_T0007`, | ||
| parentType: 'step', |
Comment on lines
+223
to
+228
| const createWarnings = (build: Build): BuildWarning[] => | ||
| Array.from({ length: Math.min(build.warningCount, 6) }, (_, index) => ({ | ||
| id: `${build.id}_W${pad(index)}`, | ||
| buildIdentifier: build.id, | ||
| parentIdentifier: `${build.id}_T000${index % 8}`, | ||
| parentType: 'step', |
Comment on lines
+43
to
+56
| // Deterministic pseudo-random generator (mulberry32) so the dev data does not | ||
| // jump around on every render/reload. | ||
| const createRandom = (seed: number) => { | ||
| let state = seed; | ||
| return () => { | ||
| state |= 0; | ||
| state = (state + 0x6d2b79f5) | 0; | ||
| let t = Math.imul(state ^ (state >>> 15), 1 | state); | ||
| t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; | ||
| return ((t ^ (t >>> 14)) >>> 0) / 4294967296; | ||
| }; | ||
| }; | ||
|
|
||
| const rand = createRandom(20210101); |
Comment on lines
+35
to
+36
| export const xCRMetricsApiExtension = ApiBlueprint.make({ | ||
| name: 'xcmetrics-api', |
Comment on lines
+25
to
+29
| "exports": { | ||
| ".": "./src/index.ts", | ||
| "./alpha": "./src/alpha.tsx", | ||
| "./package.json": "./package.json" | ||
| }, |
Signed-off-by: Tish Griffiths <38973991+TishG@users.noreply.github.com>
Signed-off-by: Tish Griffiths <38973991+TishG@users.noreply.github.com>
Comment on lines
+23
to
+27
| "exports": { | ||
| ".": "./src/index.ts", | ||
| "./alpha": "./src/alpha.tsx", | ||
| "./package.json": "./package.json" | ||
| }, |
Comment on lines
38
to
39
| "main": "src/index.ts", | ||
| "types": "src/index.ts", |
| import { rootRouteRef } from './routes'; | ||
| import { xcmetricsApiRef, XcmetricsClient } from './api'; | ||
|
|
||
| const xCMetricsPage = PageBlueprint.make({ |
| }, | ||
| }); | ||
|
|
||
| export const xCRMetricsApiExtension = ApiBlueprint.make({ |
|
|
||
| export default createFrontendPlugin({ | ||
| pluginId: 'xcmetrics', | ||
| extensions: [xCMetricsPage, xCRMetricsApiExtension], |
| const count = intBetween(5, targetNames.length); | ||
| let cursor = build.startTimestampMicroseconds; | ||
|
|
||
| return Array.from({ length: count }, (_, index) => { |
Comment on lines
+170
to
+172
| category: pick(CATEGORIES), | ||
| buildIdentifier: build.id, | ||
| fetchedFromCache: rand() > 0.85, |
Comment on lines
+223
to
+227
| const createWarnings = (build: Build): BuildWarning[] => | ||
| Array.from({ length: Math.min(build.warningCount, 6) }, (_, index) => ({ | ||
| id: `${build.id}_W${pad(index)}`, | ||
| buildIdentifier: build.id, | ||
| parentIdentifier: `${build.id}_T000${index % 8}`, |
Comment on lines
+203
to
+207
| const createErrors = (build: Build): BuildError[] => | ||
| Array.from({ length: build.errorCount }, (_, index) => ({ | ||
| id: `${build.id}_E${pad(index)}`, | ||
| buildIdentifier: build.id, | ||
| parentIdentifier: `${build.id}_T0007`, |
Comment on lines
+223
to
+227
| const createWarnings = (build: Build): BuildWarning[] => | ||
| Array.from({ length: Math.min(build.warningCount, 6) }, (_, index) => ({ | ||
| id: `${build.id}_W${pad(index)}`, | ||
| buildIdentifier: build.id, | ||
| parentIdentifier: `${build.id}_T000${index % 8}`, |
Signed-off-by: Tish Griffiths <38973991+TishG@users.noreply.github.com>
Signed-off-by: Tish Griffiths <38973991+TishG@users.noreply.github.com>
Comment on lines
+134
to
+136
| startTimestampMicroseconds: start.toSeconds(), | ||
| endTimestampMicroseconds: end.toSeconds(), | ||
| compilationEndTimestampMicroseconds: compilationEnd.toSeconds(), |
Comment on lines
+23
to
+27
| "exports": { | ||
| ".": "./src/index.ts", | ||
| "./alpha": "./src/alpha.tsx", | ||
| "./package.json": "./package.json" | ||
| }, |
Comment on lines
38
to
39
| "main": "src/index.ts", | ||
| "types": "src/index.ts", |
| import { rootRouteRef } from './routes'; | ||
| import { xcmetricsApiRef, XcmetricsClient } from './api'; | ||
|
|
||
| const xCMetricsPage = PageBlueprint.make({ |
| /** | ||
| * @alpha | ||
| */ | ||
| export const xCRMetricsApiExtension = ApiBlueprint.make({ |
|
|
||
| export default createFrontendPlugin({ | ||
| pluginId: 'xcmetrics', | ||
| extensions: [xCMetricsPage, xCRMetricsApiExtension], |
Comment on lines
+36
to
+41
| /** | ||
| * A self-contained, in-memory implementation of the {@link XcmetricsApi} used | ||
| * to run the plugin locally without a real XCMetrics backend. The data is | ||
| * generated deterministically so that charts and tables stay stable between | ||
| * reloads while still looking realistic. | ||
| */ |
|
|
||
| const createBuild = (index: number): Build => { | ||
| const daysAgo = Math.floor((index / TOTAL_BUILDS) * HISTORY_DAYS); | ||
| const start = DateTime.now() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hey, I just made a Pull Request!
Adds the new front end system support to xcmetrics #7539
✔️ Checklist
Signed-off-byline in the message. (more info)