Merge pull request #11321 from Balfa/hchb/azgittags
Add Git Tags table for azure-devops plugin
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-azure-devops': patch
|
||||
'@backstage/plugin-azure-devops-backend': patch
|
||||
'@backstage/plugin-azure-devops-common': patch
|
||||
---
|
||||
|
||||
Added entity view for Azure Git Tags, based on existing Pull Requests view
|
||||
@@ -36,6 +36,7 @@ import {
|
||||
} from '@backstage/plugin-api-docs';
|
||||
import {
|
||||
EntityAzurePipelinesContent,
|
||||
EntityAzureGitTagsContent,
|
||||
EntityAzurePullRequestsContent,
|
||||
isAzureDevOpsAvailable,
|
||||
isAzurePipelinesAvailable,
|
||||
@@ -478,6 +479,14 @@ const websiteEntityPage = (
|
||||
<EntityKubernetesContent />
|
||||
</EntityLayout.Route>
|
||||
|
||||
<EntityLayout.Route
|
||||
if={isAzureDevOpsAvailable}
|
||||
path="/git-tags"
|
||||
title="Git Tags"
|
||||
>
|
||||
<EntityAzureGitTagsContent />
|
||||
</EntityLayout.Route>
|
||||
|
||||
<EntityLayout.Route path="/pull-requests" title="Pull Requests">
|
||||
{pullRequestsContent}
|
||||
</EntityLayout.Route>
|
||||
|
||||
@@ -10,6 +10,7 @@ import { Config } from '@backstage/config';
|
||||
import { DashboardPullRequest } from '@backstage/plugin-azure-devops-common';
|
||||
import express from 'express';
|
||||
import { GitRepository } from 'azure-devops-node-api/interfaces/GitInterfaces';
|
||||
import { GitTag } from '@backstage/plugin-azure-devops-common';
|
||||
import { Logger } from 'winston';
|
||||
import { PullRequest } from '@backstage/plugin-azure-devops-common';
|
||||
import { PullRequestOptions } from '@backstage/plugin-azure-devops-common';
|
||||
@@ -61,6 +62,8 @@ export class AzureDevOpsApi {
|
||||
repoName: string,
|
||||
): Promise<GitRepository>;
|
||||
// (undocumented)
|
||||
getGitTags(projectName: string, repoName: string): Promise<GitTag[]>;
|
||||
// (undocumented)
|
||||
getPullRequests(
|
||||
projectName: string,
|
||||
repoName: string,
|
||||
|
||||
@@ -21,16 +21,19 @@ import {
|
||||
import {
|
||||
BuildResult,
|
||||
BuildStatus,
|
||||
GitTag,
|
||||
PullRequest,
|
||||
PullRequestStatus,
|
||||
RepoBuild,
|
||||
} from '@backstage/plugin-azure-devops-common';
|
||||
import {
|
||||
GitPullRequest,
|
||||
GitRef,
|
||||
GitRepository,
|
||||
} from 'azure-devops-node-api/interfaces/GitInterfaces';
|
||||
import {
|
||||
mappedBuildRun,
|
||||
mappedGitTag,
|
||||
mappedPullRequest,
|
||||
mappedRepoBuild,
|
||||
} from './AzureDevOpsApi';
|
||||
@@ -263,6 +266,38 @@ describe('AzureDevOpsApi', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedGitTag', () => {
|
||||
describe('mappedGitTag happy path', () => {
|
||||
it('should return GitTag from GitRef', () => {
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
};
|
||||
const inputGitRef: GitRef = {
|
||||
name: 'refs/tags/v1.1.2',
|
||||
creator: inputIdentityRef,
|
||||
objectId: '1111aaaa2222bbbb3333cccc4444dddd5555eeee',
|
||||
peeledObjectId: '1234567890abcdef1234567890abcdef12345678',
|
||||
};
|
||||
const inputLinkBaseUrl =
|
||||
'https://host.com/myOrg/_git/super-feature-repo?version=GT';
|
||||
const inputCommitBaseUrl =
|
||||
'https://host.com/myOrg/_git/super-feature-repo/commit';
|
||||
const outputGitTag: GitTag = {
|
||||
name: 'v1.1.2',
|
||||
createdBy: 'Jane Doe',
|
||||
commitLink:
|
||||
'https://host.com/myOrg/_git/super-feature-repo/commit/1234567890abcdef1234567890abcdef12345678',
|
||||
objectId: '1111aaaa2222bbbb3333cccc4444dddd5555eeee',
|
||||
peeledObjectId: '1234567890abcdef1234567890abcdef12345678',
|
||||
link: 'https://host.com/myOrg/_git/super-feature-repo?version=GTv1.1.2',
|
||||
};
|
||||
expect(
|
||||
mappedGitTag(inputGitRef, inputLinkBaseUrl, inputCommitBaseUrl),
|
||||
).toEqual(outputGitTag);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedPullRequest', () => {
|
||||
describe('mappedPullRequest happy path', () => {
|
||||
it('should return PullRequest from GitPullRequest', () => {
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
BuildRun,
|
||||
BuildStatus,
|
||||
DashboardPullRequest,
|
||||
GitTag,
|
||||
Policy,
|
||||
PullRequest,
|
||||
PullRequestOptions,
|
||||
@@ -33,6 +34,7 @@ import {
|
||||
import {
|
||||
GitPullRequest,
|
||||
GitPullRequestSearchCriteria,
|
||||
GitRef,
|
||||
GitRepository,
|
||||
} from 'azure-devops-node-api/interfaces/GitInterfaces';
|
||||
import {
|
||||
@@ -123,6 +125,39 @@ export class AzureDevOpsApi {
|
||||
return repoBuilds;
|
||||
}
|
||||
|
||||
public async getGitTags(
|
||||
projectName: string,
|
||||
repoName: string,
|
||||
): Promise<GitTag[]> {
|
||||
this.logger?.debug(
|
||||
`Calling Azure DevOps REST API, getting Git Tags for Repository ${repoName} for Project ${projectName}`,
|
||||
);
|
||||
|
||||
const gitRepository = await this.getGitRepository(projectName, repoName);
|
||||
const client = await this.webApi.getGitApi();
|
||||
const tagRefs: GitRef[] = await client.getRefs(
|
||||
gitRepository.id as string,
|
||||
projectName,
|
||||
'tags',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
const linkBaseUrl = `${this.webApi.serverUrl}/${encodeURIComponent(
|
||||
projectName,
|
||||
)}/_git/${encodeURIComponent(repoName)}?version=GT`;
|
||||
const commitBaseUrl = `${this.webApi.serverUrl}/${encodeURIComponent(
|
||||
projectName,
|
||||
)}/_git/${encodeURIComponent(repoName)}/commit`;
|
||||
const gitTags: GitTag[] = tagRefs.map(tagRef => {
|
||||
return mappedGitTag(tagRef, linkBaseUrl, commitBaseUrl);
|
||||
});
|
||||
|
||||
return gitTags;
|
||||
}
|
||||
|
||||
public async getPullRequests(
|
||||
projectName: string,
|
||||
repoName: string,
|
||||
@@ -359,6 +394,25 @@ export function mappedRepoBuild(build: Build): RepoBuild {
|
||||
};
|
||||
}
|
||||
|
||||
export function mappedGitTag(
|
||||
gitRef: GitRef,
|
||||
linkBaseUrl: string,
|
||||
commitBaseUrl: string,
|
||||
): GitTag {
|
||||
return {
|
||||
objectId: gitRef.objectId,
|
||||
peeledObjectId: gitRef.peeledObjectId,
|
||||
name: gitRef.name?.replace('refs/tags/', ''),
|
||||
createdBy: gitRef.creator?.displayName ?? 'N/A',
|
||||
link: `${linkBaseUrl}${encodeURIComponent(
|
||||
gitRef.name?.replace('refs/tags/', '') ?? '',
|
||||
)}`,
|
||||
commitLink: `${commitBaseUrl}/${encodeURIComponent(
|
||||
gitRef.peeledObjectId ?? '',
|
||||
)}`,
|
||||
};
|
||||
}
|
||||
|
||||
export function mappedPullRequest(
|
||||
pullRequest: GitPullRequest,
|
||||
linkBaseUrl: string,
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
BuildResult,
|
||||
BuildRun,
|
||||
BuildStatus,
|
||||
GitTag,
|
||||
PullRequest,
|
||||
PullRequestStatus,
|
||||
RepoBuild,
|
||||
@@ -46,6 +47,7 @@ describe('createRouter', () => {
|
||||
getBuildDefinitions: jest.fn(),
|
||||
getRepoBuilds: jest.fn(),
|
||||
getDefinitionBuilds: jest.fn(),
|
||||
getGitTags: jest.fn(),
|
||||
getPullRequests: jest.fn(),
|
||||
getBuilds: jest.fn(),
|
||||
getBuildRuns: jest.fn(),
|
||||
@@ -208,6 +210,43 @@ describe('createRouter', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /git-tags/:projectName/:repoName', () => {
|
||||
it('fetches a list of git tags', async () => {
|
||||
const firstGitTag: GitTag = {
|
||||
name: 'v1.1.2',
|
||||
createdBy: 'Jane Doe',
|
||||
commitLink:
|
||||
'https://host.com/myOrg/_git/super-feature-repo/commit/1234567890abcdef1234567890abcdef12345678',
|
||||
objectId: '1111aaaa2222bbbb3333cccc4444dddd5555eeee',
|
||||
peeledObjectId: '1234567890abcdef1234567890abcdef12345678',
|
||||
link: 'https://host.com/myOrg/_git/super-feature-repo?version=GTv1.1.2',
|
||||
};
|
||||
|
||||
const secondGitTag: GitTag = {
|
||||
name: 'v1.2.0',
|
||||
createdBy: 'Jane Doe',
|
||||
commitLink:
|
||||
'https://host.com/myOrg/_git/super-feature-repo/commit/2222222222222222222222222222222222222222',
|
||||
objectId: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
|
||||
peeledObjectId: '2222222222222222222222222222222222222222',
|
||||
link: 'https://host.com/myOrg/_git/super-feature-repo?version=GTv1.2.0',
|
||||
};
|
||||
|
||||
const gitTags: GitTag[] = [firstGitTag, secondGitTag];
|
||||
|
||||
azureDevOpsApi.getGitTags.mockResolvedValueOnce(gitTags);
|
||||
|
||||
const response = await request(app).get('/git-tags/myProject/myRepo');
|
||||
|
||||
expect(azureDevOpsApi.getGitTags).toHaveBeenCalledWith(
|
||||
'myProject',
|
||||
'myRepo',
|
||||
);
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toEqual(gitTags);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /pull-requests/:projectName/:repoName', () => {
|
||||
it('fetches a list of pull requests', async () => {
|
||||
const firstPullRequest: PullRequest = {
|
||||
|
||||
@@ -97,6 +97,12 @@ export async function createRouter(
|
||||
res.status(200).json(gitRepository);
|
||||
});
|
||||
|
||||
router.get('/git-tags/:projectName/:repoName', async (req, res) => {
|
||||
const { projectName, repoName } = req.params;
|
||||
const gitTags = await azureDevOpsApi.getGitTags(projectName, repoName);
|
||||
res.status(200).json(gitTags);
|
||||
});
|
||||
|
||||
router.get('/pull-requests/:projectName/:repoName', async (req, res) => {
|
||||
const { projectName, repoName } = req.params;
|
||||
|
||||
|
||||
@@ -98,6 +98,18 @@ export interface DashboardPullRequest {
|
||||
title?: string;
|
||||
}
|
||||
|
||||
// Warning: (ae-missing-release-tag) "GitTag" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export type GitTag = {
|
||||
objectId?: string;
|
||||
peeledObjectId?: string;
|
||||
name?: string;
|
||||
createdBy?: string;
|
||||
link: string;
|
||||
commitLink: string;
|
||||
};
|
||||
|
||||
// Warning: (ae-missing-release-tag) "Policy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
|
||||
@@ -108,6 +108,15 @@ export enum PullRequestStatus {
|
||||
All = 4,
|
||||
}
|
||||
|
||||
export type GitTag = {
|
||||
objectId?: string;
|
||||
peeledObjectId?: string;
|
||||
name?: string;
|
||||
createdBy?: string;
|
||||
link: string;
|
||||
commitLink: string;
|
||||
};
|
||||
|
||||
export type PullRequest = {
|
||||
pullRequestId?: number;
|
||||
repoName?: string;
|
||||
|
||||
@@ -16,6 +16,12 @@ Lists the top _n_ Active, Completed, or Abandoned Pull Requests for a given repo
|
||||
|
||||

|
||||
|
||||
### Azure Repos Git Tags
|
||||
|
||||
Lists all Git Tags for a given repository
|
||||
|
||||

|
||||
|
||||
## Setup
|
||||
|
||||
The following sections will help you get the Azure DevOps plugin setup and running
|
||||
@@ -155,6 +161,42 @@ To get the Azure Repos component working you'll need to do the following two ste
|
||||
- The `if` prop is optional on the `EntityLayout.Route`, you can remove it if you always want to see the tab even if the entity being viewed does not have the needed annotation
|
||||
- The `defaultLimit` property on the `EntityAzurePullRequestsContent` will set the max number of Pull Requests you would like to see, if not set this will default to 10
|
||||
|
||||
### Git Tags Component
|
||||
|
||||
To get the Git Tags component working you'll need to do the following two steps:
|
||||
|
||||
1. First we need to add the @backstage/plugin-azure-devops package to your frontend app:
|
||||
|
||||
```bash
|
||||
# From your Backstage root directory
|
||||
yarn add --cwd packages/app @backstage/plugin-azure-devops
|
||||
```
|
||||
|
||||
2. Second we need to add the `EntityAzureGitTagsContent` extension to the entity page in your app:
|
||||
|
||||
```tsx
|
||||
// In packages/app/src/components/catalog/EntityPage.tsx
|
||||
import {
|
||||
EntityAzureGitTagsContent,
|
||||
isAzureDevOpsAvailable,
|
||||
} from '@backstage/plugin-azure-devops';
|
||||
|
||||
// For example in the Service section
|
||||
const serviceEntityPage = (
|
||||
<EntityLayout>
|
||||
// ...
|
||||
<EntityLayout.Route if={isAzureDevOpsAvailable} path="/git-tags" title="Git Tags">
|
||||
<EntityAzureGitTagsContent />
|
||||
</EntityLayout.Route>
|
||||
// ...
|
||||
</EntityLayout>
|
||||
```
|
||||
|
||||
**Notes:**
|
||||
|
||||
- You'll need to add the `EntityLayout.Route` above from step 2 to all the entity sections you want to see Git Tags in. For example if you wanted to see Git Tags when looking at Website entities then you would need to add this to the `websiteEntityPage` section.
|
||||
- The `if` prop is optional on the `EntityLayout.Route`, you can remove it if you always want to see the tab even if the entity being viewed does not have the needed annotation
|
||||
|
||||
## Limitations
|
||||
|
||||
- Currently multiple organizations are not supported
|
||||
|
||||
@@ -136,6 +136,11 @@ export type CreatedByUserFilter = BaseFilter &
|
||||
}
|
||||
);
|
||||
|
||||
// Warning: (ae-missing-release-tag) "EntityAzureGitTagsContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export const EntityAzureGitTagsContent: () => JSX.Element;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "EntityAzurePipelinesContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
@@ -18,6 +18,7 @@ import {
|
||||
BuildRun,
|
||||
BuildRunOptions,
|
||||
DashboardPullRequest,
|
||||
GitTag,
|
||||
PullRequest,
|
||||
PullRequestOptions,
|
||||
RepoBuild,
|
||||
@@ -38,6 +39,11 @@ export interface AzureDevOpsApi {
|
||||
options?: RepoBuildOptions,
|
||||
): Promise<{ items: RepoBuild[] }>;
|
||||
|
||||
getGitTags(
|
||||
projectName: string,
|
||||
repoName: string,
|
||||
): Promise<{ items: GitTag[] }>;
|
||||
|
||||
getPullRequests(
|
||||
projectName: string,
|
||||
repoName: string,
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
BuildRun,
|
||||
BuildRunOptions,
|
||||
DashboardPullRequest,
|
||||
GitTag,
|
||||
PullRequest,
|
||||
PullRequestOptions,
|
||||
RepoBuild,
|
||||
@@ -58,6 +59,18 @@ export class AzureDevOpsClient implements AzureDevOpsApi {
|
||||
return { items };
|
||||
}
|
||||
|
||||
public async getGitTags(
|
||||
projectName: string,
|
||||
repoName: string,
|
||||
): Promise<{ items: GitTag[] }> {
|
||||
const urlSegment = `git-tags/${encodeURIComponent(
|
||||
projectName,
|
||||
)}/${encodeURIComponent(repoName)}`;
|
||||
|
||||
const items = await this.get<GitTag[]>(urlSegment);
|
||||
return { items };
|
||||
}
|
||||
|
||||
public async getPullRequests(
|
||||
projectName: string,
|
||||
repoName: string,
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* 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 { SvgIcon, SvgIconProps } from '@material-ui/core';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
// From https://github.com/microsoft/fluentui-system-icons/blob/30a3e3c458883a1d63a43a951407f30e6b32b60c/assets/Tag/SVG/ic_fluent_tag_32_regular.svg
|
||||
export const AzureGitTagsIcon = (props: SvgIconProps) => (
|
||||
<SvgIcon {...props} viewBox="0 0 32 32">
|
||||
<path d="M22.5 12C23.8807 12 25 10.8807 25 9.5C25 8.11929 23.8807 7 22.5 7C21.1193 7 20 8.11929 20 9.5C20 10.8807 21.1193 12 22.5 12ZM18.6842 3C17.6695 3 16.6927 3.38568 15.9516 4.07892L3.77041 15.4742C2.01578 17.1157 1.96966 19.8841 3.66863 21.5831L9.99455 27.909C11.6543 29.5687 14.3452 29.5687 16.005 27.909L27.8282 16.0858C28.5783 15.3356 28.9998 14.3182 28.9998 13.2574V6.5C28.9998 4.567 27.4328 3 25.4998 3H18.6842ZM17.3179 5.53946C17.6884 5.19284 18.1769 5 18.6842 5H25.4998C26.3282 5 26.9998 5.67157 26.9998 6.5V13.2574C26.9998 13.7878 26.789 14.2965 26.414 14.6716L14.5907 26.4948C13.7121 27.3735 12.2874 27.3735 11.4088 26.4948L5.08284 20.1689C4.18339 19.2694 4.20781 17.8038 5.13673 16.9348L17.3179 5.53946Z" />
|
||||
</SvgIcon>
|
||||
);
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* 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 { AzureGitTagsIcon } from './AzureGitTagsIcon';
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* 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 { GitTagTable } from '../GitTagTable/GitTagTable';
|
||||
import React from 'react';
|
||||
|
||||
export const EntityPageAzureGitTags = () => <GitTagTable />;
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* 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 { EntityPageAzureGitTags } from './EntityPageAzureGitTags';
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* 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 { Box } from '@material-ui/core';
|
||||
import {
|
||||
Link,
|
||||
ResponseErrorPanel,
|
||||
Table,
|
||||
TableColumn,
|
||||
} from '@backstage/core-components';
|
||||
import { GitTag } from '@backstage/plugin-azure-devops-common';
|
||||
import React from 'react';
|
||||
|
||||
import { AzureGitTagsIcon } from '../AzureGitTagsIcon';
|
||||
import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import { useGitTags } from '../../hooks/useGitTags';
|
||||
|
||||
const columns: TableColumn[] = [
|
||||
{
|
||||
title: 'Tag',
|
||||
field: 'name',
|
||||
highlight: false,
|
||||
defaultSort: 'desc',
|
||||
width: 'auto',
|
||||
render: (row: Partial<GitTag>) => (
|
||||
<Box display="flex" alignItems="center">
|
||||
<Link to={row.link ?? ''}>{row.name}</Link>
|
||||
</Box>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Commit',
|
||||
field: 'peeledObjectId',
|
||||
width: 'auto',
|
||||
render: (row: Partial<GitTag>) => (
|
||||
<Box display="flex" alignItems="center">
|
||||
<Link to={row.commitLink ?? ''}>{row.peeledObjectId}</Link>
|
||||
</Box>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Created By',
|
||||
field: 'createdBy',
|
||||
width: 'auto',
|
||||
},
|
||||
];
|
||||
|
||||
export const GitTagTable = () => {
|
||||
const { entity } = useEntity();
|
||||
|
||||
const { items, loading, error } = useGitTags(entity);
|
||||
|
||||
if (error) {
|
||||
return <ResponseErrorPanel error={error} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Table
|
||||
isLoading={loading}
|
||||
columns={columns}
|
||||
options={{
|
||||
search: true,
|
||||
paging: true,
|
||||
pageSize: 5,
|
||||
showEmptyDataSourceMessage: !loading,
|
||||
}}
|
||||
title={
|
||||
<Box display="flex" alignItems="center">
|
||||
<AzureGitTagsIcon style={{ fontSize: 30 }} />
|
||||
<Box mr={1} />
|
||||
Azure Repos - Git Tags ({items ? items.length : 0})
|
||||
</Box>
|
||||
}
|
||||
data={items ?? []}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* 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 { GitTagTable } from './GitTagTable';
|
||||
@@ -103,11 +103,7 @@ export const PullRequestTable = ({ defaultLimit }: PullRequestTableProps) => {
|
||||
);
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div>
|
||||
<ResponseErrorPanel error={error} />
|
||||
</div>
|
||||
);
|
||||
return <ResponseErrorPanel error={error} />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* 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 { GitTag } from '@backstage/plugin-azure-devops-common';
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { azureDevOpsApiRef } from '../api';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import { useProjectRepoFromEntity } from './useProjectRepoFromEntity';
|
||||
|
||||
export function useGitTags(entity: Entity): {
|
||||
items?: GitTag[];
|
||||
loading: boolean;
|
||||
error?: Error;
|
||||
} {
|
||||
const api = useApi(azureDevOpsApiRef);
|
||||
const { project, repo } = useProjectRepoFromEntity(entity);
|
||||
|
||||
const { value, loading, error } = useAsync(() => {
|
||||
return api.getGitTags(project, repo);
|
||||
}, [api, project, repo]);
|
||||
|
||||
return {
|
||||
items: value?.items,
|
||||
loading,
|
||||
error,
|
||||
};
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
export {
|
||||
azureDevOpsPlugin,
|
||||
EntityAzurePipelinesContent,
|
||||
EntityAzureGitTagsContent,
|
||||
EntityAzurePullRequestsContent,
|
||||
isAzureDevOpsAvailable,
|
||||
isAzurePipelinesAvailable,
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
import {
|
||||
azurePipelinesEntityContentRouteRef,
|
||||
azurePullRequestDashboardRouteRef,
|
||||
azureGitTagsEntityContentRouteRef,
|
||||
azurePullRequestsEntityContentRouteRef,
|
||||
} from './routes';
|
||||
import {
|
||||
@@ -78,6 +79,17 @@ export const EntityAzurePipelinesContent = azureDevOpsPlugin.provide(
|
||||
}),
|
||||
);
|
||||
|
||||
export const EntityAzureGitTagsContent = azureDevOpsPlugin.provide(
|
||||
createRoutableExtension({
|
||||
name: 'EntityAzureGitTagsContent',
|
||||
component: () =>
|
||||
import('./components/EntityPageAzureGitTags').then(
|
||||
m => m.EntityPageAzureGitTags,
|
||||
),
|
||||
mountPoint: azureGitTagsEntityContentRouteRef,
|
||||
}),
|
||||
);
|
||||
|
||||
export const EntityAzurePullRequestsContent = azureDevOpsPlugin.provide(
|
||||
createRoutableExtension({
|
||||
name: 'EntityAzurePullRequestsContent',
|
||||
|
||||
@@ -24,6 +24,10 @@ export const azurePipelinesEntityContentRouteRef = createRouteRef({
|
||||
id: 'azure-pipelines-entity-content',
|
||||
});
|
||||
|
||||
export const azureGitTagsEntityContentRouteRef = createRouteRef({
|
||||
id: 'azure-git-tags-entity-content',
|
||||
});
|
||||
|
||||
export const azurePullRequestsEntityContentRouteRef = createRouteRef({
|
||||
id: 'azure-pull-requests-entity-content',
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user