diff --git a/src/api/GitlabCIApi.ts b/src/api/GitlabCIApi.ts index 4bda280..fe876df 100644 --- a/src/api/GitlabCIApi.ts +++ b/src/api/GitlabCIApi.ts @@ -48,4 +48,5 @@ export type GitlabCIApi = { pipelineID: string, ): Promise; getProjectDetails(projectSlug: string): Promise; + getFileContent(projectId: string, filename: string, ref: string): Promise; }; diff --git a/src/api/GitlabCIClient.ts b/src/api/GitlabCIClient.ts index 965855f..b0844fb 100644 --- a/src/api/GitlabCIClient.ts +++ b/src/api/GitlabCIClient.ts @@ -11,6 +11,7 @@ import { ContributorData, MergeRequest, PipelineObject, + RepositoryFileObject, } from '../components/types'; export class GitlabCIClient implements GitlabCIApi { @@ -161,4 +162,27 @@ export class GitlabCIClient implements GitlabCIApi { ); return retryBuild; } + + private static encodeFilename(filename: string) { + return filename.replace(".", "%2E") + } + + async getFileContent( + projectId: string, + filename: string, + ref: string + ): Promise { + const encodedFilename = GitlabCIClient.encodeFilename(filename) + let fileObj: any = await this.callApi( + `projects/${projectId}/repository/files/${encodedFilename}`, + {ref}, + ); + + if (!fileObj?.content) { + return undefined; + } + + const buff = new Buffer(fileObj?.content, 'base64'); + return buff.toString('ascii'); + } } diff --git a/src/components/types.ts b/src/components/types.ts index a6906e9..4196448 100644 --- a/src/components/types.ts +++ b/src/components/types.ts @@ -34,4 +34,17 @@ export type PipelineObject = { updated_at: string; }; +export type RepositoryFileObject = { + file_name: string; + file_path: string; + size: number, + encoding: string; + content: string; + content_sha256: string; + ref: string; + blob_id: string; + commit_id: string; + last_commit_id: string; +}; + export type MergeRequestState = 'opened' | 'closed' | 'all'; diff --git a/src/components/widgets/ReadmeCard/ReadmeCard.tsx b/src/components/widgets/ReadmeCard/ReadmeCard.tsx new file mode 100644 index 0000000..a76ca66 --- /dev/null +++ b/src/components/widgets/ReadmeCard/ReadmeCard.tsx @@ -0,0 +1,74 @@ +import React from 'react'; +import Alert from '@material-ui/lab/Alert'; +import { InfoCard, MarkdownContent, Progress } from '@backstage/core-components'; +import { makeStyles } from "@material-ui/core"; +import { Entity } from "@backstage/catalog-model"; +import { useApi } from '@backstage/core-plugin-api'; +import { useAsync } from 'react-use'; +import { GitlabCIApiRef } from '../../../api'; +import { gitlabAppData } from '../../gitlabAppData'; + +type Props = { + entity?: Entity; + maxHeight?: number; +}; + +const useStyles = makeStyles((theme) => ({ + readMe: { + overflowY: 'auto', + paddingRight: theme.spacing(1), + '&::-webkit-scrollbar-track': { + backgroundColor: '#F5F5F5', + borderRadius: '5px', + }, + '&::-webkit-scrollbar': { + width: '5px', + backgroundColor: '#F5F5F5', + borderRadius: '5px', + }, + '&::-webkit-scrollbar-thumb': { + border: '1px solid #555555', + backgroundColor: '#555', + borderRadius: '4px', + }, + }, +})); +export const ReadmeCard = (props: Props) => { + const GitlabCIAPI = useApi(GitlabCIApiRef); + const { project_id } = gitlabAppData(); + // This should probably be moved into annotations + const filename = "README.md"; + const ref = "master"; + + const { value, loading, error } = useAsync(async (): Promise => { + const content = await GitlabCIAPI.getFileContent(project_id, filename, ref) + if (!content) { + throw new Error("No content could be found for the specified filename") + } + return content; + }); + + const classes = useStyles(); + + if (loading) { + return ; + } else if (error) { + return + {error.message} + + } + + return ( + +
+ +
+
+ ); +}; diff --git a/src/components/widgets/ReadmeCard/index.ts b/src/components/widgets/ReadmeCard/index.ts new file mode 100644 index 0000000..5043359 --- /dev/null +++ b/src/components/widgets/ReadmeCard/index.ts @@ -0,0 +1 @@ +export { ReadmeCard } from './ReadmeCard'; diff --git a/src/components/widgets/index.ts b/src/components/widgets/index.ts index 0ee5bb1..a477c7f 100644 --- a/src/components/widgets/index.ts +++ b/src/components/widgets/index.ts @@ -2,4 +2,5 @@ export { LanguagesCard } from './LanguagesCard'; export { ContributorsCard } from './ContributorsCard'; export { MergeRequestStats } from './MergeRequestStats'; export { MergeRequestsTable } from './MergeRequestsTable'; -export { PipelinesTable } from './PipelinesTable'; \ No newline at end of file +export { PipelinesTable } from './PipelinesTable'; +export { ReadmeCard } from './ReadmeCard'; \ No newline at end of file diff --git a/src/plugin.ts b/src/plugin.ts index 779e6eb..2c5f0f9 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -86,4 +86,14 @@ export const EntityGitlabPipelinesTable = gitlabPlugin.provide( import('./components/widgets/index').then((m) => m.PipelinesTable), }, }) -); \ No newline at end of file +); + +export const EntityGitlabReadmeCard = gitlabPlugin.provide( + createComponentExtension({ + name: 'EntityGitlabReadmeCard', + component: { + lazy: () => + import('./components/widgets/index').then((m) => m.ReadmeCard), + }, + }) +);