diff --git a/packages/app/package.json b/packages/app/package.json
index 341953a204..e5dbbaa5ff 100644
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -19,6 +19,7 @@
"@backstage/plugin-explore": "^0.3.2",
"@backstage/plugin-gcp-projects": "^0.2.5",
"@backstage/plugin-github-actions": "^0.4.2",
+ "@backstage/plugin-github-deployments": "^0.1.1",
"@backstage/plugin-gitops-profiles": "^0.2.6",
"@backstage/plugin-graphiql": "^0.2.9",
"@backstage/plugin-jenkins": "^0.4.1",
diff --git a/packages/app/src/plugins.ts b/packages/app/src/plugins.ts
index 13b0daf7e3..ccc7e2a45c 100644
--- a/packages/app/src/plugins.ts
+++ b/packages/app/src/plugins.ts
@@ -45,3 +45,4 @@ export { plugin as Org } from '@backstage/plugin-org';
export { plugin as Kafka } from '@backstage/plugin-kafka';
export { todoPlugin } from '@backstage/plugin-todo';
export { badgesPlugin } from '@backstage/plugin-badges';
+export { githubDeploymentsPlugin } from '@backstage/plugin-github-deployments';
diff --git a/plugins/github-deployments/.eslintrc.js b/plugins/github-deployments/.eslintrc.js
new file mode 100644
index 0000000000..13573efa9c
--- /dev/null
+++ b/plugins/github-deployments/.eslintrc.js
@@ -0,0 +1,3 @@
+module.exports = {
+ extends: [require.resolve('@backstage/cli/config/eslint')],
+};
diff --git a/plugins/github-deployments/README.md b/plugins/github-deployments/README.md
new file mode 100644
index 0000000000..174d1bc8c7
--- /dev/null
+++ b/plugins/github-deployments/README.md
@@ -0,0 +1,62 @@
+# GitHub Deployments Plugin
+
+The GitHub Deployments Plugin displays recent deployments from GitHub.
+
+
+
+## Prerequisites
+
+- [GitHub Authentication Provider](https://backstage.io/docs/auth/github/provider)
+
+## Getting Started
+
+1. Install the GitHub Deployments Plugin.
+
+```bash
+# packages/app
+
+yarn add @backstage/plugin-github-deployments
+```
+
+2. Add the plugin to the app
+
+```typescript
+// packages/app/src/plugins.ts
+
+export { githubDeploymentsPlugin as GithubDeploymentsPlugin } from '@backstage/plugin-github-deployments';
+```
+
+3. Add the `EntityGithubDeploymentsCard` to the EntityPage:
+
+```typescript
+// packages/app/src/components/catalog/EntityPage.tsx
+
+import { EntityGithubDeploymentsCard } from '@backstage/plugin-github-deployments';
+
+const OverviewContent = () => (
+
+ // ...
+
+
+
+ // ...
+
+);
+```
+
+4. Add the `github.com/project-slug` annotation to your `catalog-info.yaml` file:
+
+```yaml
+apiVersion: backstage.io/v1alpha1
+kind: Component
+metadata:
+ name: backstage
+ description: |
+ Backstage is an open-source developer portal that puts the developer experience first.
+ annotations:
+ github.com/project-slug: YOUR_PROJECT_SLUG
+spec:
+ type: library
+ owner: CNCF
+ lifecycle: experimental
+```
diff --git a/plugins/github-deployments/dev/index.tsx b/plugins/github-deployments/dev/index.tsx
new file mode 100644
index 0000000000..dbb737c3c8
--- /dev/null
+++ b/plugins/github-deployments/dev/index.tsx
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2021 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { createDevApp } from '@backstage/dev-utils';
+import { githubDeploymentsPlugin } from '../src/plugin';
+
+createDevApp().registerPlugin(githubDeploymentsPlugin).render();
diff --git a/plugins/github-deployments/docs/github-deployments-card.png b/plugins/github-deployments/docs/github-deployments-card.png
new file mode 100644
index 0000000000..f56301c0fb
Binary files /dev/null and b/plugins/github-deployments/docs/github-deployments-card.png differ
diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json
new file mode 100644
index 0000000000..b8761c1385
--- /dev/null
+++ b/plugins/github-deployments/package.json
@@ -0,0 +1,51 @@
+{
+ "name": "@backstage/plugin-github-deployments",
+ "version": "0.1.1",
+ "main": "src/index.ts",
+ "types": "src/index.ts",
+ "license": "Apache-2.0",
+ "publishConfig": {
+ "access": "public",
+ "main": "dist/index.esm.js",
+ "types": "dist/index.d.ts"
+ },
+ "scripts": {
+ "build": "backstage-cli plugin:build",
+ "start": "backstage-cli plugin:serve",
+ "lint": "backstage-cli lint",
+ "test": "backstage-cli test",
+ "diff": "backstage-cli plugin:diff",
+ "prepack": "backstage-cli prepack",
+ "postpack": "backstage-cli postpack",
+ "clean": "backstage-cli clean"
+ },
+ "dependencies": {
+ "@backstage/catalog-model": "^0.7.4",
+ "@backstage/core": "^0.7.3",
+ "@backstage/plugin-catalog-react": "^0.1.3",
+ "@backstage/theme": "^0.2.5",
+ "@material-ui/core": "^4.11.0",
+ "@material-ui/icons": "^4.9.1",
+ "@material-ui/lab": "4.0.0-alpha.45",
+ "@octokit/graphql": "^4.5.8",
+ "luxon": "^1.26.0",
+ "react": "^16.13.1",
+ "react-dom": "^16.13.1",
+ "react-use": "^15.3.3"
+ },
+ "devDependencies": {
+ "@backstage/cli": "^0.6.6",
+ "@backstage/dev-utils": "^0.1.13",
+ "@backstage/test-utils": "^0.1.9",
+ "@testing-library/jest-dom": "^5.10.1",
+ "@testing-library/react": "^11.2.5",
+ "@testing-library/user-event": "^12.0.7",
+ "@types/jest": "^26.0.7",
+ "@types/node": "^14.14.32",
+ "cross-fetch": "^3.0.6",
+ "msw": "^0.21.2"
+ },
+ "files": [
+ "dist"
+ ]
+}
diff --git a/plugins/github-deployments/src/Router.tsx b/plugins/github-deployments/src/Router.tsx
new file mode 100644
index 0000000000..e48f17b75f
--- /dev/null
+++ b/plugins/github-deployments/src/Router.tsx
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2021 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Entity } from '@backstage/catalog-model';
+
+export const GITHUB_PROJECT_SLUG_ANNOTATION = 'github.com/project-slug';
+
+export const isGithubDeploymentsAvailable = (entity: Entity) =>
+ Boolean(entity?.metadata.annotations?.[GITHUB_PROJECT_SLUG_ANNOTATION]);
diff --git a/plugins/github-deployments/src/api/index.ts b/plugins/github-deployments/src/api/index.ts
new file mode 100644
index 0000000000..ca69ac3853
--- /dev/null
+++ b/plugins/github-deployments/src/api/index.ts
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2021 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { createApiRef, OAuthApi } from '@backstage/core';
+import { graphql } from '@octokit/graphql';
+
+export type GithubDeployment = {
+ environment: string;
+ state: string;
+ updatedAt: string;
+ commit: {
+ abbreviatedOid: string;
+ commitUrl: string;
+ };
+};
+
+export interface GithubDeploymentsApi {
+ listDeployments(options: {
+ owner: string;
+ repo: string;
+ last: number;
+ }): Promise;
+}
+
+export const githubDeploymentsApiRef = createApiRef({
+ id: 'plugin.github-deployments.service',
+ description: 'Used by the GitHub Deployments plugin to make requests',
+});
+
+export type Options = {
+ githubAuthApi: OAuthApi;
+};
+
+const deploymentsQuery = `
+query deployments($owner: String!, $repo: String!, $last: Int) {
+ repository(owner: $owner, name: $repo) {
+ deployments(last: $last) {
+ nodes {
+ state
+ environment
+ updatedAt
+ commit {
+ abbreviatedOid
+ commitUrl
+ }
+ }
+ }
+ }
+}
+`;
+
+export type QueryResponse = {
+ repository?: {
+ deployments?: {
+ nodes?: GithubDeployment[];
+ };
+ };
+};
+
+export class GithubDeploymentsApiClient implements GithubDeploymentsApi {
+ private readonly githubAuthApi: OAuthApi;
+
+ constructor(options: Options) {
+ this.githubAuthApi = options.githubAuthApi;
+ }
+
+ async listDeployments(options: {
+ owner: string;
+ repo: string;
+ last: number;
+ }): Promise {
+ const token = await this.githubAuthApi.getAccessToken(['repo']);
+
+ const graphQLWithAuth = graphql.defaults({
+ headers: {
+ authorization: `token ${token}`,
+ },
+ });
+
+ const response: QueryResponse = await graphQLWithAuth(
+ deploymentsQuery,
+ options,
+ );
+ return response.repository?.deployments?.nodes?.reverse() || [];
+ }
+}
diff --git a/plugins/github-deployments/src/components/GithubDeploymentsCard.test.tsx b/plugins/github-deployments/src/components/GithubDeploymentsCard.test.tsx
new file mode 100644
index 0000000000..678132bd8f
--- /dev/null
+++ b/plugins/github-deployments/src/components/GithubDeploymentsCard.test.tsx
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2021 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+import {
+ ApiProvider,
+ ApiRegistry,
+ errorApiRef,
+ configApiRef,
+ ConfigReader,
+ ConfigApi,
+ OAuthApi,
+} from '@backstage/core';
+
+import { msw, renderInTestApp } from '@backstage/test-utils';
+import { GithubDeploymentsApiClient, githubDeploymentsApiRef } from '../api';
+import { githubDeploymentsPlugin } from '../plugin';
+import { GithubDeploymentsCard } from './GithubDeploymentsCard';
+
+import { entityStub, noDataResponseStub, responseStub } from '../mocks/mocks';
+
+import { setupServer } from 'msw/node';
+import { graphql } from 'msw';
+
+jest.mock('@backstage/plugin-catalog-react', () => ({
+ useEntity: () => {
+ return entityStub;
+ },
+}));
+
+const errorApiMock = { post: jest.fn(), error$: jest.fn() };
+
+const configApi: ConfigApi = new ConfigReader({});
+const githubAuthApi: OAuthApi = {
+ getAccessToken: async _ => 'access_token',
+};
+
+const apis = ApiRegistry.from([
+ [configApiRef, configApi],
+ [errorApiRef, errorApiMock],
+ [githubDeploymentsApiRef, new GithubDeploymentsApiClient({ githubAuthApi })],
+]);
+
+describe('github-deployments', () => {
+ const worker = setupServer();
+ msw.setupDefaultHandlers(worker);
+
+ beforeEach(() => {
+ jest.resetAllMocks();
+ });
+
+ describe('export-plugin', () => {
+ it('should export plugin', () => {
+ expect(githubDeploymentsPlugin).toBeDefined();
+ });
+ });
+
+ describe('GithubDeploymentsCard', () => {
+ it('should display fetched data', async () => {
+ worker.use(
+ graphql.query('deployments', (_, res, ctx) =>
+ res(ctx.data(responseStub)),
+ ),
+ );
+
+ const rendered = await renderInTestApp(
+
+
+ ,
+ );
+
+ expect(await rendered.findByText('active')).toBeInTheDocument();
+ expect(await rendered.findByText('prd')).toBeInTheDocument();
+ expect(await rendered.findByText('12345')).toHaveAttribute(
+ 'href',
+ 'https://exampleapi.com/123456789',
+ );
+
+ expect(await rendered.findByText('pending')).toBeInTheDocument();
+ expect(await rendered.findByText('lab')).toBeInTheDocument();
+ expect(await rendered.findByText('54321')).toHaveAttribute(
+ 'href',
+ 'https://exampleapi.com/543212345',
+ );
+ });
+
+ it('should display empty state when no data', async () => {
+ worker.use(
+ graphql.query('deployments', (_, res, ctx) =>
+ res(ctx.data(noDataResponseStub)),
+ ),
+ );
+
+ const rendered = await renderInTestApp(
+
+
+ ,
+ );
+
+ expect(
+ await rendered.findByText('No deployments found for this entity.'),
+ ).toBeInTheDocument();
+ });
+ });
+});
diff --git a/plugins/github-deployments/src/components/GithubDeploymentsCard.tsx b/plugins/github-deployments/src/components/GithubDeploymentsCard.tsx
new file mode 100644
index 0000000000..6be4a5a6b3
--- /dev/null
+++ b/plugins/github-deployments/src/components/GithubDeploymentsCard.tsx
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2021 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+import {
+ InfoCard,
+ MissingAnnotationEmptyState,
+ Progress,
+ ResponseErrorPanel,
+ useApi,
+} from '@backstage/core';
+import { useAsync } from 'react-use';
+import { githubDeploymentsApiRef } from '../api';
+import { useEntity } from '@backstage/plugin-catalog-react';
+import {
+ GITHUB_PROJECT_SLUG_ANNOTATION,
+ isGithubDeploymentsAvailable,
+} from '../Router';
+import GithubDeploymentsTable from './GithubDeploymentsTable/GithubDeploymentsTable';
+
+const GithubDeploymentsComponent = ({
+ projectSlug,
+ last,
+}: {
+ projectSlug: string;
+ last: number;
+}) => {
+ const api = useApi(githubDeploymentsApiRef);
+ const [owner, repo] = projectSlug.split('/');
+
+ const { loading, value, error } = useAsync(
+ async () => await api.listDeployments({ owner, repo, last }),
+ );
+
+ if (loading) {
+ return (
+
+
+
+ );
+ }
+ if (error) {
+ return ;
+ }
+
+ return ;
+};
+
+export const GithubDeploymentsCard = ({ last }: { last?: number }) => {
+ const { entity } = useEntity();
+
+ return !isGithubDeploymentsAvailable(entity) ? (
+
+ ) : (
+
+ );
+};
diff --git a/plugins/github-deployments/src/components/GithubDeploymentsTable/GithubDeploymentsTable.tsx b/plugins/github-deployments/src/components/GithubDeploymentsTable/GithubDeploymentsTable.tsx
new file mode 100644
index 0000000000..f5fae7f449
--- /dev/null
+++ b/plugins/github-deployments/src/components/GithubDeploymentsTable/GithubDeploymentsTable.tsx
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2021 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+import {
+ StatusPending,
+ StatusRunning,
+ StatusOK,
+ Table,
+ TableColumn,
+ StatusAborted,
+ StatusError,
+} from '@backstage/core';
+import { GithubDeployment } from '../../api';
+import { DateTime } from 'luxon';
+import { Box, Typography, Link, makeStyles } from '@material-ui/core';
+
+const useStyles = makeStyles(theme => ({
+ empty: {
+ padding: theme.spacing(2),
+ display: 'flex',
+ justifyContent: 'center',
+ },
+}));
+
+const statusIndicator = (value: string): React.ReactNode => {
+ switch (value) {
+ case 'PENDING':
+ return ;
+ case 'IN_PROGRESS':
+ return ;
+ case 'ACTIVE':
+ return ;
+ case 'ERROR':
+ case 'FAILURE':
+ return ;
+ default:
+ return ;
+ }
+};
+
+const columns: TableColumn[] = [
+ {
+ title: 'Environment',
+ field: 'environment',
+ highlight: true,
+ },
+ {
+ title: 'Status',
+ render: (row: GithubDeployment): React.ReactNode => (
+
+ {statusIndicator(row.state)}
+ {row.state}
+
+ ),
+ },
+ {
+ title: 'Commit',
+ render: (row: GithubDeployment): React.ReactNode => (
+
+ {row.commit.abbreviatedOid}
+
+ ),
+ },
+ {
+ title: 'Last Updated',
+ render: (row: GithubDeployment): React.ReactNode =>
+ DateTime.fromISO(row.updatedAt).toRelative({ locale: 'en' }),
+ },
+];
+
+type GithubDeploymentsTableProps = {
+ deployments: GithubDeployment[];
+};
+
+const GithubDeploymentsTable = ({
+ deployments,
+}: GithubDeploymentsTableProps) => {
+ const classes = useStyles();
+
+ return (
+
+
+ No deployments found for this entity.
+
+
+ }
+ />
+ );
+};
+
+export default GithubDeploymentsTable;
diff --git a/plugins/github-deployments/src/index.ts b/plugins/github-deployments/src/index.ts
new file mode 100644
index 0000000000..2ee681332a
--- /dev/null
+++ b/plugins/github-deployments/src/index.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2021 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export { githubDeploymentsPlugin, EntityGithubDeploymentsCard } from './plugin';
+export { isGithubDeploymentsAvailable } from './Router';
diff --git a/plugins/github-deployments/src/mocks/mocks.ts b/plugins/github-deployments/src/mocks/mocks.ts
new file mode 100644
index 0000000000..6a394b54bf
--- /dev/null
+++ b/plugins/github-deployments/src/mocks/mocks.ts
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2021 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { QueryResponse } from '../api';
+
+export const entityStub = {
+ entity: {
+ metadata: {
+ namespace: 'default',
+ annotations: {
+ 'github.com/project-slug': 'org/repo',
+ },
+ name: 'sample-service',
+ description: 'Sample service',
+ uid: 'g0h33dd9-56h7-835b-b63v-7x5da3j64851',
+ generation: 1,
+ },
+ apiVersion: 'backstage.io/v1alpha1',
+ kind: 'Component',
+ spec: {
+ type: 'service',
+ lifecycle: 'experimental',
+ },
+ relations: [],
+ },
+};
+
+export const responseStub: QueryResponse = {
+ repository: {
+ deployments: {
+ nodes: [
+ {
+ state: 'active',
+ environment: 'prd',
+ updatedAt: '2021-03-25T12:08:45Z',
+ commit: {
+ commitUrl: 'https://exampleapi.com/123456789',
+ abbreviatedOid: '12345',
+ },
+ },
+ {
+ state: 'pending',
+ environment: 'lab',
+ updatedAt: '2021-03-25T12:08:47Z',
+ commit: {
+ commitUrl: 'https://exampleapi.com/543212345',
+ abbreviatedOid: '54321',
+ },
+ },
+ ],
+ },
+ },
+};
+
+export const noDataResponseStub: QueryResponse = {};
diff --git a/plugins/github-deployments/src/plugin.test.ts b/plugins/github-deployments/src/plugin.test.ts
new file mode 100644
index 0000000000..cac5d58c63
--- /dev/null
+++ b/plugins/github-deployments/src/plugin.test.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2021 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { githubDeploymentsPlugin } from './plugin';
+
+describe('graphiql', () => {
+ it('should export plugin', () => {
+ expect(githubDeploymentsPlugin).toBeDefined();
+ });
+});
diff --git a/plugins/github-deployments/src/plugin.ts b/plugins/github-deployments/src/plugin.ts
new file mode 100644
index 0000000000..3707b1cf68
--- /dev/null
+++ b/plugins/github-deployments/src/plugin.ts
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {
+ createApiFactory,
+ createComponentExtension,
+ createPlugin,
+ githubAuthApiRef,
+} from '@backstage/core';
+import { githubDeploymentsApiRef, GithubDeploymentsApiClient } from './api';
+
+export const githubDeploymentsPlugin = createPlugin({
+ id: 'github-deployments',
+ apis: [
+ createApiFactory({
+ api: githubDeploymentsApiRef,
+ deps: { githubAuthApi: githubAuthApiRef },
+ factory: ({ githubAuthApi }) =>
+ new GithubDeploymentsApiClient({ githubAuthApi }),
+ }),
+ ],
+});
+
+export const EntityGithubDeploymentsCard = githubDeploymentsPlugin.provide(
+ createComponentExtension({
+ component: {
+ lazy: () =>
+ import('./components/GithubDeploymentsCard').then(
+ m => m.GithubDeploymentsCard,
+ ),
+ },
+ }),
+);
diff --git a/plugins/github-deployments/src/setupTests.ts b/plugins/github-deployments/src/setupTests.ts
new file mode 100644
index 0000000000..0cec5b395d
--- /dev/null
+++ b/plugins/github-deployments/src/setupTests.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2021 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import '@testing-library/jest-dom';
+import 'cross-fetch/polyfill';