@backstage-community/plugin-cicd-statistics-module-buildkite 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @backstage-community/plugin-cicd-statistics-module-buildkite
2
+
3
+ ## 0.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 87d6273: An initial release implementation of a Buildkite `CicdStatisticsApi` for use in using the existing [cicd-statistics](https://github.com/backstage/community-plugins/tree/main/workspaces/cicd-statistics/plugins/cicd-statistics) plugin with [Buildkite](https://buildkite.com/).
package/README.md ADDED
@@ -0,0 +1,53 @@
1
+ # cicd-statistics-module-buildkite
2
+
3
+ This is an extension module to the `cicd-statistics` plugin providing a `CicdStatisticsApiBuildkite`
4
+ for use extracting CI/CD statistics from Buildkite pipelines.
5
+
6
+ ## Getting started
7
+
8
+ 1. Install the `cicd-statistics` and `cicd-statistics-module-buildkite` plugins in the `app` package.
9
+
10
+ 2. Configure your ApiFactory (Note that `CicdStatisticsApiBuildkite` accepts a [CicdStatisticsApiBuildkiteOpts](https://github.com/backstage/community-plugins/blob/master/plugins/cicd-statistics-module-buildkite/src/api/buildkite.ts#L51)):
11
+
12
+ ```tsx
13
+ // packages/app/src/apis.ts
14
+ import {
15
+ createApiFactory,
16
+ discoveryApiRef,
17
+ fetchApiRef,
18
+ } from '@backstage/core-plugin-api';
19
+
20
+ import { cicdStatisticsApiRef } from '@backstage-community/plugin-cicd-statistics';
21
+ import { CicdStatisticsApiBuildkite } from '@backstage-community/plugin-cicd-statistics-module-buildkite';
22
+
23
+ export const apis: AnyApiFactory[] = [
24
+ createApiFactory({
25
+ api: cicdStatisticsApiRef,
26
+ deps: {
27
+ discoveryApi: discoveryApiRef,
28
+ fetchApiApi: fetchApiRef,
29
+ },
30
+ factory({ discoveryApi, fetchApi }) {
31
+ return new CicdStatisticsApiBuildkite(discoveryApi, fetchApi);
32
+ },
33
+ }),
34
+ ];
35
+ ```
36
+
37
+ 3. Add the component to your EntityPage:
38
+
39
+ ```tsx
40
+ // packages/app/src/components/catalog/EntityPage.tsx
41
+ import { EntityCicdStatisticsContent } from '@backstage-community/plugin-cicd-statistics';
42
+
43
+ <EntityLayout.Route path="/cicd-statistics" title="CI/CD Statistics">
44
+ <EntityCicdStatisticsContent />
45
+ </EntityLayout.Route>;
46
+ ```
47
+
48
+ 4. Configure entities to feature a `buildkite.com/pipeline-name` annotation:
49
+
50
+ ```yaml
51
+ annotations:
52
+ buildkite.com/pipeline-name: 'org-name/some-pipeline'
53
+ ```
@@ -0,0 +1,62 @@
1
+ import { toBuilds, buildStatusMap } from './utils.esm.js';
2
+ import { BuildkiteApi } from '@roadiehq/backstage-plugin-buildkite';
3
+
4
+ class CicdStatisticsApiBuildkite {
5
+ #cicdDefaults;
6
+ #discoveryApi;
7
+ #fetchApi;
8
+ #proxyPath;
9
+ constructor(opts) {
10
+ this.#cicdDefaults = opts.cicdDefaults ? opts.cicdDefaults : {};
11
+ this.#discoveryApi = opts.discoveryApi;
12
+ this.#fetchApi = opts.fetchApi;
13
+ this.#proxyPath = opts.proxyPath;
14
+ }
15
+ async createBuildkiteApi(entity) {
16
+ const pipelineAnnotation = entity.metadata.annotations?.["buildkite.com/pipeline"] || "";
17
+ const pipelineParts = pipelineAnnotation.split("/");
18
+ const org = pipelineParts[0];
19
+ const pipeline = pipelineParts[1] ? pipelineParts[1] : "";
20
+ return {
21
+ api: new BuildkiteApi({
22
+ discoveryApi: this.#discoveryApi,
23
+ fetchApi: this.#fetchApi,
24
+ proxyPath: this.#proxyPath
25
+ }),
26
+ org,
27
+ pipeline
28
+ };
29
+ }
30
+ async fetchBuilds(options) {
31
+ const {
32
+ entity,
33
+ updateProgress,
34
+ filterStatus = ["all"],
35
+ filterType = "all"
36
+ } = options;
37
+ const { api, org, pipeline } = await this.createBuildkiteApi(entity);
38
+ updateProgress(0, 0, 0);
39
+ const branch = filterType === "master" ? await this.getDefaultBranch(api, org, pipeline) : void 0;
40
+ const bkBuilds = await api.getBuilds(org, pipeline, 0, 25, branch);
41
+ const builds = toBuilds(bkBuilds);
42
+ const filteredBuilds = builds.filter(
43
+ (b) => filterStatus.includes("all") || filterStatus.includes(b.status)
44
+ );
45
+ return { builds: filteredBuilds };
46
+ }
47
+ async getConfiguration() {
48
+ return {
49
+ availableStatuses: Object.keys(
50
+ buildStatusMap
51
+ ),
52
+ defaults: this.#cicdDefaults
53
+ };
54
+ }
55
+ async getDefaultBranch(api, org, pipelineName) {
56
+ const pipeline = await api.getPipeline(org, pipelineName);
57
+ return pipeline.default_branch;
58
+ }
59
+ }
60
+
61
+ export { CicdStatisticsApiBuildkite };
62
+ //# sourceMappingURL=buildkite.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildkite.esm.js","sources":["../../src/api/buildkite.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LIAnnotationCENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api';\nimport {\n CicdStatisticsApi,\n CicdState,\n CicdConfiguration,\n CicdDefaults,\n FetchBuildsOptions,\n FilterStatusType,\n} from '@backstage-community/plugin-cicd-statistics';\nimport { Entity } from '@backstage/catalog-model';\nimport { toBuilds, buildStatusMap } from './utils';\nimport { BuildkiteApi } from '@roadiehq/backstage-plugin-buildkite';\n\n/**\n * BuildkiteClient represents an initialized Buildkite client.\n *\n * @public\n */\nexport type BuildkiteClient = {\n /* the actual API */\n api: InstanceType<typeof BuildkiteApi>;\n\n /* the Buildkite organization; retrieved from the entity */\n org: string;\n\n /* the Buildkite pipeline name; retrieved from the entity */\n pipeline: string;\n};\n\n/**\n * CicdStatisticsApiBuildkiteOpts configures a new CicdStatisticsApiBuildkite.\n *\n * @public\n */\nexport type CicdStatisticsApiBuildkiteOpts = {\n /* the DiscoveryApi to use */\n discoveryApi: DiscoveryApi;\n\n /* the FetchApi to use */\n fetchApi: FetchApi;\n\n /* the CicdDefaults to use */\n cicdDefaults?: Partial<CicdDefaults>;\n\n /* the path to the Buildkite API Backstage backend proxy endpoint */\n proxyPath?: string;\n};\n\n/**\n * Extracts the CI/CD statistics from a Buildkite pipeline.\n *\n * @public\n */\nexport class CicdStatisticsApiBuildkite implements CicdStatisticsApi {\n readonly #cicdDefaults: Partial<CicdDefaults>;\n readonly #discoveryApi: DiscoveryApi;\n readonly #fetchApi: FetchApi;\n readonly #proxyPath?: string;\n\n constructor(opts: CicdStatisticsApiBuildkiteOpts) {\n this.#cicdDefaults = opts.cicdDefaults ? opts.cicdDefaults : {};\n this.#discoveryApi = opts.discoveryApi;\n this.#fetchApi = opts.fetchApi;\n this.#proxyPath = opts.proxyPath;\n }\n\n public async createBuildkiteApi(entity: Entity): Promise<BuildkiteClient> {\n const pipelineAnnotation =\n entity.metadata.annotations?.['buildkite.com/pipeline'] || '';\n const pipelineParts = pipelineAnnotation.split('/');\n const org = pipelineParts[0];\n const pipeline = pipelineParts[1] ? pipelineParts[1] : '';\n\n return {\n api: new BuildkiteApi({\n discoveryApi: this.#discoveryApi,\n fetchApi: this.#fetchApi,\n proxyPath: this.#proxyPath,\n }),\n org,\n pipeline,\n };\n }\n\n public async fetchBuilds(options: FetchBuildsOptions): Promise<CicdState> {\n const {\n entity,\n updateProgress,\n filterStatus = ['all'],\n filterType = 'all',\n } = options;\n const { api, org, pipeline } = await this.createBuildkiteApi(entity);\n updateProgress(0, 0, 0);\n\n // Note the cicd-statistics plugin regards 'master' as a generic term\n // referring to a particular default 'trunk' branch, and not necessarily\n // the literal 'master' branch name.\n const branch =\n filterType === 'master'\n ? await this.getDefaultBranch(api, org, pipeline)\n : undefined;\n const bkBuilds = await api.getBuilds(org, pipeline, 0, 25, branch);\n const builds = toBuilds(bkBuilds);\n const filteredBuilds = builds.filter(\n b => filterStatus.includes('all') || filterStatus.includes(b.status),\n );\n\n return { builds: filteredBuilds };\n }\n\n public async getConfiguration(): Promise<Partial<CicdConfiguration>> {\n return {\n availableStatuses: Object.keys(\n buildStatusMap,\n ) as ReadonlyArray<FilterStatusType>,\n defaults: this.#cicdDefaults,\n };\n }\n\n private async getDefaultBranch(\n api: BuildkiteApi,\n org: string,\n pipelineName: string,\n ): Promise<string> {\n const pipeline = await api.getPipeline(org, pipelineName);\n\n return pipeline.default_branch;\n }\n}\n"],"names":[],"mappings":";;;AAqEO,MAAM,0BAAwD,CAAA;AAAA,EAC1D,aAAA,CAAA;AAAA,EACA,aAAA,CAAA;AAAA,EACA,SAAA,CAAA;AAAA,EACA,UAAA,CAAA;AAAA,EAET,YAAY,IAAsC,EAAA;AAChD,IAAA,IAAA,CAAK,aAAgB,GAAA,IAAA,CAAK,YAAe,GAAA,IAAA,CAAK,eAAe,EAAC,CAAA;AAC9D,IAAA,IAAA,CAAK,gBAAgB,IAAK,CAAA,YAAA,CAAA;AAC1B,IAAA,IAAA,CAAK,YAAY,IAAK,CAAA,QAAA,CAAA;AACtB,IAAA,IAAA,CAAK,aAAa,IAAK,CAAA,SAAA,CAAA;AAAA,GACzB;AAAA,EAEA,MAAa,mBAAmB,MAA0C,EAAA;AACxE,IAAA,MAAM,kBACJ,GAAA,MAAA,CAAO,QAAS,CAAA,WAAA,GAAc,wBAAwB,CAAK,IAAA,EAAA,CAAA;AAC7D,IAAM,MAAA,aAAA,GAAgB,kBAAmB,CAAA,KAAA,CAAM,GAAG,CAAA,CAAA;AAClD,IAAM,MAAA,GAAA,GAAM,cAAc,CAAC,CAAA,CAAA;AAC3B,IAAA,MAAM,WAAW,aAAc,CAAA,CAAC,CAAI,GAAA,aAAA,CAAc,CAAC,CAAI,GAAA,EAAA,CAAA;AAEvD,IAAO,OAAA;AAAA,MACL,GAAA,EAAK,IAAI,YAAa,CAAA;AAAA,QACpB,cAAc,IAAK,CAAA,aAAA;AAAA,QACnB,UAAU,IAAK,CAAA,SAAA;AAAA,QACf,WAAW,IAAK,CAAA,UAAA;AAAA,OACjB,CAAA;AAAA,MACD,GAAA;AAAA,MACA,QAAA;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAEA,MAAa,YAAY,OAAiD,EAAA;AACxE,IAAM,MAAA;AAAA,MACJ,MAAA;AAAA,MACA,cAAA;AAAA,MACA,YAAA,GAAe,CAAC,KAAK,CAAA;AAAA,MACrB,UAAa,GAAA,KAAA;AAAA,KACX,GAAA,OAAA,CAAA;AACJ,IAAM,MAAA,EAAE,KAAK,GAAK,EAAA,QAAA,KAAa,MAAM,IAAA,CAAK,mBAAmB,MAAM,CAAA,CAAA;AACnE,IAAe,cAAA,CAAA,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AAKtB,IAAM,MAAA,MAAA,GACJ,eAAe,QACX,GAAA,MAAM,KAAK,gBAAiB,CAAA,GAAA,EAAK,GAAK,EAAA,QAAQ,CAC9C,GAAA,KAAA,CAAA,CAAA;AACN,IAAM,MAAA,QAAA,GAAW,MAAM,GAAI,CAAA,SAAA,CAAU,KAAK,QAAU,EAAA,CAAA,EAAG,IAAI,MAAM,CAAA,CAAA;AACjE,IAAM,MAAA,MAAA,GAAS,SAAS,QAAQ,CAAA,CAAA;AAChC,IAAA,MAAM,iBAAiB,MAAO,CAAA,MAAA;AAAA,MAC5B,CAAA,CAAA,KAAK,aAAa,QAAS,CAAA,KAAK,KAAK,YAAa,CAAA,QAAA,CAAS,EAAE,MAAM,CAAA;AAAA,KACrE,CAAA;AAEA,IAAO,OAAA,EAAE,QAAQ,cAAe,EAAA,CAAA;AAAA,GAClC;AAAA,EAEA,MAAa,gBAAwD,GAAA;AACnE,IAAO,OAAA;AAAA,MACL,mBAAmB,MAAO,CAAA,IAAA;AAAA,QACxB,cAAA;AAAA,OACF;AAAA,MACA,UAAU,IAAK,CAAA,aAAA;AAAA,KACjB,CAAA;AAAA,GACF;AAAA,EAEA,MAAc,gBAAA,CACZ,GACA,EAAA,GAAA,EACA,YACiB,EAAA;AACjB,IAAA,MAAM,QAAW,GAAA,MAAM,GAAI,CAAA,WAAA,CAAY,KAAK,YAAY,CAAA,CAAA;AAExD,IAAA,OAAO,QAAS,CAAA,cAAA,CAAA;AAAA,GAClB;AACF;;;;"}
@@ -0,0 +1,80 @@
1
+ const buildStatusMap = {
2
+ running: "running",
3
+ scheduled: "scheduled",
4
+ passed: "succeeded",
5
+ failing: "failed",
6
+ failed: "failed",
7
+ blocked: "stalled",
8
+ canceled: "aborted",
9
+ canceling: "aborted",
10
+ skipped: "aborted",
11
+ not_run: "scheduled",
12
+ finished: "unknown"
13
+ };
14
+ const jobStatusMap = {
15
+ accepted: "scheduled",
16
+ assigned: "scheduled",
17
+ blocked: "stalled",
18
+ blocked_failed: "failed",
19
+ broken: "failed",
20
+ canceled: "aborted",
21
+ canceling: "aborted",
22
+ expired: "aborted",
23
+ finished: "unknown",
24
+ limited: "unknown",
25
+ limiting: "unknown",
26
+ pending: "stalled",
27
+ running: "running",
28
+ scheduled: "scheduled",
29
+ skipped: "aborted",
30
+ timed_out: "expired",
31
+ timing_out: "expired",
32
+ unblocked: "unknown",
33
+ unblocked_failed: "failed",
34
+ waiting: "scheduled",
35
+ waiting_failed: "failed"
36
+ };
37
+ function toBuilds(builds) {
38
+ return builds.map((build) => {
39
+ return {
40
+ id: build.id,
41
+ status: buildStatusMap[build.state],
42
+ // TODO: is this correct?
43
+ branchType: build.branch,
44
+ duration: new Date(build.finished_at).valueOf() - new Date(build.started_at).valueOf(),
45
+ requestedAt: new Date(build.created_at),
46
+ triggeredBy: triggeredBy(build.source),
47
+ stages: jobsToStages(build.jobs)
48
+ };
49
+ });
50
+ }
51
+ function triggeredBy(source) {
52
+ if (source === "schedule") {
53
+ return "internal";
54
+ }
55
+ if (source === "ui") {
56
+ return "manual";
57
+ }
58
+ return "scm";
59
+ }
60
+ function jobsToStages(jobs) {
61
+ return jobs.map((job) => {
62
+ const status = jobStatusMap[job.state] ? jobStatusMap[job.state] : "unknown";
63
+ const duration = new Date(job.finished_at).valueOf() - new Date(job.started_at).valueOf();
64
+ return {
65
+ name: job.name,
66
+ status,
67
+ duration,
68
+ stages: [
69
+ {
70
+ name: job.name,
71
+ status,
72
+ duration
73
+ }
74
+ ]
75
+ };
76
+ });
77
+ }
78
+
79
+ export { buildStatusMap, jobsToStages, toBuilds, triggeredBy };
80
+ //# sourceMappingURL=utils.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.esm.js","sources":["../../src/api/utils.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Build,\n FilterStatusType,\n FilterBranchType,\n TriggerReason,\n Stage,\n} from '@backstage-community/plugin-cicd-statistics';\nimport { BuildkiteBuild, Job } from './types';\n\n/*\n * See https://buildkite.com/docs/pipelines/defining-steps#build-states\n */\nexport const buildStatusMap: Record<string, FilterStatusType> = {\n running: 'running',\n scheduled: 'scheduled',\n passed: 'succeeded',\n failing: 'failed',\n failed: 'failed',\n blocked: 'stalled',\n canceled: 'aborted',\n canceling: 'aborted',\n skipped: 'aborted',\n not_run: 'scheduled',\n finished: 'unknown',\n};\n\n/*\n * See https://buildkite.com/docs/pipelines/defining-steps#job-states\n */\nconst jobStatusMap: Record<string, FilterStatusType> = {\n accepted: 'scheduled',\n assigned: 'scheduled',\n blocked: 'stalled',\n blocked_failed: 'failed',\n broken: 'failed',\n canceled: 'aborted',\n canceling: 'aborted',\n expired: 'aborted',\n finished: 'unknown',\n limited: 'unknown',\n limiting: 'unknown',\n pending: 'stalled',\n running: 'running',\n scheduled: 'scheduled',\n skipped: 'aborted',\n timed_out: 'expired',\n timing_out: 'expired',\n unblocked: 'unknown',\n unblocked_failed: 'failed',\n waiting: 'scheduled',\n waiting_failed: 'failed',\n};\n\n/**\n * toBuilds transforms build objects from Buildkite to Build objects.\n *\n * @param builds - array of build objects returned from Buildkite's API.\n *\n * @public\n */\nexport function toBuilds(builds: BuildkiteBuild[]): Build[] {\n return builds.map(build => {\n return {\n id: build.id,\n status: buildStatusMap[build.state],\n // TODO: is this correct?\n branchType: build.branch as FilterBranchType,\n duration:\n new Date(build.finished_at).valueOf() -\n new Date(build.started_at).valueOf(),\n requestedAt: new Date(build.created_at),\n triggeredBy: triggeredBy(build.source),\n stages: jobsToStages(build.jobs),\n };\n });\n}\n\nexport function triggeredBy(source: string): TriggerReason {\n if (source === 'schedule') {\n return 'internal';\n }\n\n if (source === 'ui') {\n return 'manual';\n }\n\n return 'scm';\n}\n\n/**\n * jobsToStages transforms Job objects from Buildkite to Stage objects.\n *\n * @param jobs - array of job objects returned from the Buildkite API.\n *\n * @public\n */\nexport function jobsToStages(jobs: Job[]): Stage[] {\n return jobs.map(job => {\n const status = jobStatusMap[job.state]\n ? jobStatusMap[job.state]\n : 'unknown';\n const duration =\n new Date(job.finished_at).valueOf() - new Date(job.started_at).valueOf();\n\n return {\n name: job.name,\n status,\n duration,\n stages: [\n {\n name: job.name,\n status,\n duration,\n },\n ],\n };\n });\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api';
2
+ import { CicdDefaults, CicdStatisticsApi, FetchBuildsOptions, CicdState, CicdConfiguration } from '@backstage-community/plugin-cicd-statistics';
3
+ import { Entity } from '@backstage/catalog-model';
4
+ import { BuildkiteApi } from '@roadiehq/backstage-plugin-buildkite';
5
+
6
+ /**
7
+ * BuildkiteClient represents an initialized Buildkite client.
8
+ *
9
+ * @public
10
+ */
11
+ type BuildkiteClient = {
12
+ api: InstanceType<typeof BuildkiteApi>;
13
+ org: string;
14
+ pipeline: string;
15
+ };
16
+ /**
17
+ * CicdStatisticsApiBuildkiteOpts configures a new CicdStatisticsApiBuildkite.
18
+ *
19
+ * @public
20
+ */
21
+ type CicdStatisticsApiBuildkiteOpts = {
22
+ discoveryApi: DiscoveryApi;
23
+ fetchApi: FetchApi;
24
+ cicdDefaults?: Partial<CicdDefaults>;
25
+ proxyPath?: string;
26
+ };
27
+ /**
28
+ * Extracts the CI/CD statistics from a Buildkite pipeline.
29
+ *
30
+ * @public
31
+ */
32
+ declare class CicdStatisticsApiBuildkite implements CicdStatisticsApi {
33
+ #private;
34
+ constructor(opts: CicdStatisticsApiBuildkiteOpts);
35
+ createBuildkiteApi(entity: Entity): Promise<BuildkiteClient>;
36
+ fetchBuilds(options: FetchBuildsOptions): Promise<CicdState>;
37
+ getConfiguration(): Promise<Partial<CicdConfiguration>>;
38
+ private getDefaultBranch;
39
+ }
40
+
41
+ export { type BuildkiteClient, CicdStatisticsApiBuildkite, type CicdStatisticsApiBuildkiteOpts };
@@ -0,0 +1,2 @@
1
+ export { CicdStatisticsApiBuildkite } from './api/buildkite.esm.js';
2
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@backstage-community/plugin-cicd-statistics-module-buildkite",
3
+ "version": "0.0.1",
4
+ "description": "CI/CD Statistics plugin module; Buildkite CI/CD",
5
+ "backstage": {
6
+ "role": "frontend-plugin-module",
7
+ "pluginId": "cicd-statistics",
8
+ "pluginPackage": "@backstage-community/plugin-cicd-statistics"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public",
12
+ "main": "dist/index.esm.js",
13
+ "types": "dist/index.d.ts"
14
+ },
15
+ "keywords": [
16
+ "backstage",
17
+ "cicd statistics",
18
+ "gitlab"
19
+ ],
20
+ "homepage": "https://backstage.io",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/backstage/community-plugins",
24
+ "directory": "workspaces/cicd-statistics/plugins/cicd-statistics-module-buildkite"
25
+ },
26
+ "license": "Apache-2.0",
27
+ "sideEffects": false,
28
+ "main": "dist/index.esm.js",
29
+ "types": "dist/index.d.ts",
30
+ "files": [
31
+ "dist"
32
+ ],
33
+ "scripts": {
34
+ "build": "backstage-cli package build",
35
+ "clean": "backstage-cli package clean",
36
+ "lint": "backstage-cli package lint",
37
+ "prepack": "backstage-cli package prepack",
38
+ "postpack": "backstage-cli package postpack",
39
+ "test": "backstage-cli package test"
40
+ },
41
+ "dependencies": {
42
+ "@backstage-community/plugin-cicd-statistics": "^0.1.39",
43
+ "@backstage/catalog-model": "^1.4.5",
44
+ "@backstage/core-plugin-api": "^1.9.2",
45
+ "@backstage/test-utils": "^1.5.9",
46
+ "@gitbeaker/browser": "^35.6.0",
47
+ "@gitbeaker/core": "^35.6.0",
48
+ "@roadiehq/backstage-plugin-buildkite": "^2.3.1",
49
+ "luxon": "^3.0.0",
50
+ "p-limit": "^3.1.0"
51
+ },
52
+ "devDependencies": {
53
+ "@backstage/cli": "^0.26.3",
54
+ "@types/react": "^16.13.1 || ^17.0.0",
55
+ "@types/react-dom": "^18.2.19",
56
+ "react": "^16.13.1 || ^17.0.0 || ^18.0.0",
57
+ "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0",
58
+ "react-router-dom": "6.0.0-beta.0 || ^6.3.0"
59
+ },
60
+ "peerDependencies": {
61
+ "react": "^16.13.1 || ^17.0.0 || ^18.0.0",
62
+ "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0",
63
+ "react-router-dom": "6.0.0-beta.0 || ^6.3.0"
64
+ },
65
+ "module": "./dist/index.esm.js"
66
+ }