Merge pull request #4365 from backstage/rugvip/ports
plugins: migrate circleci, cloudbuild, github-actions, jenkins to new composability API + tweaks for lighthouse and org
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-circleci': patch
|
||||
---
|
||||
|
||||
Migrated to new composability API, exporting the plugin instance as `circleCIPlugin`, the entity page content as `EntityCircleCIContent`, and entity conditional as `isCircleCIAvailable`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-cloudbuild': patch
|
||||
---
|
||||
|
||||
Migrate to new composability API, exporting the plugin instance as `cloudbuildPlugin`, the entity content as `EntityCloudbuildContent`, the entity conditional as `isCloudbuildAvailable`, and entity cards as `EntityLatestCloudbuildRunCard` and `EntityLatestCloudbuildsForBranchCard`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-jenkins': patch
|
||||
---
|
||||
|
||||
Migrate to new composability API, exporting the plugin instance as `jenkinsPlugin`, the entity content as `EntityJenkinsContent`, the entity conditional as `isJenkinsAvailable`, and the entity card as `EntityLatestJenkinsRunCard`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-github-actions': patch
|
||||
---
|
||||
|
||||
Migrate to new composability API, exporting the plugin instance as `githubActionsPlugin`, the entity content as `EntityGithubActionsContent`, entity conditional as `isGithubActionsAvailable`, and entity cards as `EntityLatestGithubActionRunCard`, `EntityLatestGithubActionsForBranchCard`, and `EntityRecentGithubActionsRunsCard`.
|
||||
@@ -15,6 +15,6 @@
|
||||
*/
|
||||
|
||||
import { createDevApp } from '@backstage/dev-utils';
|
||||
import { plugin } from '../src/plugin';
|
||||
import { circleCIPlugin } from '../src/plugin';
|
||||
|
||||
createDevApp().registerPlugin(plugin).render();
|
||||
createDevApp().registerPlugin(circleCIPlugin).render();
|
||||
|
||||
@@ -21,15 +21,25 @@ import { BuildWithStepsPage } from './BuildWithStepsPage/';
|
||||
import { BuildsPage } from './BuildsPage';
|
||||
import { CIRCLECI_ANNOTATION } from '../constants';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import { MissingAnnotationEmptyState } from '@backstage/core';
|
||||
|
||||
export const isPluginApplicableToEntity = (entity: Entity) =>
|
||||
export const isCircleCIAvailable = (entity: Entity) =>
|
||||
Boolean(entity.metadata.annotations?.[CIRCLECI_ANNOTATION]);
|
||||
|
||||
export const Router = ({ entity }: { entity: Entity }) =>
|
||||
!isPluginApplicableToEntity(entity) ? (
|
||||
<MissingAnnotationEmptyState annotation={CIRCLECI_ANNOTATION} />
|
||||
) : (
|
||||
type Props = {
|
||||
/** @deprecated The entity is now grabbed from context instead */
|
||||
entity?: Entity;
|
||||
};
|
||||
|
||||
export const Router = (_props: Props) => {
|
||||
const { entity } = useEntity();
|
||||
|
||||
if (!isCircleCIAvailable(entity)) {
|
||||
return <MissingAnnotationEmptyState annotation={CIRCLECI_ANNOTATION} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route path={`/${circleCIRouteRef.path}`} element={<BuildsPage />} />
|
||||
<Route
|
||||
@@ -38,3 +48,4 @@ export const Router = ({ entity }: { entity: Entity }) =>
|
||||
/>
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,8 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { plugin } from './plugin';
|
||||
export {
|
||||
circleCIPlugin,
|
||||
circleCIPlugin as plugin,
|
||||
EntityCircleCIContent,
|
||||
} from './plugin';
|
||||
export * from './api';
|
||||
export * from './route-refs';
|
||||
export { Router, isPluginApplicableToEntity } from './components/Router';
|
||||
export {
|
||||
Router,
|
||||
isCircleCIAvailable,
|
||||
isCircleCIAvailable as isPluginApplicableToEntity,
|
||||
} from './components/Router';
|
||||
export { CIRCLECI_ANNOTATION } from './constants';
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { plugin } from './plugin';
|
||||
import { circleCIPlugin } from './plugin';
|
||||
|
||||
describe('circleci', () => {
|
||||
it('should export plugin', () => {
|
||||
expect(plugin).toBeDefined();
|
||||
expect(circleCIPlugin).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,10 +18,12 @@ import {
|
||||
createPlugin,
|
||||
createApiFactory,
|
||||
discoveryApiRef,
|
||||
createRoutableExtension,
|
||||
} from '@backstage/core';
|
||||
import { circleCIApiRef, CircleCIApi } from './api';
|
||||
import { circleCIRouteRef } from './route-refs';
|
||||
|
||||
export const plugin = createPlugin({
|
||||
export const circleCIPlugin = createPlugin({
|
||||
id: 'circleci',
|
||||
apis: [
|
||||
createApiFactory({
|
||||
@@ -31,3 +33,10 @@ export const plugin = createPlugin({
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
export const EntityCircleCIContent = circleCIPlugin.provide(
|
||||
createRoutableExtension({
|
||||
component: () => import('./components/Router').then(m => m.Router),
|
||||
mountPoint: circleCIRouteRef,
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -14,6 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { createDevApp } from '@backstage/dev-utils';
|
||||
import { plugin } from '../src/plugin';
|
||||
import { cloudbuildPlugin } from '../src/plugin';
|
||||
|
||||
createDevApp().registerPlugin(plugin).render();
|
||||
createDevApp().registerPlugin(cloudbuildPlugin).render();
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/catalog-model": "^0.7.1",
|
||||
"@backstage/plugin-catalog-react": "^0.0.2",
|
||||
"@backstage/core": "^0.6.0",
|
||||
"@backstage/theme": "^0.2.3",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
|
||||
@@ -17,6 +17,7 @@ import React, { useEffect } from 'react';
|
||||
import { useWorkflowRuns } from '../useWorkflowRuns';
|
||||
import { WorkflowRun, WorkflowRunsTable } from '../WorkflowRunsTable';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import { WorkflowRunStatus } from '../WorkflowRunStatus';
|
||||
import { Link, Theme, makeStyles, LinearProgress } from '@material-ui/core';
|
||||
import {
|
||||
@@ -72,12 +73,13 @@ const WidgetContent = ({
|
||||
};
|
||||
|
||||
export const LatestWorkflowRunCard = ({
|
||||
entity,
|
||||
branch = 'master',
|
||||
}: {
|
||||
entity: Entity;
|
||||
/** @deprecated The entity is now grabbed from context instead */
|
||||
entity?: Entity;
|
||||
branch: string;
|
||||
}) => {
|
||||
const { entity } = useEntity();
|
||||
const errorApi = useApi(errorApiRef);
|
||||
const projectId = entity?.metadata.annotations?.[CLOUDBUILD_ANNOTATION] || '';
|
||||
|
||||
@@ -104,13 +106,17 @@ export const LatestWorkflowRunCard = ({
|
||||
};
|
||||
|
||||
export const LatestWorkflowsForBranchCard = ({
|
||||
entity,
|
||||
branch = 'master',
|
||||
}: {
|
||||
entity: Entity;
|
||||
/** @deprecated The entity is now grabbed from context instead */
|
||||
entity?: Entity;
|
||||
branch: string;
|
||||
}) => (
|
||||
<InfoCard title={`Last ${branch} build`}>
|
||||
<WorkflowRunsTable entity={entity} />
|
||||
</InfoCard>
|
||||
);
|
||||
}) => {
|
||||
const { entity } = useEntity();
|
||||
|
||||
return (
|
||||
<InfoCard title={`Last ${branch} build`}>
|
||||
<WorkflowRunsTable entity={entity} />
|
||||
</InfoCard>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
import React from 'react';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import { Routes, Route } from 'react-router';
|
||||
import { rootRouteRef, buildRouteRef } from '../plugin';
|
||||
import { WorkflowRunDetails } from './WorkflowRunDetails';
|
||||
@@ -22,14 +23,22 @@ import { WorkflowRunsTable } from './WorkflowRunsTable';
|
||||
import { CLOUDBUILD_ANNOTATION } from './useProjectName';
|
||||
import { MissingAnnotationEmptyState } from '@backstage/core';
|
||||
|
||||
export const isPluginApplicableToEntity = (entity: Entity) =>
|
||||
export const isCloudbuildAvailable = (entity: Entity) =>
|
||||
Boolean(entity.metadata.annotations?.[CLOUDBUILD_ANNOTATION]);
|
||||
|
||||
export const Router = ({ entity }: { entity: Entity }) =>
|
||||
// TODO(shmidt-i): move warning to a separate standardized component
|
||||
!isPluginApplicableToEntity(entity) ? (
|
||||
<MissingAnnotationEmptyState annotation={CLOUDBUILD_ANNOTATION} />
|
||||
) : (
|
||||
type Props = {
|
||||
/** @deprecated The entity is now grabbed from context instead */
|
||||
entity?: Entity;
|
||||
};
|
||||
|
||||
export const Router = (_props: Props) => {
|
||||
const { entity } = useEntity();
|
||||
|
||||
if (!isCloudbuildAvailable(entity)) {
|
||||
// TODO(shmidt-i): move warning to a separate standardized component
|
||||
return <MissingAnnotationEmptyState annotation={CLOUDBUILD_ANNOTATION} />;
|
||||
}
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
path={`/${rootRouteRef.path}`}
|
||||
@@ -42,3 +51,4 @@ export const Router = ({ entity }: { entity: Entity }) =>
|
||||
)
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,8 +13,18 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { plugin } from './plugin';
|
||||
export {
|
||||
cloudbuildPlugin,
|
||||
cloudbuildPlugin as plugin,
|
||||
EntityCloudbuildContent,
|
||||
EntityLatestCloudbuildRunCard,
|
||||
EntityLatestCloudbuildsForBranchCard,
|
||||
} from './plugin';
|
||||
export * from './api';
|
||||
export { Router, isPluginApplicableToEntity } from './components/Router';
|
||||
export {
|
||||
Router,
|
||||
isCloudbuildAvailable,
|
||||
isCloudbuildAvailable as isPluginApplicableToEntity,
|
||||
} from './components/Router';
|
||||
export * from './components/Cards';
|
||||
export { CLOUDBUILD_ANNOTATION } from './components/useProjectName';
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { plugin } from './plugin';
|
||||
import { cloudbuildPlugin } from './plugin';
|
||||
|
||||
describe('cloudbuild', () => {
|
||||
it('should export plugin', () => {
|
||||
expect(plugin).toBeDefined();
|
||||
expect(cloudbuildPlugin).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,6 +18,8 @@ import {
|
||||
createRouteRef,
|
||||
createApiFactory,
|
||||
googleAuthApiRef,
|
||||
createRoutableExtension,
|
||||
createComponentExtension,
|
||||
} from '@backstage/core';
|
||||
import { cloudbuildApiRef, CloudbuildClient } from './api';
|
||||
|
||||
@@ -31,7 +33,7 @@ export const buildRouteRef = createRouteRef({
|
||||
title: 'Cloudbuild Run',
|
||||
});
|
||||
|
||||
export const plugin = createPlugin({
|
||||
export const cloudbuildPlugin = createPlugin({
|
||||
id: 'cloudbuild',
|
||||
apis: [
|
||||
createApiFactory({
|
||||
@@ -42,4 +44,32 @@ export const plugin = createPlugin({
|
||||
},
|
||||
}),
|
||||
],
|
||||
routes: {
|
||||
entityContent: rootRouteRef,
|
||||
},
|
||||
});
|
||||
|
||||
export const EntityCloudbuildContent = cloudbuildPlugin.provide(
|
||||
createRoutableExtension({
|
||||
component: () => import('./components/Router').then(m => m.Router),
|
||||
mountPoint: rootRouteRef,
|
||||
}),
|
||||
);
|
||||
|
||||
export const EntityLatestCloudbuildRunCard = cloudbuildPlugin.provide(
|
||||
createComponentExtension({
|
||||
component: {
|
||||
lazy: () =>
|
||||
import('./components/Cards').then(m => m.LatestWorkflowRunCard),
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
export const EntityLatestCloudbuildsForBranchCard = cloudbuildPlugin.provide(
|
||||
createComponentExtension({
|
||||
component: {
|
||||
lazy: () =>
|
||||
import('./components/Cards').then(m => m.LatestWorkflowsForBranchCard),
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -15,6 +15,6 @@
|
||||
*/
|
||||
|
||||
import { createDevApp } from '@backstage/dev-utils';
|
||||
import { plugin } from '../src/plugin';
|
||||
import { githubActionsPlugin } from '../src/plugin';
|
||||
|
||||
createDevApp().registerPlugin(plugin).render();
|
||||
createDevApp().registerPlugin(githubActionsPlugin).render();
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/catalog-model": "^0.7.1",
|
||||
"@backstage/plugin-catalog-react": "^0.0.2",
|
||||
"@backstage/core": "^0.6.0",
|
||||
"@backstage/integration": "^0.3.2",
|
||||
"@backstage/theme": "^0.2.3",
|
||||
|
||||
@@ -17,6 +17,7 @@ import React, { useEffect } from 'react';
|
||||
import { useWorkflowRuns } from '../useWorkflowRuns';
|
||||
import { WorkflowRun, WorkflowRunsTable } from '../WorkflowRunsTable';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import { readGitHubIntegrationConfigs } from '@backstage/integration';
|
||||
import { WorkflowRunStatus } from '../WorkflowRunStatus';
|
||||
import {
|
||||
@@ -81,11 +82,11 @@ const WidgetContent = ({
|
||||
};
|
||||
|
||||
export const LatestWorkflowRunCard = ({
|
||||
entity,
|
||||
branch = 'master',
|
||||
// Display the card full height suitable for
|
||||
variant,
|
||||
}: Props) => {
|
||||
const { entity } = useEntity();
|
||||
const config = useApi(configApiRef);
|
||||
const errorApi = useApi(errorApiRef);
|
||||
// TODO: Get github hostname from metadata annotation
|
||||
@@ -121,17 +122,21 @@ export const LatestWorkflowRunCard = ({
|
||||
};
|
||||
|
||||
type Props = {
|
||||
entity: Entity;
|
||||
/** @deprecated The entity is now grabbed from context instead */
|
||||
entity?: Entity;
|
||||
branch: string;
|
||||
variant?: string;
|
||||
};
|
||||
|
||||
export const LatestWorkflowsForBranchCard = ({
|
||||
entity,
|
||||
branch = 'master',
|
||||
variant,
|
||||
}: Props) => (
|
||||
<InfoCard title={`Last ${branch} build`} variant={variant}>
|
||||
<WorkflowRunsTable branch={branch} entity={entity} />
|
||||
</InfoCard>
|
||||
);
|
||||
}: Props) => {
|
||||
const { entity } = useEntity();
|
||||
|
||||
return (
|
||||
<InfoCard title={`Last ${branch} build`} variant={variant}>
|
||||
<WorkflowRunsTable branch={branch} entity={entity} />
|
||||
</InfoCard>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
ConfigApi,
|
||||
ConfigReader,
|
||||
} from '@backstage/core';
|
||||
import { EntityProvider } from '@backstage/plugin-catalog-react';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import { render } from '@testing-library/react';
|
||||
@@ -84,7 +85,9 @@ describe('<RecentWorkflowRunsCard />', () => {
|
||||
configApi,
|
||||
)}
|
||||
>
|
||||
<RecentWorkflowRunsCard {...props} />
|
||||
<EntityProvider entity={props.entity!}>
|
||||
<RecentWorkflowRunsCard {...props} />
|
||||
</EntityProvider>
|
||||
</ApiProvider>
|
||||
</MemoryRouter>
|
||||
</ThemeProvider>,
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
useApi,
|
||||
} from '@backstage/core';
|
||||
import { readGitHubIntegrationConfigs } from '@backstage/integration';
|
||||
import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import { Button, Link } from '@material-ui/core';
|
||||
import React, { useEffect } from 'react';
|
||||
import { generatePath, Link as RouterLink } from 'react-router-dom';
|
||||
@@ -33,7 +34,8 @@ import { WorkflowRunStatus } from '../WorkflowRunStatus';
|
||||
const firstLine = (message: string): string => message.split('\n')[0];
|
||||
|
||||
export type Props = {
|
||||
entity: Entity;
|
||||
/** @deprecated The entity is now grabbed from context instead */
|
||||
entity?: Entity;
|
||||
branch?: string;
|
||||
dense?: boolean;
|
||||
limit?: number;
|
||||
@@ -41,12 +43,12 @@ export type Props = {
|
||||
};
|
||||
|
||||
export const RecentWorkflowRunsCard = ({
|
||||
entity,
|
||||
branch,
|
||||
dense = false,
|
||||
limit = 5,
|
||||
variant,
|
||||
}: Props) => {
|
||||
const { entity } = useEntity();
|
||||
const config = useApi(configApiRef);
|
||||
const errorApi = useApi(errorApiRef);
|
||||
// TODO: Get github hostname from metadata annotation
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
import React from 'react';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import { Routes, Route } from 'react-router';
|
||||
import { rootRouteRef, buildRouteRef } from '../plugin';
|
||||
import { WorkflowRunDetails } from './WorkflowRunDetails';
|
||||
@@ -22,13 +23,23 @@ import { WorkflowRunsTable } from './WorkflowRunsTable';
|
||||
import { GITHUB_ACTIONS_ANNOTATION } from './useProjectName';
|
||||
import { MissingAnnotationEmptyState } from '@backstage/core';
|
||||
|
||||
export const isPluginApplicableToEntity = (entity: Entity) =>
|
||||
export const isGithubActionsAvailable = (entity: Entity) =>
|
||||
Boolean(entity.metadata.annotations?.[GITHUB_ACTIONS_ANNOTATION]);
|
||||
|
||||
export const Router = ({ entity }: { entity: Entity }) =>
|
||||
!isPluginApplicableToEntity(entity) ? (
|
||||
<MissingAnnotationEmptyState annotation={GITHUB_ACTIONS_ANNOTATION} />
|
||||
) : (
|
||||
type Props = {
|
||||
/** @deprecated The entity is now grabbed from context instead */
|
||||
entity?: Entity;
|
||||
};
|
||||
|
||||
export const Router = (_props: Props) => {
|
||||
const { entity } = useEntity();
|
||||
|
||||
if (!isGithubActionsAvailable(entity)) {
|
||||
return (
|
||||
<MissingAnnotationEmptyState annotation={GITHUB_ACTIONS_ANNOTATION} />
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
path={`/${rootRouteRef.path}`}
|
||||
@@ -41,3 +52,4 @@ export const Router = ({ entity }: { entity: Entity }) =>
|
||||
)
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,8 +14,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { plugin } from './plugin';
|
||||
export {
|
||||
githubActionsPlugin,
|
||||
githubActionsPlugin as plugin,
|
||||
EntityGithubActionsContent,
|
||||
EntityLatestGithubActionRunCard,
|
||||
EntityLatestGithubActionsForBranchCard,
|
||||
EntityRecentGithubActionsRunsCard,
|
||||
} from './plugin';
|
||||
export * from './api';
|
||||
export { Router, isPluginApplicableToEntity } from './components/Router';
|
||||
export {
|
||||
Router,
|
||||
isGithubActionsAvailable,
|
||||
isGithubActionsAvailable as isPluginApplicableToEntity,
|
||||
} from './components/Router';
|
||||
export * from './components/Cards';
|
||||
export { GITHUB_ACTIONS_ANNOTATION } from './components/useProjectName';
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { plugin } from './plugin';
|
||||
import { githubActionsPlugin } from './plugin';
|
||||
|
||||
describe('github-actions', () => {
|
||||
it('should export plugin', () => {
|
||||
expect(plugin).toBeDefined();
|
||||
expect(githubActionsPlugin).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,6 +20,8 @@ import {
|
||||
createRouteRef,
|
||||
createApiFactory,
|
||||
githubAuthApiRef,
|
||||
createRoutableExtension,
|
||||
createComponentExtension,
|
||||
} from '@backstage/core';
|
||||
import { githubActionsApiRef, GithubActionsClient } from './api';
|
||||
|
||||
@@ -34,7 +36,7 @@ export const buildRouteRef = createRouteRef({
|
||||
title: 'GitHub Actions Workflow Run',
|
||||
});
|
||||
|
||||
export const plugin = createPlugin({
|
||||
export const githubActionsPlugin = createPlugin({
|
||||
id: 'github-actions',
|
||||
apis: [
|
||||
createApiFactory({
|
||||
@@ -44,4 +46,41 @@ export const plugin = createPlugin({
|
||||
new GithubActionsClient({ configApi, githubAuthApi }),
|
||||
}),
|
||||
],
|
||||
routes: {
|
||||
entityContent: rootRouteRef,
|
||||
},
|
||||
});
|
||||
|
||||
export const EntityGithubActionsContent = githubActionsPlugin.provide(
|
||||
createRoutableExtension({
|
||||
component: () => import('./components/Router').then(m => m.Router),
|
||||
mountPoint: rootRouteRef,
|
||||
}),
|
||||
);
|
||||
|
||||
export const EntityLatestGithubActionRunCard = githubActionsPlugin.provide(
|
||||
createComponentExtension({
|
||||
component: {
|
||||
lazy: () =>
|
||||
import('./components/Cards').then(m => m.LatestWorkflowRunCard),
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
export const EntityLatestGithubActionsForBranchCard = githubActionsPlugin.provide(
|
||||
createComponentExtension({
|
||||
component: {
|
||||
lazy: () =>
|
||||
import('./components/Cards').then(m => m.LatestWorkflowsForBranchCard),
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
export const EntityRecentGithubActionsRunsCard = githubActionsPlugin.provide(
|
||||
createComponentExtension({
|
||||
component: {
|
||||
lazy: () =>
|
||||
import('./components/Cards').then(m => m.RecentWorkflowRunsCard),
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -15,6 +15,6 @@
|
||||
*/
|
||||
|
||||
import { createDevApp } from '@backstage/dev-utils';
|
||||
import { plugin } from '../src/plugin';
|
||||
import { jenkinsPlugin } from '../src/plugin';
|
||||
|
||||
createDevApp().registerPlugin(plugin).render();
|
||||
createDevApp().registerPlugin(jenkinsPlugin).render();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
import React from 'react';
|
||||
import { Route, Routes } from 'react-router';
|
||||
import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import { buildRouteRef, rootRouteRef } from '../plugin';
|
||||
import { DetailedViewPage } from './BuildWithStepsPage/';
|
||||
import { JENKINS_ANNOTATION } from '../constants';
|
||||
@@ -22,13 +23,22 @@ import { Entity } from '@backstage/catalog-model';
|
||||
import { MissingAnnotationEmptyState } from '@backstage/core';
|
||||
import { CITable } from './BuildsPage/lib/CITable';
|
||||
|
||||
export const isPluginApplicableToEntity = (entity: Entity) =>
|
||||
export const isJenkinsAvailable = (entity: Entity) =>
|
||||
Boolean(entity.metadata.annotations?.[JENKINS_ANNOTATION]);
|
||||
|
||||
export const Router = ({ entity }: { entity: Entity }) => {
|
||||
return !isPluginApplicableToEntity(entity) ? (
|
||||
<MissingAnnotationEmptyState annotation={JENKINS_ANNOTATION} />
|
||||
) : (
|
||||
type Props = {
|
||||
/** @deprecated The entity is now grabbed from context instead */
|
||||
entity?: Entity;
|
||||
};
|
||||
|
||||
export const Router = (_props: Props) => {
|
||||
const { entity } = useEntity();
|
||||
|
||||
if (!isJenkinsAvailable(entity)) {
|
||||
return <MissingAnnotationEmptyState annotation={JENKINS_ANNOTATION} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route path={`/${rootRouteRef.path}`} element={<CITable />} />
|
||||
<Route path={`/${buildRouteRef.path}`} element={<DetailedViewPage />} />
|
||||
|
||||
@@ -14,8 +14,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { plugin } from './plugin';
|
||||
export {
|
||||
jenkinsPlugin,
|
||||
jenkinsPlugin as plugin,
|
||||
EntityJenkinsContent,
|
||||
EntityLatestJenkinsRunCard,
|
||||
} from './plugin';
|
||||
export { LatestRunCard } from './components/Cards';
|
||||
export { Router, isPluginApplicableToEntity } from './components/Router';
|
||||
export {
|
||||
Router,
|
||||
isJenkinsAvailable,
|
||||
isJenkinsAvailable as isPluginApplicableToEntity,
|
||||
} from './components/Router';
|
||||
export { JENKINS_ANNOTATION } from './constants';
|
||||
export * from './api';
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { plugin } from './plugin';
|
||||
import { jenkinsPlugin } from './plugin';
|
||||
|
||||
describe('jenkins', () => {
|
||||
it('should export plugin', () => {
|
||||
expect(plugin).toBeDefined();
|
||||
expect(jenkinsPlugin).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,6 +19,8 @@ import {
|
||||
createRouteRef,
|
||||
createApiFactory,
|
||||
discoveryApiRef,
|
||||
createRoutableExtension,
|
||||
createComponentExtension,
|
||||
} from '@backstage/core';
|
||||
import { jenkinsApiRef, JenkinsApi } from './api';
|
||||
|
||||
@@ -32,7 +34,7 @@ export const buildRouteRef = createRouteRef({
|
||||
title: 'Jenkins run',
|
||||
});
|
||||
|
||||
export const plugin = createPlugin({
|
||||
export const jenkinsPlugin = createPlugin({
|
||||
id: 'jenkins',
|
||||
apis: [
|
||||
createApiFactory({
|
||||
@@ -41,4 +43,21 @@ export const plugin = createPlugin({
|
||||
factory: ({ discoveryApi }) => new JenkinsApi({ discoveryApi }),
|
||||
}),
|
||||
],
|
||||
routes: {
|
||||
entityContent: rootRouteRef,
|
||||
},
|
||||
});
|
||||
|
||||
export const EntityJenkinsContent = jenkinsPlugin.provide(
|
||||
createRoutableExtension({
|
||||
component: () => import('./components/Router').then(m => m.Router),
|
||||
mountPoint: rootRouteRef,
|
||||
}),
|
||||
);
|
||||
export const EntityLatestJenkinsRunCard = jenkinsPlugin.provide(
|
||||
createComponentExtension({
|
||||
component: {
|
||||
lazy: () => import('./components/Cards').then(m => m.LatestRunCard),
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import { Route, Routes } from 'react-router-dom';
|
||||
import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import AuditList from './components/AuditList';
|
||||
import AuditView, { AuditViewContent } from './components/AuditView';
|
||||
import CreateAudit, { CreateAuditContent } from './components/CreateAudit';
|
||||
@@ -35,15 +36,27 @@ export const Router = () => (
|
||||
</Routes>
|
||||
);
|
||||
|
||||
export const EmbeddedRouter = ({ entity }: { entity: Entity }) =>
|
||||
!isLighthouseAvailable(entity) ? (
|
||||
<MissingAnnotationEmptyState
|
||||
annotation={LIGHTHOUSE_WEBSITE_URL_ANNOTATION}
|
||||
/>
|
||||
) : (
|
||||
type Props = {
|
||||
/** @deprecated The entity is now grabbed from context instead */
|
||||
entity?: Entity;
|
||||
};
|
||||
|
||||
export const EmbeddedRouter = (_props: Props) => {
|
||||
const { entity } = useEntity();
|
||||
|
||||
if (!isLighthouseAvailable(entity)) {
|
||||
return (
|
||||
<MissingAnnotationEmptyState
|
||||
annotation={LIGHTHOUSE_WEBSITE_URL_ANNOTATION}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/" element={<AuditListForEntity />} />
|
||||
<Route path="/audit/:id" element={<AuditViewContent />} />
|
||||
<Route path="/create-audit" element={<CreateAuditContent />} />
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
RELATION_PARENT_OF,
|
||||
} from '@backstage/catalog-model';
|
||||
import { Avatar, InfoCard } from '@backstage/core';
|
||||
import { entityRouteParams } from '@backstage/plugin-catalog-react';
|
||||
import { useEntity, entityRouteParams } from '@backstage/plugin-catalog-react';
|
||||
import { Box, Grid, Link, Tooltip, Typography } from '@material-ui/core';
|
||||
import AccountTreeIcon from '@material-ui/icons/AccountTree';
|
||||
import EmailIcon from '@material-ui/icons/Email';
|
||||
@@ -33,26 +33,29 @@ import { generatePath, Link as RouterLink } from 'react-router-dom';
|
||||
const GroupLink = ({
|
||||
groupName,
|
||||
index = 0,
|
||||
entity,
|
||||
}: {
|
||||
groupName: string;
|
||||
index?: number;
|
||||
entity: Entity;
|
||||
}) => (
|
||||
<>
|
||||
{index >= 1 ? ', ' : ''}
|
||||
<Link
|
||||
component={RouterLink}
|
||||
to={generatePath(
|
||||
`/catalog/:namespace/group/${groupName}`,
|
||||
entityRouteParams(entity),
|
||||
)}
|
||||
>
|
||||
[{groupName}]
|
||||
</Link>
|
||||
</>
|
||||
);
|
||||
/** @deprecated The entity is now grabbed from context instead */
|
||||
entity?: Entity;
|
||||
}) => {
|
||||
const { entity } = useEntity();
|
||||
|
||||
return (
|
||||
<>
|
||||
{index >= 1 ? ', ' : ''}
|
||||
<Link
|
||||
component={RouterLink}
|
||||
to={generatePath(
|
||||
`/catalog/:namespace/group/${groupName}`,
|
||||
entityRouteParams(entity),
|
||||
)}
|
||||
>
|
||||
[{groupName}]
|
||||
</Link>
|
||||
</>
|
||||
);
|
||||
};
|
||||
const CardTitle = ({ title }: { title: string }) => (
|
||||
<Box display="flex" alignItems="center">
|
||||
<GroupIcon fontSize="inherit" />
|
||||
@@ -61,12 +64,13 @@ const CardTitle = ({ title }: { title: string }) => (
|
||||
);
|
||||
|
||||
export const GroupProfileCard = ({
|
||||
entity: group,
|
||||
variant,
|
||||
}: {
|
||||
entity: GroupEntity;
|
||||
/** @deprecated The entity is now grabbed from context instead */
|
||||
entity?: GroupEntity;
|
||||
variant: string;
|
||||
}) => {
|
||||
const group = useEntity().entity as GroupEntity;
|
||||
const {
|
||||
metadata: { name, description },
|
||||
spec: { profile },
|
||||
|
||||
@@ -16,7 +16,11 @@
|
||||
|
||||
import { Entity, GroupEntity } from '@backstage/catalog-model';
|
||||
import { ApiProvider, ApiRegistry } from '@backstage/core';
|
||||
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import {
|
||||
CatalogApi,
|
||||
catalogApiRef,
|
||||
EntityProvider,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils';
|
||||
import React from 'react';
|
||||
import { MembersListCard } from './MembersListCard';
|
||||
@@ -78,7 +82,10 @@ describe('MemberTab Test', () => {
|
||||
const rendered = await renderWithEffects(
|
||||
wrapInTestApp(
|
||||
<ApiProvider apis={apis}>
|
||||
<MembersListCard entity={groupEntity} />
|
||||
<EntityProvider entity={groupEntity}>
|
||||
<MembersListCard />
|
||||
</EntityProvider>
|
||||
,
|
||||
</ApiProvider>,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
} from '@backstage/catalog-model';
|
||||
import { Avatar, InfoCard, Progress, useApi } from '@backstage/core';
|
||||
import {
|
||||
useEntity,
|
||||
catalogApiRef,
|
||||
entityRouteParams,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
@@ -105,11 +106,11 @@ const MemberComponent = ({
|
||||
);
|
||||
};
|
||||
|
||||
export const MembersListCard = ({
|
||||
entity: groupEntity,
|
||||
}: {
|
||||
entity: GroupEntity;
|
||||
export const MembersListCard = (_props: {
|
||||
/** @deprecated The entity is now grabbed from context instead */
|
||||
entity?: GroupEntity;
|
||||
}) => {
|
||||
const groupEntity = useEntity().entity as GroupEntity;
|
||||
const {
|
||||
metadata: { name: groupName },
|
||||
spec: { profile },
|
||||
|
||||
@@ -16,7 +16,11 @@
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { InfoCard, Progress, useApi } from '@backstage/core';
|
||||
import { catalogApiRef, isOwnerOf } from '@backstage/plugin-catalog-react';
|
||||
import {
|
||||
catalogApiRef,
|
||||
isOwnerOf,
|
||||
useEntity,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { pageTheme } from '@backstage/theme';
|
||||
import {
|
||||
Box,
|
||||
@@ -113,12 +117,13 @@ const EntityCountTile = ({
|
||||
};
|
||||
|
||||
export const OwnershipCard = ({
|
||||
entity,
|
||||
variant,
|
||||
}: {
|
||||
entity: Entity;
|
||||
/** @deprecated The entity is now grabbed from context instead */
|
||||
entity?: Entity;
|
||||
variant: string;
|
||||
}) => {
|
||||
const { entity } = useEntity();
|
||||
const catalogApi = useApi(catalogApiRef);
|
||||
const {
|
||||
loading,
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import { UserEntity } from '@backstage/catalog-model';
|
||||
import { EntityProvider } from '@backstage/plugin-catalog-react';
|
||||
import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils';
|
||||
import React from 'react';
|
||||
import { UserProfileCard } from './UserProfileCard';
|
||||
@@ -48,7 +49,11 @@ describe('UserSummary Test', () => {
|
||||
|
||||
it('Display Profile Card', async () => {
|
||||
const rendered = await renderWithEffects(
|
||||
wrapInTestApp(<UserProfileCard entity={userEntity} variant="gridItem" />),
|
||||
wrapInTestApp(
|
||||
<EntityProvider entity={userEntity}>
|
||||
<UserProfileCard entity={userEntity} variant="gridItem" />
|
||||
</EntityProvider>,
|
||||
),
|
||||
);
|
||||
|
||||
expect(rendered.getByText('calum-leavy@example.com')).toBeInTheDocument();
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
UserEntity,
|
||||
} from '@backstage/catalog-model';
|
||||
import { Avatar, InfoCard } from '@backstage/core';
|
||||
import { entityRouteParams } from '@backstage/plugin-catalog-react';
|
||||
import { useEntity, entityRouteParams } from '@backstage/plugin-catalog-react';
|
||||
import { Box, Grid, Link, Tooltip, Typography } from '@material-ui/core';
|
||||
import EmailIcon from '@material-ui/icons/Email';
|
||||
import GroupIcon from '@material-ui/icons/Group';
|
||||
@@ -60,12 +60,13 @@ const CardTitle = ({ title }: { title?: string }) =>
|
||||
) : null;
|
||||
|
||||
export const UserProfileCard = ({
|
||||
entity: user,
|
||||
variant,
|
||||
}: {
|
||||
entity: UserEntity;
|
||||
/** @deprecated The entity is now grabbed from context instead */
|
||||
entity?: UserEntity;
|
||||
variant: string;
|
||||
}) => {
|
||||
const user = useEntity().entity as UserEntity;
|
||||
const {
|
||||
metadata: { name: metaName },
|
||||
spec: { profile },
|
||||
|
||||
Reference in New Issue
Block a user