From 08d0a6abf10b1c79bcacafd503b450e6c2544c22 Mon Sep 17 00:00:00 2001 From: djamaile Date: Fri, 11 Mar 2022 19:33:32 +0100 Subject: [PATCH 01/12] feat: introduce cicd-statistics-module-gitlab plugin Signed-off-by: djamaile --- packages/app/src/apis.ts | 13 +- .../app/src/components/catalog/EntityPage.tsx | 5 + .../.eslintrc.js | 3 + .../cicd-statistics-module-gitlab/README.md | 9 + .../package.json | 48 +++++ .../src/api/gitlab.ts | 189 ++++++++++++++++++ .../src/api/index.ts | 17 ++ .../src/index.ts | 17 ++ .../src/setupTests.ts | 17 ++ plugins/cicd-statistics/src/apis/types.ts | 2 +- .../src/components/button-switch.tsx | 3 + plugins/cicd-statistics/src/entity-page.tsx | 2 + .../cicd-statistics/src/utils/stage-names.ts | 4 +- 13 files changed, 326 insertions(+), 3 deletions(-) create mode 100644 plugins/cicd-statistics-module-gitlab/.eslintrc.js create mode 100644 plugins/cicd-statistics-module-gitlab/README.md create mode 100644 plugins/cicd-statistics-module-gitlab/package.json create mode 100644 plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts create mode 100644 plugins/cicd-statistics-module-gitlab/src/api/index.ts create mode 100644 plugins/cicd-statistics-module-gitlab/src/index.ts create mode 100644 plugins/cicd-statistics-module-gitlab/src/setupTests.ts diff --git a/packages/app/src/apis.ts b/packages/app/src/apis.ts index d587a88402..afc96a68db 100644 --- a/packages/app/src/apis.ts +++ b/packages/app/src/apis.ts @@ -32,8 +32,10 @@ import { configApiRef, createApiFactory, errorApiRef, - githubAuthApiRef, + githubAuthApiRef, gitlabAuthApiRef, } from '@backstage/core-plugin-api'; +import { cicdStatisticsApiRef } from '@backstage/plugin-cicd-statistics'; +import {CicdStatisticsApiGitlab} from "@backstage/plugin-cicd-statistics-module-gitlab"; export const apis: AnyApiFactory[] = [ createApiFactory({ @@ -42,6 +44,7 @@ export const apis: AnyApiFactory[] = [ factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi), }), + ScmAuth.createDefaultApiFactory(), createApiFactory({ @@ -64,4 +67,12 @@ export const apis: AnyApiFactory[] = [ }), createApiFactory(costInsightsApiRef, new ExampleCostInsightsClient()), + createApiFactory({ + api: cicdStatisticsApiRef, + deps: {gitlabAuthApi: gitlabAuthApiRef}, + factory({ gitlabAuthApi }) { + return new CicdStatisticsApiGitlab(gitlabAuthApi); + }, + }), +// createApiFactory(cicdStatisticsApiRef, new CicdStatisticsApiGitlab()), ]; diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index 26068c6c8f..89897905b8 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -136,6 +136,7 @@ import { EntityNewRelicDashboardCard, } from '@backstage/plugin-newrelic-dashboard'; import { EntityGoCdContent, isGoCdAvailable } from '@backstage/plugin-gocd'; +import {EntityCicdStatisticsContent} from "@backstage/plugin-cicd-statistics"; import React, { ReactNode, useMemo, useState } from 'react'; @@ -444,6 +445,10 @@ const websiteEntityPage = ( {cicdContent} + + + + diff --git a/plugins/cicd-statistics-module-gitlab/.eslintrc.js b/plugins/cicd-statistics-module-gitlab/.eslintrc.js new file mode 100644 index 0000000000..13573efa9c --- /dev/null +++ b/plugins/cicd-statistics-module-gitlab/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [require.resolve('@backstage/cli/config/eslint')], +}; diff --git a/plugins/cicd-statistics-module-gitlab/README.md b/plugins/cicd-statistics-module-gitlab/README.md new file mode 100644 index 0000000000..85c297932e --- /dev/null +++ b/plugins/cicd-statistics-module-gitlab/README.md @@ -0,0 +1,9 @@ +# cicd-statistics-module-gitlab + +## Getting started + +Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/cicd-statistics-module-gitlab](http://localhost:3000/cicd-statistics-module-gitlab). + +You can also serve the plugin in isolation by running `yarn start` in the plugin directory. +This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. +It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. diff --git a/plugins/cicd-statistics-module-gitlab/package.json b/plugins/cicd-statistics-module-gitlab/package.json new file mode 100644 index 0000000000..df9ccef6b8 --- /dev/null +++ b/plugins/cicd-statistics-module-gitlab/package.json @@ -0,0 +1,48 @@ +{ + "name": "@backstage/plugin-cicd-statistics-module-gitlab", + "description": "CI/CD Statistics plugin module; Gitlab CICD", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "private": false, + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "frontend-plugin" + }, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/cicd-statistics-module-gitlab" + }, + "keywords": [ + "backstage", + "cicd statestics", + "gitlab" + ], + "scripts": { + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test" + }, + "dependencies": { + "@backstage/catalog-model": "^0.9.10", + "@backstage/core-plugin-api": "^0.8.0", + "@backstage/plugin-cicd-statistics": "^0.1.0", + "@gitbeaker/browser": "34.2.0", + "@gitbeaker/core": "^35.4.0", + "lodash": "^4.17.21", + "luxon": "^2.0.2", + "p-limit": "^4.0.0" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts b/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts new file mode 100644 index 0000000000..a28ce612d5 --- /dev/null +++ b/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts @@ -0,0 +1,189 @@ +/* + * Copyright 2022 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 { + CicdStatisticsApi, + CicdState, + CicdConfiguration, + Build, + FilterStatusType, + FetchBuildsOptions, + Stage, +} from '@backstage/plugin-cicd-statistics'; +import { Gitlab } from '@gitbeaker/browser'; +import { OAuthApi } from '@backstage/core-plugin-api'; +import limiterFactory from 'p-limit'; + +import { Types } from '@gitbeaker/core'; +import { Entity, getEntitySourceLocation } from '@backstage/catalog-model'; + +const statusMap: Record = { + manual: 'unknown', + created: 'enqueued', + waiting_for_resource: 'stalled', + preparing: 'unknown', + pending: 'scheduled', + running: 'running', + success: 'succeeded', + failed: 'failed', + canceled: 'aborted', + skipped: 'aborted', + scheduled: 'scheduled', +}; + +function jobtToBuild(jobs: Array): Build[] { + return jobs.map(j => { + return { + id: j.id.toString(), + status: statusMap[j.status], + branchType: 'master', + duration: 0, // will get filled in later in a seperate API call + requestedAt: new Date(j.created_at), + stages: [], + }; + }); +} + +function jobsToStages(jobs: Array): Stage[] { + return jobs.map(j => { + const status = statusMap[j.status] ? statusMap[j.status] : 'unknown'; + return { + name: j.name, + status: status, + duration: j.duration ? ((j.duration * 1000) as number) : 0, + }; + }); +} + +type GitlabClient = { + api: InstanceType; + owner: string; +}; + +export class CicdStatisticsApiGitlab implements CicdStatisticsApi { + readonly #gitLabAuthApi: OAuthApi; + + constructor(gitLabAuthApi: OAuthApi) { + this.#gitLabAuthApi = gitLabAuthApi; + } + + public async createGitlabApi( + entity: Entity, + scopes: string[], + ): Promise { + const entityInfo = getEntitySourceLocation(entity); + const url = new URL(entityInfo.target); + const owner = url.pathname.split('/-/blob/')[0]; + const oauthToken = await this.#gitLabAuthApi.getAccessToken(scopes); + return { + api: new Gitlab({ + host: `https://${url.host}`, + oauthToken, + }), + owner: owner.substring(1), + }; + } + + private static async updateBuildWithStages( + gitbeaker: InstanceType, + owner: string, + build: Build, + ): Promise { + const jobs = await gitbeaker.Jobs.showPipelineJobs( + owner, + parseInt(build.id, 10), + ); + const stages = jobsToStages(jobs); + return stages; + } + + private static async getDurationOfBuild( + gitbeaker: InstanceType, + owner: string, + build: Build, + ): Promise { + const pipeline = (await gitbeaker.Pipelines.show( + owner, + parseInt(build.id, 10), + )) as Types.PipelineExtendedSchema; + return parseInt(pipeline.duration as string, 10) * 1000; + } + + private static async getDefaultBranch( + gitbeaker: InstanceType, + owner: string, + ): Promise { + const branches = await gitbeaker.Branches.all(owner); + return branches.find(b => b.default)?.name; + } + + public async fetchBuilds(options: FetchBuildsOptions): Promise { + const { + entity, + updateProgress, + timeFrom, + timeTo, + filterStatus = ['all'], + filterType = 'all', + } = options; + const { api, owner } = await this.createGitlabApi(entity as Entity, [ + 'read_api', + ]); + updateProgress(0, 0, 0); + + const branch = + filterType === 'master' + ? await CicdStatisticsApiGitlab.getDefaultBranch(api, owner) + : undefined; + const pipelines = await api.Pipelines.all(owner, { + perPage: 25, + updated_after: timeFrom.toISOString(), + updated_before: timeTo.toISOString(), + ref: branch, + }); + + const limiter = limiterFactory(10); + const builds = jobtToBuild(pipelines).map(async build => ({ + ...build, + duration: await limiter(() => + CicdStatisticsApiGitlab.getDurationOfBuild(api, owner, build), + ), + stages: await limiter(() => + CicdStatisticsApiGitlab.updateBuildWithStages(api, owner, build), + ), + })); + const promisedBuilds = (await Promise.all(builds)).filter(b => + filterStatus.includes(b.status), + ) as unknown as Build[]; + + return { builds: promisedBuilds }; + } + + public async getConfiguration(): Promise> { + return { + availableStatuses: [ + 'succeeded', + 'failed', + 'enqueued', + 'running', + 'aborted', + 'stalled', + 'expired', + 'unknown', + ] as const, + }; + } +} diff --git a/plugins/cicd-statistics-module-gitlab/src/api/index.ts b/plugins/cicd-statistics-module-gitlab/src/api/index.ts new file mode 100644 index 0000000000..686c8b5f63 --- /dev/null +++ b/plugins/cicd-statistics-module-gitlab/src/api/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 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 * from "./gitlab"; diff --git a/plugins/cicd-statistics-module-gitlab/src/index.ts b/plugins/cicd-statistics-module-gitlab/src/index.ts new file mode 100644 index 0000000000..409c45eecd --- /dev/null +++ b/plugins/cicd-statistics-module-gitlab/src/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 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 { CicdStatisticsApiGitlab } from './api'; diff --git a/plugins/cicd-statistics-module-gitlab/src/setupTests.ts b/plugins/cicd-statistics-module-gitlab/src/setupTests.ts new file mode 100644 index 0000000000..9bb3e72355 --- /dev/null +++ b/plugins/cicd-statistics-module-gitlab/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 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 '@testing-library/jest-dom'; +import 'cross-fetch/polyfill'; diff --git a/plugins/cicd-statistics/src/apis/types.ts b/plugins/cicd-statistics/src/apis/types.ts index 32d9d3f2df..975f69525c 100644 --- a/plugins/cicd-statistics/src/apis/types.ts +++ b/plugins/cicd-statistics/src/apis/types.ts @@ -117,7 +117,7 @@ export interface Build { duration: number; /** Top-level build stages */ - stages: Array; + stages?: Array; } /** diff --git a/plugins/cicd-statistics/src/components/button-switch.tsx b/plugins/cicd-statistics/src/components/button-switch.tsx index 65f55eee41..89a5f7735a 100644 --- a/plugins/cicd-statistics/src/components/button-switch.tsx +++ b/plugins/cicd-statistics/src/components/button-switch.tsx @@ -78,6 +78,9 @@ export function ButtonSwitch(props: ButtonSwitchProps) { ); const value = switchValue(values[index]); + if(!value){ + console.log(values[index]); + } if (props.multi) { props.onChange( props.selection.includes(value as T) diff --git a/plugins/cicd-statistics/src/entity-page.tsx b/plugins/cicd-statistics/src/entity-page.tsx index 3c51dabf2a..8c3209c854 100644 --- a/plugins/cicd-statistics/src/entity-page.tsx +++ b/plugins/cicd-statistics/src/entity-page.tsx @@ -166,6 +166,8 @@ function CicdCharts(props: CicdChartsProps) { errorApi.post(chartableStagesState.error); }, [errorApi, chartableStagesState.error]); + console.log(chartableStagesState); + return ( diff --git a/plugins/cicd-statistics/src/utils/stage-names.ts b/plugins/cicd-statistics/src/utils/stage-names.ts index 69c8cdcf25..8853336fef 100644 --- a/plugins/cicd-statistics/src/utils/stage-names.ts +++ b/plugins/cicd-statistics/src/utils/stage-names.ts @@ -68,6 +68,8 @@ export async function cleanupBuildTree( return map(builds, { chunk: 'idle' }, build => ({ ...build, - stages: build.stages.map(stage => recurseStage(stage, [])), + stages: build.stages + ? build.stages.map(stage => recurseStage(stage, [])) + : [], })); } From d3af30b47d8d5a9879456adcf5acbb9343ee3790 Mon Sep 17 00:00:00 2001 From: djamaile Date: Fri, 11 Mar 2022 20:22:00 +0100 Subject: [PATCH 02/12] chore: run prettier to prevent build from failing Signed-off-by: djamaile --- .changeset/proud-news-perform.md | 5 +++++ packages/app/src/apis.ts | 10 +++++----- packages/app/src/components/catalog/EntityPage.tsx | 2 +- plugins/cicd-statistics-module-gitlab/src/api/index.ts | 2 +- plugins/cicd-statistics/src/apis/types.ts | 2 +- .../cicd-statistics/src/components/button-switch.tsx | 3 --- plugins/cicd-statistics/src/entity-page.tsx | 2 -- plugins/cicd-statistics/src/utils/stage-names.ts | 4 +--- 8 files changed, 14 insertions(+), 16 deletions(-) create mode 100644 .changeset/proud-news-perform.md diff --git a/.changeset/proud-news-perform.md b/.changeset/proud-news-perform.md new file mode 100644 index 0000000000..20259c33e5 --- /dev/null +++ b/.changeset/proud-news-perform.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-cicd-statistics-module-gitlab': minor +--- + +Will update this once the PR is ready to be merged diff --git a/packages/app/src/apis.ts b/packages/app/src/apis.ts index afc96a68db..7214a96688 100644 --- a/packages/app/src/apis.ts +++ b/packages/app/src/apis.ts @@ -32,10 +32,11 @@ import { configApiRef, createApiFactory, errorApiRef, - githubAuthApiRef, gitlabAuthApiRef, + githubAuthApiRef, + gitlabAuthApiRef, } from '@backstage/core-plugin-api'; import { cicdStatisticsApiRef } from '@backstage/plugin-cicd-statistics'; -import {CicdStatisticsApiGitlab} from "@backstage/plugin-cicd-statistics-module-gitlab"; +import { CicdStatisticsApiGitlab } from '@backstage/plugin-cicd-statistics-module-gitlab'; export const apis: AnyApiFactory[] = [ createApiFactory({ @@ -44,7 +45,6 @@ export const apis: AnyApiFactory[] = [ factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi), }), - ScmAuth.createDefaultApiFactory(), createApiFactory({ @@ -69,10 +69,10 @@ export const apis: AnyApiFactory[] = [ createApiFactory(costInsightsApiRef, new ExampleCostInsightsClient()), createApiFactory({ api: cicdStatisticsApiRef, - deps: {gitlabAuthApi: gitlabAuthApiRef}, + deps: { gitlabAuthApi: gitlabAuthApiRef }, factory({ gitlabAuthApi }) { return new CicdStatisticsApiGitlab(gitlabAuthApi); }, }), -// createApiFactory(cicdStatisticsApiRef, new CicdStatisticsApiGitlab()), + // createApiFactory(cicdStatisticsApiRef, new CicdStatisticsApiGitlab()), ]; diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index 89897905b8..3ade051077 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -136,7 +136,7 @@ import { EntityNewRelicDashboardCard, } from '@backstage/plugin-newrelic-dashboard'; import { EntityGoCdContent, isGoCdAvailable } from '@backstage/plugin-gocd'; -import {EntityCicdStatisticsContent} from "@backstage/plugin-cicd-statistics"; +import { EntityCicdStatisticsContent } from '@backstage/plugin-cicd-statistics'; import React, { ReactNode, useMemo, useState } from 'react'; diff --git a/plugins/cicd-statistics-module-gitlab/src/api/index.ts b/plugins/cicd-statistics-module-gitlab/src/api/index.ts index 686c8b5f63..21f5f622a6 100644 --- a/plugins/cicd-statistics-module-gitlab/src/api/index.ts +++ b/plugins/cicd-statistics-module-gitlab/src/api/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export * from "./gitlab"; +export * from './gitlab'; diff --git a/plugins/cicd-statistics/src/apis/types.ts b/plugins/cicd-statistics/src/apis/types.ts index 975f69525c..32d9d3f2df 100644 --- a/plugins/cicd-statistics/src/apis/types.ts +++ b/plugins/cicd-statistics/src/apis/types.ts @@ -117,7 +117,7 @@ export interface Build { duration: number; /** Top-level build stages */ - stages?: Array; + stages: Array; } /** diff --git a/plugins/cicd-statistics/src/components/button-switch.tsx b/plugins/cicd-statistics/src/components/button-switch.tsx index 89a5f7735a..65f55eee41 100644 --- a/plugins/cicd-statistics/src/components/button-switch.tsx +++ b/plugins/cicd-statistics/src/components/button-switch.tsx @@ -78,9 +78,6 @@ export function ButtonSwitch(props: ButtonSwitchProps) { ); const value = switchValue(values[index]); - if(!value){ - console.log(values[index]); - } if (props.multi) { props.onChange( props.selection.includes(value as T) diff --git a/plugins/cicd-statistics/src/entity-page.tsx b/plugins/cicd-statistics/src/entity-page.tsx index 8c3209c854..3c51dabf2a 100644 --- a/plugins/cicd-statistics/src/entity-page.tsx +++ b/plugins/cicd-statistics/src/entity-page.tsx @@ -166,8 +166,6 @@ function CicdCharts(props: CicdChartsProps) { errorApi.post(chartableStagesState.error); }, [errorApi, chartableStagesState.error]); - console.log(chartableStagesState); - return ( diff --git a/plugins/cicd-statistics/src/utils/stage-names.ts b/plugins/cicd-statistics/src/utils/stage-names.ts index 8853336fef..69c8cdcf25 100644 --- a/plugins/cicd-statistics/src/utils/stage-names.ts +++ b/plugins/cicd-statistics/src/utils/stage-names.ts @@ -68,8 +68,6 @@ export async function cleanupBuildTree( return map(builds, { chunk: 'idle' }, build => ({ ...build, - stages: build.stages - ? build.stages.map(stage => recurseStage(stage, [])) - : [], + stages: build.stages.map(stage => recurseStage(stage, [])), })); } From e3cca397e4e2686add39644b3ad1f533e6192777 Mon Sep 17 00:00:00 2001 From: djamaile Date: Sat, 12 Mar 2022 19:25:49 +0100 Subject: [PATCH 03/12] fix: yarn.lock to keep tsc command from failing Signed-off-by: djamaile --- packages/app/src/apis.ts | 4 +--- .../.eslintrc.js | 4 +--- .../package.json | 22 ++++++++----------- .../src/setupTests.ts | 3 +-- 4 files changed, 12 insertions(+), 21 deletions(-) diff --git a/packages/app/src/apis.ts b/packages/app/src/apis.ts index 7214a96688..7b3232f42d 100644 --- a/packages/app/src/apis.ts +++ b/packages/app/src/apis.ts @@ -65,8 +65,6 @@ export const apis: AnyApiFactory[] = [ }), ]), }), - - createApiFactory(costInsightsApiRef, new ExampleCostInsightsClient()), createApiFactory({ api: cicdStatisticsApiRef, deps: { gitlabAuthApi: gitlabAuthApiRef }, @@ -74,5 +72,5 @@ export const apis: AnyApiFactory[] = [ return new CicdStatisticsApiGitlab(gitlabAuthApi); }, }), - // createApiFactory(cicdStatisticsApiRef, new CicdStatisticsApiGitlab()), + createApiFactory(costInsightsApiRef, new ExampleCostInsightsClient()), ]; diff --git a/plugins/cicd-statistics-module-gitlab/.eslintrc.js b/plugins/cicd-statistics-module-gitlab/.eslintrc.js index 13573efa9c..e2a53a6ad2 100644 --- a/plugins/cicd-statistics-module-gitlab/.eslintrc.js +++ b/plugins/cicd-statistics-module-gitlab/.eslintrc.js @@ -1,3 +1 @@ -module.exports = { - extends: [require.resolve('@backstage/cli/config/eslint')], -}; +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/cicd-statistics-module-gitlab/package.json b/plugins/cicd-statistics-module-gitlab/package.json index df9ccef6b8..e41e634dc2 100644 --- a/plugins/cicd-statistics-module-gitlab/package.json +++ b/plugins/cicd-statistics-module-gitlab/package.json @@ -8,16 +8,12 @@ "private": false, "publishConfig": { "access": "public", - "main": "dist/index.esm.js", + "main": "dist/index.cjs.js", + "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, "backstage": { - "role": "frontend-plugin" - }, - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/cicd-statistics-module-gitlab" + "role": "common-library" }, "keywords": [ "backstage", @@ -27,20 +23,20 @@ "scripts": { "build": "backstage-cli package build", "lint": "backstage-cli package lint", - "test": "backstage-cli package test" + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/catalog-model": "^0.9.10", - "@backstage/core-plugin-api": "^0.8.0", "@backstage/plugin-cicd-statistics": "^0.1.0", "@gitbeaker/browser": "34.2.0", "@gitbeaker/core": "^35.4.0", - "lodash": "^4.17.21", "luxon": "^2.0.2", "p-limit": "^4.0.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0" + "devDependencies": { + "@backstage/cli": "^0.15.2" }, "files": [ "dist" diff --git a/plugins/cicd-statistics-module-gitlab/src/setupTests.ts b/plugins/cicd-statistics-module-gitlab/src/setupTests.ts index 9bb3e72355..8b9b6bd586 100644 --- a/plugins/cicd-statistics-module-gitlab/src/setupTests.ts +++ b/plugins/cicd-statistics-module-gitlab/src/setupTests.ts @@ -13,5 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import '@testing-library/jest-dom'; -import 'cross-fetch/polyfill'; +export {}; From f65495894e583dedb5050791546c2210f167984a Mon Sep 17 00:00:00 2001 From: djamaile Date: Sat, 12 Mar 2022 19:44:35 +0100 Subject: [PATCH 04/12] fix: add missing dependencies to prevent build from failing Signed-off-by: djamaile --- plugins/cicd-statistics-module-gitlab/package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/cicd-statistics-module-gitlab/package.json b/plugins/cicd-statistics-module-gitlab/package.json index e41e634dc2..f7121a42ae 100644 --- a/plugins/cicd-statistics-module-gitlab/package.json +++ b/plugins/cicd-statistics-module-gitlab/package.json @@ -33,7 +33,9 @@ "@gitbeaker/browser": "34.2.0", "@gitbeaker/core": "^35.4.0", "luxon": "^2.0.2", - "p-limit": "^4.0.0" + "p-limit": "^4.0.0", + "@backstage/core-plugin-api": "^0.8.0", + "@backstage/catalog-model": "^0.13.0" }, "devDependencies": { "@backstage/cli": "^0.15.2" From 9e4937dd836a4432801745961b21490f626ae313 Mon Sep 17 00:00:00 2001 From: djamaile Date: Sat, 12 Mar 2022 20:05:28 +0100 Subject: [PATCH 05/12] chore: add API report Signed-off-by: djamaile --- .../api-report.md | 28 +++++++++++++++++++ .../src/api/gitlab.ts | 5 ++++ 2 files changed, 33 insertions(+) create mode 100644 plugins/cicd-statistics-module-gitlab/api-report.md diff --git a/plugins/cicd-statistics-module-gitlab/api-report.md b/plugins/cicd-statistics-module-gitlab/api-report.md new file mode 100644 index 0000000000..c9e1e19016 --- /dev/null +++ b/plugins/cicd-statistics-module-gitlab/api-report.md @@ -0,0 +1,28 @@ +## API Report File for "@backstage/plugin-cicd-statistics-module-gitlab" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { CicdConfiguration } from '@backstage/plugin-cicd-statistics'; +import { CicdState } from '@backstage/plugin-cicd-statistics'; +import { CicdStatisticsApi } from '@backstage/plugin-cicd-statistics'; +import { Entity } from '@backstage/catalog-model'; +import { FetchBuildsOptions } from '@backstage/plugin-cicd-statistics'; +import { Gitlab } from '@gitbeaker/browser'; +import { OAuthApi } from '@backstage/core-plugin-api'; + +// @public +export class CicdStatisticsApiGitlab implements CicdStatisticsApi { + constructor(gitLabAuthApi: OAuthApi); + // Warning: (ae-forgotten-export) The symbol "GitlabClient" needs to be exported by the entry point index.d.ts + // + // (undocumented) + createGitlabApi(entity: Entity, scopes: string[]): Promise; + // (undocumented) + fetchBuilds(options: FetchBuildsOptions): Promise; + // (undocumented) + getConfiguration(): Promise>; +} + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts b/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts index a28ce612d5..45b682302b 100644 --- a/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts +++ b/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts @@ -73,6 +73,11 @@ type GitlabClient = { owner: string; }; +/** + * Extracts the CI/CD statistics from a Gitlab repository + * + * @public + */ export class CicdStatisticsApiGitlab implements CicdStatisticsApi { readonly #gitLabAuthApi: OAuthApi; From ff21a91645e4b7a69865d18e5ae73d61e0456bb1 Mon Sep 17 00:00:00 2001 From: djamaile Date: Sat, 12 Mar 2022 20:26:07 +0100 Subject: [PATCH 06/12] chore: update API report and remove links from README Signed-off-by: djamaile --- plugins/cicd-statistics-module-gitlab/README.md | 6 +----- plugins/cicd-statistics-module-gitlab/api-report.md | 8 ++++++-- plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts | 9 ++++++++- plugins/cicd-statistics-module-gitlab/src/index.ts | 1 + 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/plugins/cicd-statistics-module-gitlab/README.md b/plugins/cicd-statistics-module-gitlab/README.md index 85c297932e..3cce8b0cde 100644 --- a/plugins/cicd-statistics-module-gitlab/README.md +++ b/plugins/cicd-statistics-module-gitlab/README.md @@ -2,8 +2,4 @@ ## Getting started -Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/cicd-statistics-module-gitlab](http://localhost:3000/cicd-statistics-module-gitlab). - -You can also serve the plugin in isolation by running `yarn start` in the plugin directory. -This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. -It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. +Will update in another commit diff --git a/plugins/cicd-statistics-module-gitlab/api-report.md b/plugins/cicd-statistics-module-gitlab/api-report.md index c9e1e19016..5e07255f54 100644 --- a/plugins/cicd-statistics-module-gitlab/api-report.md +++ b/plugins/cicd-statistics-module-gitlab/api-report.md @@ -14,8 +14,6 @@ import { OAuthApi } from '@backstage/core-plugin-api'; // @public export class CicdStatisticsApiGitlab implements CicdStatisticsApi { constructor(gitLabAuthApi: OAuthApi); - // Warning: (ae-forgotten-export) The symbol "GitlabClient" needs to be exported by the entry point index.d.ts - // // (undocumented) createGitlabApi(entity: Entity, scopes: string[]): Promise; // (undocumented) @@ -24,5 +22,11 @@ export class CicdStatisticsApiGitlab implements CicdStatisticsApi { getConfiguration(): Promise>; } +// @public +export type GitlabClient = { + api: InstanceType; + owner: string; +}; + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts b/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts index 45b682302b..1c4866557c 100644 --- a/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts +++ b/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts @@ -68,8 +68,15 @@ function jobsToStages(jobs: Array): Stage[] { }); } -type GitlabClient = { +/** + * This type represents a initialized gitlab client with gitbeaker + * + * @public + */ +export type GitlabClient = { + /* the actual API of gitbeaker */ api: InstanceType; + /* the owner the repository, retrieved from the entity source location */ owner: string; }; diff --git a/plugins/cicd-statistics-module-gitlab/src/index.ts b/plugins/cicd-statistics-module-gitlab/src/index.ts index 409c45eecd..c8d53d5bd2 100644 --- a/plugins/cicd-statistics-module-gitlab/src/index.ts +++ b/plugins/cicd-statistics-module-gitlab/src/index.ts @@ -15,3 +15,4 @@ */ export { CicdStatisticsApiGitlab } from './api'; +export type { GitlabClient } from './api'; From d9a4b672c2f81aed85cd0ed6e08107acfc2fc757 Mon Sep 17 00:00:00 2001 From: djamaile Date: Wed, 30 Mar 2022 17:10:16 +0200 Subject: [PATCH 07/12] test: add test cases to test if the util functions are working correctly Signed-off-by: djamaile --- .../cicd-statistics-module-gitlab/README.md | 35 +++++++++++- .../src/api/gitlab.ts | 56 +++---------------- 2 files changed, 41 insertions(+), 50 deletions(-) diff --git a/plugins/cicd-statistics-module-gitlab/README.md b/plugins/cicd-statistics-module-gitlab/README.md index 3cce8b0cde..58c053167f 100644 --- a/plugins/cicd-statistics-module-gitlab/README.md +++ b/plugins/cicd-statistics-module-gitlab/README.md @@ -1,5 +1,38 @@ # cicd-statistics-module-gitlab +This is an extension module to the `cicd-statistics` plugin, providing a `CicdStatisticsApiGitlab` that you can use to extract the cicd statistics from your Gitlab repository. + ## Getting started -Will update in another commit +1. Install the `cicd-statistics` and `cicd-statistics-module-gitlab` plugins in the `app` package. + +2. Configure your ApiFactory: + +```tsx +// packages/app/src/apis.ts +import { gitlabAuthApiRef } from '@backstage/core-plugin-api'; + +import { cicdStatisticsApiRef } from '@backstage/plugin-cicd-statistics'; +import { CicdStatisticsApiGitlab } from '@backstage plugin-cicd-statistics-module-gitlab'; + +export const apis: AnyApiFactory[] = [ + createApiFactory({ + api: cicdStatisticsApiRef, + deps: { gitlabAuthApi: gitlabAuthApiRef }, + factory({ gitlabAuthApi }) { + return new CicdStatisticsApiGitlab(gitlabAuthApi); + }, + }), +]; +``` + +3. Add the component to your EntityPage: + +```tsx +// packages/app/src/components/catalog/EntityPage.tsx +import { EntityCicdStatisticsContent } from '@backstage/plugin-cicd-statistics'; + + + +; +``` diff --git a/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts b/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts index 1c4866557c..7439d1800c 100644 --- a/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts +++ b/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts @@ -19,54 +19,14 @@ import { CicdState, CicdConfiguration, Build, - FilterStatusType, FetchBuildsOptions, Stage, } from '@backstage/plugin-cicd-statistics'; import { Gitlab } from '@gitbeaker/browser'; import { OAuthApi } from '@backstage/core-plugin-api'; import limiterFactory from 'p-limit'; - -import { Types } from '@gitbeaker/core'; import { Entity, getEntitySourceLocation } from '@backstage/catalog-model'; - -const statusMap: Record = { - manual: 'unknown', - created: 'enqueued', - waiting_for_resource: 'stalled', - preparing: 'unknown', - pending: 'scheduled', - running: 'running', - success: 'succeeded', - failed: 'failed', - canceled: 'aborted', - skipped: 'aborted', - scheduled: 'scheduled', -}; - -function jobtToBuild(jobs: Array): Build[] { - return jobs.map(j => { - return { - id: j.id.toString(), - status: statusMap[j.status], - branchType: 'master', - duration: 0, // will get filled in later in a seperate API call - requestedAt: new Date(j.created_at), - stages: [], - }; - }); -} - -function jobsToStages(jobs: Array): Stage[] { - return jobs.map(j => { - const status = statusMap[j.status] ? statusMap[j.status] : 'unknown'; - return { - name: j.name, - status: status, - duration: j.duration ? ((j.duration * 1000) as number) : 0, - }; - }); -} +import { pipelinesToBuilds, jobsToStages } from './utils'; /** * This type represents a initialized gitlab client with gitbeaker @@ -127,10 +87,10 @@ export class CicdStatisticsApiGitlab implements CicdStatisticsApi { owner: string, build: Build, ): Promise { - const pipeline = (await gitbeaker.Pipelines.show( + const pipeline = await gitbeaker.Pipelines.show( owner, parseInt(build.id, 10), - )) as Types.PipelineExtendedSchema; + ); return parseInt(pipeline.duration as string, 10) * 1000; } @@ -139,7 +99,7 @@ export class CicdStatisticsApiGitlab implements CicdStatisticsApi { owner: string, ): Promise { const branches = await gitbeaker.Branches.all(owner); - return branches.find(b => b.default)?.name; + return branches.find(branch => branch.default)?.name; } public async fetchBuilds(options: FetchBuildsOptions): Promise { @@ -151,9 +111,7 @@ export class CicdStatisticsApiGitlab implements CicdStatisticsApi { filterStatus = ['all'], filterType = 'all', } = options; - const { api, owner } = await this.createGitlabApi(entity as Entity, [ - 'read_api', - ]); + const { api, owner } = await this.createGitlabApi(entity, ['read_api']); updateProgress(0, 0, 0); const branch = @@ -168,7 +126,7 @@ export class CicdStatisticsApiGitlab implements CicdStatisticsApi { }); const limiter = limiterFactory(10); - const builds = jobtToBuild(pipelines).map(async build => ({ + const builds = pipelinesToBuilds(pipelines).map(async build => ({ ...build, duration: await limiter(() => CicdStatisticsApiGitlab.getDurationOfBuild(api, owner, build), @@ -179,7 +137,7 @@ export class CicdStatisticsApiGitlab implements CicdStatisticsApi { })); const promisedBuilds = (await Promise.all(builds)).filter(b => filterStatus.includes(b.status), - ) as unknown as Build[]; + ); return { builds: promisedBuilds }; } From 0e8b8472fcca6434e39629f793b59cac9fdf88ce Mon Sep 17 00:00:00 2001 From: djamaile Date: Wed, 30 Mar 2022 17:34:33 +0200 Subject: [PATCH 08/12] feat: add trigger reason to give a better overview to the user Signed-off-by: djamaile --- .../src/api/utils.test.ts | 89 +++++++++++++++ .../src/api/utils.ts | 107 ++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 plugins/cicd-statistics-module-gitlab/src/api/utils.test.ts create mode 100644 plugins/cicd-statistics-module-gitlab/src/api/utils.ts diff --git a/plugins/cicd-statistics-module-gitlab/src/api/utils.test.ts b/plugins/cicd-statistics-module-gitlab/src/api/utils.test.ts new file mode 100644 index 0000000000..338b92bf4f --- /dev/null +++ b/plugins/cicd-statistics-module-gitlab/src/api/utils.test.ts @@ -0,0 +1,89 @@ +/* + * Copyright 2022 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 { pipelinesToBuilds, jobsToStages } from './utils'; +import { Types } from '@gitbeaker/core'; + +const pipelineMock: Types.PipelineSchema[] = [ + { + id: 1000, + iid: 1, + project_id: 1, + sha: 'd40', + ref: 'main', + status: 'success', + source: 'schedule', + created_at: '2022-03-30T13:03:09.846Z', + updated_at: '2022-03-30T13:07:49.248Z', + web_url: 'https://gitlab.com/backstage/app/-/pipelines/1000', + user: { + name: 'user', + avatar_url: 'avatar_user', + }, + }, +]; + +// cast to unknown so we can omit a lot unused vars but also keep the type +const jobMock = [ + { + id: 6962883, + status: 'success', + stage: 'build', + name: 'docker', + ref: 'refs/merge-requests/209/train', + tag: false, + allow_failure: false, + created_at: new Date('2022-03-30T08:35:15.394Z'), + started_at: new Date('2022-03-30T08:35:16.532Z'), + finished_at: new Date('2022-03-30T08:35:37.731Z'), + duration: 21.199465, + queued_duration: 0.976313, + }, +] as unknown as Array; + +describe('util functionality', () => { + it('transforms the pipeline object to the build object', () => { + const builds = pipelinesToBuilds(pipelineMock); + expect(builds).toEqual([ + { + id: '1000', + status: 'succeeded', + branchType: 'master', + duration: 0, + requestedAt: new Date('2022-03-30T13:03:09.846Z'), + stages: [], + }, + ]); + }); + + it('transforms the job object to the stage object', () => { + const stages = jobsToStages(jobMock); + expect(stages).toEqual([ + { + name: 'build', + status: 'succeeded', + duration: 21199.465, + stages: [ + { + name: 'docker', + status: 'succeeded', + duration: 21199.465, + }, + ], + }, + ]); + }); +}); diff --git a/plugins/cicd-statistics-module-gitlab/src/api/utils.ts b/plugins/cicd-statistics-module-gitlab/src/api/utils.ts new file mode 100644 index 0000000000..acf2910704 --- /dev/null +++ b/plugins/cicd-statistics-module-gitlab/src/api/utils.ts @@ -0,0 +1,107 @@ +/* + * Copyright 2022 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 { + Build, + FilterStatusType, + TriggerReason, + Stage, +} from '@backstage/plugin-cicd-statistics'; +import { Types } from '@gitbeaker/core'; + +const statusMap: Record = { + manual: 'unknown', + created: 'enqueued', + waiting_for_resource: 'stalled', + preparing: 'unknown', + pending: 'scheduled', + running: 'running', + success: 'succeeded', + failed: 'failed', + canceled: 'aborted', + skipped: 'aborted', + scheduled: 'scheduled', +}; + +// all gitlab trigger reasons can be found here: https://docs.gitlab.com/ee/api/pipelines.html#list-project-pipelines +const triggerReasonMap: Record = { + push: 'scm', + trigger: 'manual', + merge_request_event: 'scm', + schedule: 'internal', +}; + +/** + * Takes the Pipeline object from Gitlab and transforms it to the Build object + * + * @param pipelines - Pipeline object that gets returned from Gitlab + * + * @public + */ +export function pipelinesToBuilds( + pipelines: Array, +): Build[] { + return pipelines.map(pipeline => { + return { + id: pipeline.id.toString(), + status: statusMap[pipeline.status], + branchType: 'master', + duration: 0, // will get filled in later in a seperate API call + requestedAt: new Date(pipeline.created_at), + triggeredBy: triggerReasonMap[pipeline.source as string] ?? 'other', + stages: [], + }; + }); +} + +/** + * Takes the Job object from Gitlab and transforms it to the Stage object + * + * @param jobs - Job object that gets returned from Gitlab + * + * @public + * + * @remarks + * + * The Gitlab API can only return the job (sub-stage) of a pipeline and not a whole stage a pipeline + * The job does return from which stage it is + * So, for the stage name we use the parent stage name and in the sub-stages we add the current job + * In the end the cicd-statistics plugin will calculate the right durations for each stage + * + * Furthermore, we don't add the job to the sub-stage if it is has the same name as the parent stage + * We then assume that the stage has no sub-stages + */ +export function jobsToStages(jobs: Array): Stage[] { + return jobs.map(job => { + const status = statusMap[job.status] ? statusMap[job.status] : 'unknown'; + const duration = job.duration ? ((job.duration * 1000) as number) : 0; + return { + name: job.stage, + status, + duration, + stages: + job.name !== job.stage + ? [ + { + name: job.name, + status, + duration, + }, + ] + : [], + }; + }); +} From b891d32604cfa1774a7409c3aa76eae5f013ea16 Mon Sep 17 00:00:00 2001 From: djamaile Date: Wed, 30 Mar 2022 17:39:52 +0200 Subject: [PATCH 09/12] chore: clean up of test variables Signed-off-by: djamaile --- .changeset/proud-news-perform.md | 3 ++- packages/app/src/apis.ts | 11 +---------- packages/app/src/components/catalog/EntityPage.tsx | 5 ----- .../cicd-statistics-module-gitlab/src/api/utils.ts | 2 +- 4 files changed, 4 insertions(+), 17 deletions(-) diff --git a/.changeset/proud-news-perform.md b/.changeset/proud-news-perform.md index 20259c33e5..9d5cbae8ab 100644 --- a/.changeset/proud-news-perform.md +++ b/.changeset/proud-news-perform.md @@ -2,4 +2,5 @@ '@backstage/plugin-cicd-statistics-module-gitlab': minor --- -Will update this once the PR is ready to be merged +Created a module to extract the CI/CD statistics from a Gitlab repository. +Read the `README.md` in the `cicd-statistics-module-gitlab` plugin folder on how to set it up. diff --git a/packages/app/src/apis.ts b/packages/app/src/apis.ts index 7b3232f42d..d587a88402 100644 --- a/packages/app/src/apis.ts +++ b/packages/app/src/apis.ts @@ -33,10 +33,7 @@ import { createApiFactory, errorApiRef, githubAuthApiRef, - gitlabAuthApiRef, } from '@backstage/core-plugin-api'; -import { cicdStatisticsApiRef } from '@backstage/plugin-cicd-statistics'; -import { CicdStatisticsApiGitlab } from '@backstage/plugin-cicd-statistics-module-gitlab'; export const apis: AnyApiFactory[] = [ createApiFactory({ @@ -65,12 +62,6 @@ export const apis: AnyApiFactory[] = [ }), ]), }), - createApiFactory({ - api: cicdStatisticsApiRef, - deps: { gitlabAuthApi: gitlabAuthApiRef }, - factory({ gitlabAuthApi }) { - return new CicdStatisticsApiGitlab(gitlabAuthApi); - }, - }), + createApiFactory(costInsightsApiRef, new ExampleCostInsightsClient()), ]; diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index 3ade051077..26068c6c8f 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -136,7 +136,6 @@ import { EntityNewRelicDashboardCard, } from '@backstage/plugin-newrelic-dashboard'; import { EntityGoCdContent, isGoCdAvailable } from '@backstage/plugin-gocd'; -import { EntityCicdStatisticsContent } from '@backstage/plugin-cicd-statistics'; import React, { ReactNode, useMemo, useState } from 'react'; @@ -445,10 +444,6 @@ const websiteEntityPage = ( {cicdContent} - - - - diff --git a/plugins/cicd-statistics-module-gitlab/src/api/utils.ts b/plugins/cicd-statistics-module-gitlab/src/api/utils.ts index acf2910704..5f1d1cbeba 100644 --- a/plugins/cicd-statistics-module-gitlab/src/api/utils.ts +++ b/plugins/cicd-statistics-module-gitlab/src/api/utils.ts @@ -76,7 +76,7 @@ export function pipelinesToBuilds( * * @remarks * - * The Gitlab API can only return the job (sub-stage) of a pipeline and not a whole stage a pipeline + * The Gitlab API can only return the job (sub-stage) of a pipeline and not a whole stage * The job does return from which stage it is * So, for the stage name we use the parent stage name and in the sub-stages we add the current job * In the end the cicd-statistics plugin will calculate the right durations for each stage From 6803844d0ba7decab21fa5570cdc1aef127c5276 Mon Sep 17 00:00:00 2001 From: djamaile Date: Wed, 30 Mar 2022 17:48:02 +0200 Subject: [PATCH 10/12] fix: add CI/CD to vale to prevent build from failing Signed-off-by: djamaile --- .github/styles/vocab.txt | 1 + plugins/cicd-statistics-module-gitlab/README.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/styles/vocab.txt b/.github/styles/vocab.txt index 4070e5600a..d2257f1b6f 100644 --- a/.github/styles/vocab.txt +++ b/.github/styles/vocab.txt @@ -39,6 +39,7 @@ Changesets chanwit Chanwit ci +CI/CD classname cli cloudbuild diff --git a/plugins/cicd-statistics-module-gitlab/README.md b/plugins/cicd-statistics-module-gitlab/README.md index 58c053167f..0b11f6950a 100644 --- a/plugins/cicd-statistics-module-gitlab/README.md +++ b/plugins/cicd-statistics-module-gitlab/README.md @@ -1,6 +1,6 @@ # cicd-statistics-module-gitlab -This is an extension module to the `cicd-statistics` plugin, providing a `CicdStatisticsApiGitlab` that you can use to extract the cicd statistics from your Gitlab repository. +This is an extension module to the `cicd-statistics` plugin, providing a `CicdStatisticsApiGitlab` that you can use to extract the CI/CD statistics from your Gitlab repository. ## Getting started From e2735e790233123ab1e5cd4ab19463c2a2fb31a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Sat, 9 Apr 2022 16:09:24 +0200 Subject: [PATCH 11/12] fix versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../package.json | 12 ++++----- yarn.lock | 27 +++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/plugins/cicd-statistics-module-gitlab/package.json b/plugins/cicd-statistics-module-gitlab/package.json index f7121a42ae..280282dd04 100644 --- a/plugins/cicd-statistics-module-gitlab/package.json +++ b/plugins/cicd-statistics-module-gitlab/package.json @@ -29,16 +29,16 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/plugin-cicd-statistics": "^0.1.0", - "@gitbeaker/browser": "34.2.0", - "@gitbeaker/core": "^35.4.0", + "@backstage/plugin-cicd-statistics": "^0.1.6-next.0", + "@gitbeaker/browser": "^35.6.0", + "@gitbeaker/core": "^35.6.0", "luxon": "^2.0.2", "p-limit": "^4.0.0", - "@backstage/core-plugin-api": "^0.8.0", - "@backstage/catalog-model": "^0.13.0" + "@backstage/core-plugin-api": "^1.0.0", + "@backstage/catalog-model": "^1.0.1-next.1" }, "devDependencies": { - "@backstage/cli": "^0.15.2" + "@backstage/cli": "^0.17.0-next.2" }, "files": [ "dist" diff --git a/yarn.lock b/yarn.lock index e469f8432b..efd79f7ac7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2186,6 +2186,16 @@ resolved "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.2.tgz#30aa825f11d438671d585bd44e7fd564535fc210" integrity sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw== +"@gitbeaker/browser@^35.6.0": + version "35.6.0" + resolved "https://registry.npmjs.org/@gitbeaker/browser/-/browser-35.6.0.tgz#a639ae57eeb4d4829b73a634f757ef5841ad4116" + integrity sha512-cMkMG3r1HfVV7AUxVfp+PzDpISJYDQK5TnFfVT9vwVfW2uUDYALxMWYFwBLPkn3otqrOY1TkHXl/I9WgwsZMfg== + dependencies: + "@gitbeaker/core" "^35.6.0" + "@gitbeaker/requester-utils" "^35.6.0" + delay "^5.0.0" + ky "0.28.7" + "@gitbeaker/core@^35.5.0", "@gitbeaker/core@^35.6.0": version "35.6.0" resolved "https://registry.npmjs.org/@gitbeaker/core/-/core-35.6.0.tgz#c46e15986081ef1e647434c450964eed5fb0e390" @@ -16369,6 +16379,11 @@ kuler@^2.0.0: resolved "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== +ky@0.28.7: + version "0.28.7" + resolved "https://registry.npmjs.org/ky/-/ky-0.28.7.tgz#10c42be863fb96c1846d6e71e229263ffb72eb15" + integrity sha512-a23i6qSr/ep15vdtw/zyEQIDLoUaKDg9Jf04CYl/0ns/wXNYna26zJpI+MeIFaPeDvkrjLPrKtKOiiI3IE53RQ== + language-subtag-registry@~0.3.2: version "0.3.21" resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz#04ac218bea46f04cb039084602c6da9e788dd45a" @@ -19163,6 +19178,13 @@ p-limit@^2.0.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" +p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -25849,6 +25871,11 @@ yocto-queue@^0.1.0: resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +yocto-queue@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" + integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== + yup@^0.32.9: version "0.32.11" resolved "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz#d67fb83eefa4698607982e63f7ca4c5ed3cf18c5" From b4c5585234bf914a7b8902a096aac7c4a8e0d698 Mon Sep 17 00:00:00 2001 From: djamaile Date: Mon, 11 Apr 2022 14:42:13 +0200 Subject: [PATCH 12/12] test: add triggeredBy to testcases to prevent build from breaking Signed-off-by: djamaile --- plugins/cicd-statistics-module-gitlab/package.json | 4 ++-- plugins/cicd-statistics-module-gitlab/src/api/utils.test.ts | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/cicd-statistics-module-gitlab/package.json b/plugins/cicd-statistics-module-gitlab/package.json index 280282dd04..b36bcf2476 100644 --- a/plugins/cicd-statistics-module-gitlab/package.json +++ b/plugins/cicd-statistics-module-gitlab/package.json @@ -13,11 +13,11 @@ "types": "dist/index.d.ts" }, "backstage": { - "role": "common-library" + "role": "frontend-plugin-module" }, "keywords": [ "backstage", - "cicd statestics", + "cicd statistics", "gitlab" ], "scripts": { diff --git a/plugins/cicd-statistics-module-gitlab/src/api/utils.test.ts b/plugins/cicd-statistics-module-gitlab/src/api/utils.test.ts index 338b92bf4f..fda5e68540 100644 --- a/plugins/cicd-statistics-module-gitlab/src/api/utils.test.ts +++ b/plugins/cicd-statistics-module-gitlab/src/api/utils.test.ts @@ -64,6 +64,7 @@ describe('util functionality', () => { branchType: 'master', duration: 0, requestedAt: new Date('2022-03-30T13:03:09.846Z'), + triggeredBy: 'internal', stages: [], }, ]);