@backstage-community/plugin-cicd-statistics-module-github 0.13.0 → 0.14.0

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 CHANGED
@@ -1,5 +1,24 @@
1
1
  # @backstage-community/plugin-cicd-statistics-module-github
2
2
 
3
+ ## 0.14.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 6b61b33: Backstage version bump to v1.50.2
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [6b61b33]
12
+ - @backstage-community/plugin-cicd-statistics@0.16.0
13
+
14
+ ## 0.13.1
15
+
16
+ ### Patch Changes
17
+
18
+ - a7f3f99: Backstage version bump to v1.48.4
19
+ - Updated dependencies [a7f3f99]
20
+ - @backstage-community/plugin-cicd-statistics@0.15.1
21
+
3
22
  ## 0.13.0
4
23
 
5
24
  ### Minor Changes
@@ -1 +1 @@
1
- {"version":3,"file":"apis.esm.js","sources":["../../src/alpha/apis.ts"],"sourcesContent":["/*\n * Copyright 2025 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 */\nimport { configApiRef, ApiBlueprint } from '@backstage/frontend-plugin-api';\nimport { scmAuthApiRef } from '@backstage/integration-react';\nimport { cicdStatisticsApiRef } from '@backstage-community/plugin-cicd-statistics';\nimport { CicdStatisticsApiGithub } from '../api';\n\n/**\n * @alpha\n */\nexport const cicdStatisticsGithubApi = ApiBlueprint.make({\n name: 'cicd-statistics/cicd-statistics-github-api',\n params: defineParams =>\n defineParams({\n api: cicdStatisticsApiRef,\n deps: { configApi: configApiRef, scmAuthApi: scmAuthApiRef },\n factory: ({ configApi, scmAuthApi }) =>\n new CicdStatisticsApiGithub({ configApi, scmAuthApi }),\n }),\n});\n"],"names":[],"mappings":";;;;;AAuBa,MAAA,uBAAA,GAA0B,aAAa,IAAK,CAAA;AAAA,EACvD,IAAM,EAAA,4CAAA;AAAA,EACN,MAAA,EAAQ,kBACN,YAAa,CAAA;AAAA,IACX,GAAK,EAAA,oBAAA;AAAA,IACL,IAAM,EAAA,EAAE,SAAW,EAAA,YAAA,EAAc,YAAY,aAAc,EAAA;AAAA,IAC3D,OAAA,EAAS,CAAC,EAAE,SAAW,EAAA,UAAA,EACrB,KAAA,IAAI,uBAAwB,CAAA,EAAE,SAAW,EAAA,UAAA,EAAY;AAAA,GACxD;AACL,CAAC;;;;"}
1
+ {"version":3,"file":"apis.esm.js","sources":["../../src/alpha/apis.ts"],"sourcesContent":["/*\n * Copyright 2025 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 */\nimport { configApiRef, ApiBlueprint } from '@backstage/frontend-plugin-api';\nimport { scmAuthApiRef } from '@backstage/integration-react';\nimport { cicdStatisticsApiRef } from '@backstage-community/plugin-cicd-statistics';\nimport { CicdStatisticsApiGithub } from '../api';\n\n/**\n * @alpha\n */\nexport const cicdStatisticsGithubApi = ApiBlueprint.make({\n name: 'cicd-statistics/cicd-statistics-github-api',\n params: defineParams =>\n defineParams({\n api: cicdStatisticsApiRef,\n deps: { configApi: configApiRef, scmAuthApi: scmAuthApiRef },\n factory: ({ configApi, scmAuthApi }) =>\n new CicdStatisticsApiGithub({ configApi, scmAuthApi }),\n }),\n});\n"],"names":[],"mappings":";;;;;AAuBO,MAAM,uBAAA,GAA0B,aAAa,IAAA,CAAK;AAAA,EACvD,IAAA,EAAM,4CAAA;AAAA,EACN,MAAA,EAAQ,kBACN,YAAA,CAAa;AAAA,IACX,GAAA,EAAK,oBAAA;AAAA,IACL,IAAA,EAAM,EAAE,SAAA,EAAW,YAAA,EAAc,YAAY,aAAA,EAAc;AAAA,IAC3D,OAAA,EAAS,CAAC,EAAE,SAAA,EAAW,UAAA,EAAW,KAChC,IAAI,uBAAA,CAAwB,EAAE,SAAA,EAAW,UAAA,EAAY;AAAA,GACxD;AACL,CAAC;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"alpha.esm.js","sources":["../src/alpha.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 */\nimport { createFrontendModule } from '@backstage/frontend-plugin-api';\nimport { cicdStatisticsGithubApi } from './alpha/index';\n\n/**\n * @alpha\n */\nexport default createFrontendModule({\n pluginId: 'cicd-statistics',\n extensions: [cicdStatisticsGithubApi],\n});\n"],"names":[],"mappings":";;;AAqBA,YAAe,oBAAqB,CAAA;AAAA,EAClC,QAAU,EAAA,iBAAA;AAAA,EACV,UAAA,EAAY,CAAC,uBAAuB;AACtC,CAAC,CAAA;;;;"}
1
+ {"version":3,"file":"alpha.esm.js","sources":["../src/alpha.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 */\nimport { createFrontendModule } from '@backstage/frontend-plugin-api';\nimport { cicdStatisticsGithubApi } from './alpha/index';\n\n/**\n * @alpha\n */\nexport default createFrontendModule({\n pluginId: 'cicd-statistics',\n extensions: [cicdStatisticsGithubApi],\n});\n"],"names":[],"mappings":";;;AAqBA,YAAe,oBAAA,CAAqB;AAAA,EAClC,QAAA,EAAU,iBAAA;AAAA,EACV,UAAA,EAAY,CAAC,uBAAuB;AACtC,CAAC,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"github.esm.js","sources":["../../src/api/github.ts"],"sourcesContent":["/*\n * Copyright 2022 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 CicdStatisticsApi,\n CicdState,\n CicdConfiguration,\n CicdDefaults,\n Build,\n FetchBuildsOptions,\n Stage,\n} from '@backstage-community/plugin-cicd-statistics';\nimport { ConfigApi } from '@backstage/core-plugin-api';\nimport limiterFactory from 'p-limit';\nimport { Entity, getEntitySourceLocation } from '@backstage/catalog-model';\nimport { jobToStages, workflowToBuild } from './utils';\n\nimport { readGithubIntegrationConfigs } from '@backstage/integration';\nimport { ScmAuthApi } from '@backstage/integration-react';\nimport { Octokit } from '@octokit/rest';\n\n/** @public */\nexport const GITHUB_ACTIONS_ANNOTATION = 'github.com/project-slug';\n\nexport const getProjectNameFromEntity = (entity: Entity) =>\n entity?.metadata.annotations?.[GITHUB_ACTIONS_ANNOTATION] ?? '';\n\n/**\n * This type represents an initialized github client with octokit\n *\n * @public\n */\nexport type GithubClient = {\n /* the octokit instance for making GitHub API calls */\n octokit: InstanceType<typeof Octokit>;\n /* the owner of the repository, retrieved from the entity source location */\n owner: string;\n /* the repository name, retrieved from the entity source location */\n repo: string;\n};\n\n/**\n * Extracts the CI/CD statistics from a Github repository\n *\n * @public\n */\nexport class CicdStatisticsApiGithub implements CicdStatisticsApi {\n private readonly scmAuthApi: ScmAuthApi;\n private readonly configApi: ConfigApi;\n private readonly cicdDefaults: Partial<CicdDefaults>;\n\n constructor(options: {\n scmAuthApi: ScmAuthApi;\n configApi: ConfigApi;\n cicdDefaults?: Partial<CicdDefaults>;\n }) {\n this.scmAuthApi = options.scmAuthApi;\n this.configApi = options.configApi;\n this.cicdDefaults = options.cicdDefaults ?? {};\n }\n\n private async getOctokit(hostname: string = 'github.com'): Promise<Octokit> {\n const { token } = await this.scmAuthApi.getCredentials({\n url: `https://${hostname}/`,\n additionalScope: {\n customScopes: {\n github: ['repo'],\n },\n },\n });\n const configs = readGithubIntegrationConfigs(\n this.configApi.getOptionalConfigArray('integrations.github') ?? [],\n );\n const githubIntegrationConfig = configs.find(v => v.host === hostname);\n const baseUrl = githubIntegrationConfig?.apiBaseUrl;\n return new Octokit({ auth: token, baseUrl });\n }\n\n public async createGithubClient(entity: Entity): Promise<GithubClient> {\n const entityInfo = getEntitySourceLocation(entity);\n const [owner, repo] = getProjectNameFromEntity(entity).split('/');\n const url = new URL(entityInfo.target);\n const hostname = url.hostname;\n\n const octokit = await this.getOctokit(hostname);\n return {\n octokit,\n owner,\n repo,\n };\n }\n\n private static async updateBuildWithStages(\n octokit: InstanceType<typeof Octokit>,\n owner: string,\n repo: string,\n build: Build,\n ): Promise<Stage[]> {\n const jobs = await octokit.actions.listJobsForWorkflowRun({\n repo,\n owner,\n run_id: parseInt(build.id, 10),\n });\n const stages = jobs.data.jobs.map(jobToStages);\n return stages;\n }\n\n private static async getDurationOfBuild(\n octokit: InstanceType<typeof Octokit>,\n owner: string,\n repo: string,\n build: Build,\n ): Promise<number> {\n const workflow = await octokit.actions.getWorkflowRunUsage({\n owner,\n repo,\n run_id: parseInt(build.id, 10),\n });\n return workflow.data?.run_duration_ms ?? 0;\n }\n\n private static async getDefaultBranch(\n octokit: InstanceType<typeof Octokit>,\n owner: string,\n repo: string,\n ): Promise<string | undefined> {\n const repository = await octokit.repos.get({\n owner,\n repo,\n });\n return repository.data.default_branch;\n }\n\n public async fetchBuilds(options: FetchBuildsOptions): Promise<CicdState> {\n const {\n entity,\n updateProgress,\n timeFrom,\n timeTo,\n filterStatus = ['all'],\n filterType = 'all',\n } = options;\n const { octokit, owner, repo } = await this.createGithubClient(entity);\n updateProgress(0, 0, 0);\n\n const branch =\n filterType === 'master'\n ? await CicdStatisticsApiGithub.getDefaultBranch(octokit, owner, repo)\n : undefined;\n\n const workflowsRuns = await octokit.paginate(\n octokit.actions.listWorkflowRunsForRepo,\n {\n owner,\n repo,\n per_page: 1000, // max items per page\n ...(branch ? { branch } : {}),\n created: `${timeFrom.toISOString()}..${timeTo.toISOString()}`, // see https://docs.github.com/en/search-github/getting-started-with-searching-on-github/understanding-the-search-syntax#query-for-dates\n },\n response => response.data.map(workflowToBuild),\n );\n\n const limiter = limiterFactory(10);\n const builds = workflowsRuns.map(async build => ({\n ...build,\n duration: await limiter(() =>\n CicdStatisticsApiGithub.getDurationOfBuild(octokit, owner, repo, build),\n ),\n stages: await limiter(() =>\n CicdStatisticsApiGithub.updateBuildWithStages(\n octokit,\n owner,\n repo,\n build,\n ),\n ),\n }));\n const promisedBuilds = (await Promise.all(builds)).filter(b =>\n filterStatus.includes(b.status),\n );\n\n return { builds: promisedBuilds };\n }\n\n public async getConfiguration(): Promise<Partial<CicdConfiguration>> {\n return {\n availableStatuses: [\n 'succeeded',\n 'running',\n 'aborted',\n 'failed',\n 'unknown',\n 'stalled',\n 'expired',\n 'enqueued',\n 'scheduled',\n ] as const,\n defaults: this.cicdDefaults,\n };\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"github.esm.js","sources":["../../src/api/github.ts"],"sourcesContent":["/*\n * Copyright 2022 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 CicdStatisticsApi,\n CicdState,\n CicdConfiguration,\n CicdDefaults,\n Build,\n FetchBuildsOptions,\n Stage,\n} from '@backstage-community/plugin-cicd-statistics';\nimport { ConfigApi } from '@backstage/core-plugin-api';\nimport limiterFactory from 'p-limit';\nimport { Entity, getEntitySourceLocation } from '@backstage/catalog-model';\nimport { jobToStages, workflowToBuild } from './utils';\n\nimport { readGithubIntegrationConfigs } from '@backstage/integration';\nimport { ScmAuthApi } from '@backstage/integration-react';\nimport { Octokit } from '@octokit/rest';\n\n/** @public */\nexport const GITHUB_ACTIONS_ANNOTATION = 'github.com/project-slug';\n\nexport const getProjectNameFromEntity = (entity: Entity) =>\n entity?.metadata.annotations?.[GITHUB_ACTIONS_ANNOTATION] ?? '';\n\n/**\n * This type represents an initialized github client with octokit\n *\n * @public\n */\nexport type GithubClient = {\n /* the octokit instance for making GitHub API calls */\n octokit: InstanceType<typeof Octokit>;\n /* the owner of the repository, retrieved from the entity source location */\n owner: string;\n /* the repository name, retrieved from the entity source location */\n repo: string;\n};\n\n/**\n * Extracts the CI/CD statistics from a Github repository\n *\n * @public\n */\nexport class CicdStatisticsApiGithub implements CicdStatisticsApi {\n private readonly scmAuthApi: ScmAuthApi;\n private readonly configApi: ConfigApi;\n private readonly cicdDefaults: Partial<CicdDefaults>;\n\n constructor(options: {\n scmAuthApi: ScmAuthApi;\n configApi: ConfigApi;\n cicdDefaults?: Partial<CicdDefaults>;\n }) {\n this.scmAuthApi = options.scmAuthApi;\n this.configApi = options.configApi;\n this.cicdDefaults = options.cicdDefaults ?? {};\n }\n\n private async getOctokit(hostname: string = 'github.com'): Promise<Octokit> {\n const { token } = await this.scmAuthApi.getCredentials({\n url: `https://${hostname}/`,\n additionalScope: {\n customScopes: {\n github: ['repo'],\n },\n },\n });\n const configs = readGithubIntegrationConfigs(\n this.configApi.getOptionalConfigArray('integrations.github') ?? [],\n );\n const githubIntegrationConfig = configs.find(v => v.host === hostname);\n const baseUrl = githubIntegrationConfig?.apiBaseUrl;\n return new Octokit({ auth: token, baseUrl });\n }\n\n public async createGithubClient(entity: Entity): Promise<GithubClient> {\n const entityInfo = getEntitySourceLocation(entity);\n const [owner, repo] = getProjectNameFromEntity(entity).split('/');\n const url = new URL(entityInfo.target);\n const hostname = url.hostname;\n\n const octokit = await this.getOctokit(hostname);\n return {\n octokit,\n owner,\n repo,\n };\n }\n\n private static async updateBuildWithStages(\n octokit: InstanceType<typeof Octokit>,\n owner: string,\n repo: string,\n build: Build,\n ): Promise<Stage[]> {\n const jobs = await octokit.actions.listJobsForWorkflowRun({\n repo,\n owner,\n run_id: parseInt(build.id, 10),\n });\n const stages = jobs.data.jobs.map(jobToStages);\n return stages;\n }\n\n private static async getDurationOfBuild(\n octokit: InstanceType<typeof Octokit>,\n owner: string,\n repo: string,\n build: Build,\n ): Promise<number> {\n const workflow = await octokit.actions.getWorkflowRunUsage({\n owner,\n repo,\n run_id: parseInt(build.id, 10),\n });\n return workflow.data?.run_duration_ms ?? 0;\n }\n\n private static async getDefaultBranch(\n octokit: InstanceType<typeof Octokit>,\n owner: string,\n repo: string,\n ): Promise<string | undefined> {\n const repository = await octokit.repos.get({\n owner,\n repo,\n });\n return repository.data.default_branch;\n }\n\n public async fetchBuilds(options: FetchBuildsOptions): Promise<CicdState> {\n const {\n entity,\n updateProgress,\n timeFrom,\n timeTo,\n filterStatus = ['all'],\n filterType = 'all',\n } = options;\n const { octokit, owner, repo } = await this.createGithubClient(entity);\n updateProgress(0, 0, 0);\n\n const branch =\n filterType === 'master'\n ? await CicdStatisticsApiGithub.getDefaultBranch(octokit, owner, repo)\n : undefined;\n\n const workflowsRuns = await octokit.paginate(\n octokit.actions.listWorkflowRunsForRepo,\n {\n owner,\n repo,\n per_page: 1000, // max items per page\n ...(branch ? { branch } : {}),\n created: `${timeFrom.toISOString()}..${timeTo.toISOString()}`, // see https://docs.github.com/en/search-github/getting-started-with-searching-on-github/understanding-the-search-syntax#query-for-dates\n },\n response => response.data.map(workflowToBuild),\n );\n\n const limiter = limiterFactory(10);\n const builds = workflowsRuns.map(async build => ({\n ...build,\n duration: await limiter(() =>\n CicdStatisticsApiGithub.getDurationOfBuild(octokit, owner, repo, build),\n ),\n stages: await limiter(() =>\n CicdStatisticsApiGithub.updateBuildWithStages(\n octokit,\n owner,\n repo,\n build,\n ),\n ),\n }));\n const promisedBuilds = (await Promise.all(builds)).filter(b =>\n filterStatus.includes(b.status),\n );\n\n return { builds: promisedBuilds };\n }\n\n public async getConfiguration(): Promise<Partial<CicdConfiguration>> {\n return {\n availableStatuses: [\n 'succeeded',\n 'running',\n 'aborted',\n 'failed',\n 'unknown',\n 'stalled',\n 'expired',\n 'enqueued',\n 'scheduled',\n ] as const,\n defaults: this.cicdDefaults,\n };\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.esm.js","sources":["../../src/api/utils.ts"],"sourcesContent":["/*\n * Copyright 2022 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 TriggerReason,\n Stage,\n} from '@backstage-community/plugin-cicd-statistics';\n\nimport { RestEndpointMethodTypes } from '@octokit/rest';\n\n// \"unknown\" | \"enqueued\" | \"scheduled\" | \"running\" | \"aborted\" | \"succeeded\" | \"failed\" | \"stalled\" | \"expired\"\n//\nconst statusMap: Record<string, FilterStatusType> = {\n // completed, action_required, cancelled, failure, neutral, skipped, stale, success, timed_out, in_progress, queued, requested, waiting, pending\n\n completed: 'succeeded',\n action_required: 'running',\n cancelled: 'aborted',\n failure: 'failed',\n neutral: 'unknown',\n skipped: 'aborted',\n stale: 'stalled',\n success: 'succeeded',\n timed_out: 'expired',\n in_progress: 'running',\n queued: 'enqueued',\n requested: 'scheduled',\n waiting: 'running',\n pending: 'running',\n};\n\n// see https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows\nconst triggerEventMap: Record<string, TriggerReason> = {\n push: 'scm',\n workflow_dispatch: 'manual',\n pull_request: 'scm',\n schedule: 'internal',\n deployment: 'scm',\n dynamic: 'internal',\n};\n\n/**\n * Takes the Workflow object from Github and transforms it to the Build object\n *\n * @param workflow - Workflow object that gets returned from Github\n *\n * @public\n */\nexport function workflowToBuild(\n workflow: RestEndpointMethodTypes['actions']['listWorkflowRuns']['response']['data']['workflow_runs'][0],\n): Build {\n return {\n id: workflow.id.toString(),\n status: statusMap[workflow.conclusion ?? ''] ?? 'unknown',\n branchType: ['main', 'master'].includes(workflow.head_branch ?? '')\n ? 'master'\n : 'branch',\n duration: 0, // will get filled in later in a separate API call\n requestedAt: new Date(workflow.created_at),\n triggeredBy: triggerEventMap[workflow.event] ?? 'other',\n stages: [],\n };\n}\n\n/**\n * Takes the Job object from Github and transforms it to the Stage object\n *\n * @param jobs - Job object that gets returned from Github\n *\n * @public\n *\n * @remarks\n *\n */\nexport function jobToStages(\n job: RestEndpointMethodTypes['actions']['listJobsForWorkflowRun']['response']['data']['jobs'][0],\n): Stage {\n const status = statusMap[job.status] ? statusMap[job.status] : 'unknown';\n const duration =\n job.started_at && job.completed_at\n ? new Date(job.completed_at).getTime() -\n new Date(job.started_at).getTime()\n : 0;\n return {\n name: job.name,\n status,\n duration,\n stages: job.steps?.map(step => {\n return {\n name: step.name,\n status: statusMap[step.status] ?? 'unknown',\n duration:\n step.started_at && step.completed_at\n ? new Date(step.completed_at).getTime() -\n new Date(step.started_at).getTime()\n : 0,\n };\n }),\n };\n}\n"],"names":[],"mappings":"AA2BA,MAAM,SAA8C,GAAA;AAAA;AAAA,EAGlD,SAAW,EAAA,WAAA;AAAA,EACX,eAAiB,EAAA,SAAA;AAAA,EACjB,SAAW,EAAA,SAAA;AAAA,EACX,OAAS,EAAA,QAAA;AAAA,EACT,OAAS,EAAA,SAAA;AAAA,EACT,OAAS,EAAA,SAAA;AAAA,EACT,KAAO,EAAA,SAAA;AAAA,EACP,OAAS,EAAA,WAAA;AAAA,EACT,SAAW,EAAA,SAAA;AAAA,EACX,WAAa,EAAA,SAAA;AAAA,EACb,MAAQ,EAAA,UAAA;AAAA,EACR,SAAW,EAAA,WAAA;AAAA,EACX,OAAS,EAAA,SAAA;AAAA,EACT,OAAS,EAAA;AACX,CAAA;AAGA,MAAM,eAAiD,GAAA;AAAA,EACrD,IAAM,EAAA,KAAA;AAAA,EACN,iBAAmB,EAAA,QAAA;AAAA,EACnB,YAAc,EAAA,KAAA;AAAA,EACd,QAAU,EAAA,UAAA;AAAA,EACV,UAAY,EAAA,KAAA;AAAA,EACZ,OAAS,EAAA;AACX,CAAA;AASO,SAAS,gBACd,QACO,EAAA;AACP,EAAO,OAAA;AAAA,IACL,EAAA,EAAI,QAAS,CAAA,EAAA,CAAG,QAAS,EAAA;AAAA,IACzB,MAAQ,EAAA,SAAA,CAAU,QAAS,CAAA,UAAA,IAAc,EAAE,CAAK,IAAA,SAAA;AAAA,IAChD,UAAA,EAAY,CAAC,MAAA,EAAQ,QAAQ,CAAA,CAAE,SAAS,QAAS,CAAA,WAAA,IAAe,EAAE,CAAA,GAC9D,QACA,GAAA,QAAA;AAAA,IACJ,QAAU,EAAA,CAAA;AAAA;AAAA,IACV,WAAa,EAAA,IAAI,IAAK,CAAA,QAAA,CAAS,UAAU,CAAA;AAAA,IACzC,WAAa,EAAA,eAAA,CAAgB,QAAS,CAAA,KAAK,CAAK,IAAA,OAAA;AAAA,IAChD,QAAQ;AAAC,GACX;AACF;AAYO,SAAS,YACd,GACO,EAAA;AACP,EAAM,MAAA,MAAA,GAAS,UAAU,GAAI,CAAA,MAAM,IAAI,SAAU,CAAA,GAAA,CAAI,MAAM,CAAI,GAAA,SAAA;AAC/D,EAAA,MAAM,WACJ,GAAI,CAAA,UAAA,IAAc,IAAI,YAClB,GAAA,IAAI,KAAK,GAAI,CAAA,YAAY,CAAE,CAAA,OAAA,KAC3B,IAAI,IAAA,CAAK,IAAI,UAAU,CAAA,CAAE,SACzB,GAAA,CAAA;AACN,EAAO,OAAA;AAAA,IACL,MAAM,GAAI,CAAA,IAAA;AAAA,IACV,MAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAQ,EAAA,GAAA,CAAI,KAAO,EAAA,GAAA,CAAI,CAAQ,IAAA,KAAA;AAC7B,MAAO,OAAA;AAAA,QACL,MAAM,IAAK,CAAA,IAAA;AAAA,QACX,MAAQ,EAAA,SAAA,CAAU,IAAK,CAAA,MAAM,CAAK,IAAA,SAAA;AAAA,QAClC,UACE,IAAK,CAAA,UAAA,IAAc,KAAK,YACpB,GAAA,IAAI,KAAK,IAAK,CAAA,YAAY,CAAE,CAAA,OAAA,KAC5B,IAAI,IAAA,CAAK,KAAK,UAAU,CAAA,CAAE,SAC1B,GAAA;AAAA,OACR;AAAA,KACD;AAAA,GACH;AACF;;;;"}
1
+ {"version":3,"file":"utils.esm.js","sources":["../../src/api/utils.ts"],"sourcesContent":["/*\n * Copyright 2022 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 TriggerReason,\n Stage,\n} from '@backstage-community/plugin-cicd-statistics';\n\nimport { RestEndpointMethodTypes } from '@octokit/rest';\n\n// \"unknown\" | \"enqueued\" | \"scheduled\" | \"running\" | \"aborted\" | \"succeeded\" | \"failed\" | \"stalled\" | \"expired\"\n//\nconst statusMap: Record<string, FilterStatusType> = {\n // completed, action_required, cancelled, failure, neutral, skipped, stale, success, timed_out, in_progress, queued, requested, waiting, pending\n\n completed: 'succeeded',\n action_required: 'running',\n cancelled: 'aborted',\n failure: 'failed',\n neutral: 'unknown',\n skipped: 'aborted',\n stale: 'stalled',\n success: 'succeeded',\n timed_out: 'expired',\n in_progress: 'running',\n queued: 'enqueued',\n requested: 'scheduled',\n waiting: 'running',\n pending: 'running',\n};\n\n// see https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows\nconst triggerEventMap: Record<string, TriggerReason> = {\n push: 'scm',\n workflow_dispatch: 'manual',\n pull_request: 'scm',\n schedule: 'internal',\n deployment: 'scm',\n dynamic: 'internal',\n};\n\n/**\n * Takes the Workflow object from Github and transforms it to the Build object\n *\n * @param workflow - Workflow object that gets returned from Github\n *\n * @public\n */\nexport function workflowToBuild(\n workflow: RestEndpointMethodTypes['actions']['listWorkflowRuns']['response']['data']['workflow_runs'][0],\n): Build {\n return {\n id: workflow.id.toString(),\n status: statusMap[workflow.conclusion ?? ''] ?? 'unknown',\n branchType: ['main', 'master'].includes(workflow.head_branch ?? '')\n ? 'master'\n : 'branch',\n duration: 0, // will get filled in later in a separate API call\n requestedAt: new Date(workflow.created_at),\n triggeredBy: triggerEventMap[workflow.event] ?? 'other',\n stages: [],\n };\n}\n\n/**\n * Takes the Job object from Github and transforms it to the Stage object\n *\n * @param jobs - Job object that gets returned from Github\n *\n * @public\n *\n * @remarks\n *\n */\nexport function jobToStages(\n job: RestEndpointMethodTypes['actions']['listJobsForWorkflowRun']['response']['data']['jobs'][0],\n): Stage {\n const status = statusMap[job.status] ? statusMap[job.status] : 'unknown';\n const duration =\n job.started_at && job.completed_at\n ? new Date(job.completed_at).getTime() -\n new Date(job.started_at).getTime()\n : 0;\n return {\n name: job.name,\n status,\n duration,\n stages: job.steps?.map(step => {\n return {\n name: step.name,\n status: statusMap[step.status] ?? 'unknown',\n duration:\n step.started_at && step.completed_at\n ? new Date(step.completed_at).getTime() -\n new Date(step.started_at).getTime()\n : 0,\n };\n }),\n };\n}\n"],"names":[],"mappings":"AA2BA,MAAM,SAAA,GAA8C;AAAA;AAAA,EAGlD,SAAA,EAAW,WAAA;AAAA,EACX,eAAA,EAAiB,SAAA;AAAA,EACjB,SAAA,EAAW,SAAA;AAAA,EACX,OAAA,EAAS,QAAA;AAAA,EACT,OAAA,EAAS,SAAA;AAAA,EACT,OAAA,EAAS,SAAA;AAAA,EACT,KAAA,EAAO,SAAA;AAAA,EACP,OAAA,EAAS,WAAA;AAAA,EACT,SAAA,EAAW,SAAA;AAAA,EACX,WAAA,EAAa,SAAA;AAAA,EACb,MAAA,EAAQ,UAAA;AAAA,EACR,SAAA,EAAW,WAAA;AAAA,EACX,OAAA,EAAS,SAAA;AAAA,EACT,OAAA,EAAS;AACX,CAAA;AAGA,MAAM,eAAA,GAAiD;AAAA,EACrD,IAAA,EAAM,KAAA;AAAA,EACN,iBAAA,EAAmB,QAAA;AAAA,EACnB,YAAA,EAAc,KAAA;AAAA,EACd,QAAA,EAAU,UAAA;AAAA,EACV,UAAA,EAAY,KAAA;AAAA,EACZ,OAAA,EAAS;AACX,CAAA;AASO,SAAS,gBACd,QAAA,EACO;AACP,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,QAAA,CAAS,EAAA,CAAG,QAAA,EAAS;AAAA,IACzB,MAAA,EAAQ,SAAA,CAAU,QAAA,CAAS,UAAA,IAAc,EAAE,CAAA,IAAK,SAAA;AAAA,IAChD,UAAA,EAAY,CAAC,MAAA,EAAQ,QAAQ,CAAA,CAAE,SAAS,QAAA,CAAS,WAAA,IAAe,EAAE,CAAA,GAC9D,QAAA,GACA,QAAA;AAAA,IACJ,QAAA,EAAU,CAAA;AAAA;AAAA,IACV,WAAA,EAAa,IAAI,IAAA,CAAK,QAAA,CAAS,UAAU,CAAA;AAAA,IACzC,WAAA,EAAa,eAAA,CAAgB,QAAA,CAAS,KAAK,CAAA,IAAK,OAAA;AAAA,IAChD,QAAQ;AAAC,GACX;AACF;AAYO,SAAS,YACd,GAAA,EACO;AACP,EAAA,MAAM,MAAA,GAAS,UAAU,GAAA,CAAI,MAAM,IAAI,SAAA,CAAU,GAAA,CAAI,MAAM,CAAA,GAAI,SAAA;AAC/D,EAAA,MAAM,WACJ,GAAA,CAAI,UAAA,IAAc,IAAI,YAAA,GAClB,IAAI,KAAK,GAAA,CAAI,YAAY,CAAA,CAAE,OAAA,KAC3B,IAAI,IAAA,CAAK,IAAI,UAAU,CAAA,CAAE,SAAQ,GACjC,CAAA;AACN,EAAA,OAAO;AAAA,IACL,MAAM,GAAA,CAAI,IAAA;AAAA,IACV,MAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA,EAAQ,GAAA,CAAI,KAAA,EAAO,GAAA,CAAI,CAAA,IAAA,KAAQ;AAC7B,MAAA,OAAO;AAAA,QACL,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,MAAA,EAAQ,SAAA,CAAU,IAAA,CAAK,MAAM,CAAA,IAAK,SAAA;AAAA,QAClC,UACE,IAAA,CAAK,UAAA,IAAc,KAAK,YAAA,GACpB,IAAI,KAAK,IAAA,CAAK,YAAY,CAAA,CAAE,OAAA,KAC5B,IAAI,IAAA,CAAK,KAAK,UAAU,CAAA,CAAE,SAAQ,GAClC;AAAA,OACR;AAAA,IACF,CAAC;AAAA,GACH;AACF;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage-community/plugin-cicd-statistics-module-github",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "CI/CD Statistics plugin module; Github CICD",
5
5
  "backstage": {
6
6
  "role": "frontend-plugin-module",
@@ -65,21 +65,21 @@
65
65
  "test": "backstage-cli package test"
66
66
  },
67
67
  "dependencies": {
68
- "@backstage-community/plugin-cicd-statistics": "^0.15.0",
69
- "@backstage/catalog-model": "^1.7.6",
70
- "@backstage/core-plugin-api": "^1.12.2",
71
- "@backstage/frontend-plugin-api": "^0.13.4",
72
- "@backstage/integration": "^1.19.2",
73
- "@backstage/integration-react": "^1.2.14",
68
+ "@backstage-community/plugin-cicd-statistics": "^0.16.0",
69
+ "@backstage/catalog-model": "^1.8.0",
70
+ "@backstage/core-plugin-api": "^1.12.5",
71
+ "@backstage/frontend-plugin-api": "^0.16.2",
72
+ "@backstage/integration": "^2.0.1",
73
+ "@backstage/integration-react": "^1.2.17",
74
74
  "@octokit/rest": "^21.1.1",
75
75
  "p-limit": "^3.1.0"
76
76
  },
77
77
  "devDependencies": {
78
- "@backstage/cli": "^0.35.3",
79
- "@backstage/dev-utils": "^1.1.19",
80
- "@backstage/integration": "^1.19.2",
81
- "@backstage/plugin-catalog": "^1.32.2",
82
- "@backstage/plugin-catalog-react": "^1.21.6",
78
+ "@backstage/cli": "^0.36.1",
79
+ "@backstage/dev-utils": "^1.1.22",
80
+ "@backstage/integration": "^2.0.1",
81
+ "@backstage/plugin-catalog": "^2.0.4",
82
+ "@backstage/plugin-catalog-react": "^2.1.4",
83
83
  "@types/react": "^16.13.1 || ^17.0.0",
84
84
  "@types/react-dom": "^18.2.19",
85
85
  "react": "^16.13.1 || ^17.0.0 || ^18.0.0",